算法设计课程报告(C++实现贪心算法)

声明:本报告比较简单,仅供参考哦!!

报告内容(主要包括四个方面的内容):

1、算法设计简介;

2、可以自行选择几种感兴趣的算法进行简介和分析;也可以针对以下给出的算法设计题,任选一题,完成编码任务,给出运行结果;

3、学习算法的心得体会;

4、参考文献

最小正整数问题

问题描述:键盘输入一个高精度的正整数 n(n<10位 ) , 去掉任意 s 个数字后剩下的数字按原左右次序组成一个新的正整数,寻求一种方案,使得新的正整数最小。

问题分析

1) 贪心法求解:删 k 个数符的全局最优解,包含了删除 1个数符的子问题的最优解。

2) 以字符串形式输入 s ,使用尽可能逼近目标的贪心法来逐一删去其中的 k 个数符, 每一步总是选择一个能使剩下的数最小的数符删去。


 

 

摘要:算法是解决特定问题的描述,在计算机领域当中,算法显得尤为重要。本文就算法的定义、特征以及发展历程进行描述,并列举了常见的算法思想。然后利用贪心算法来解决实际问题,最后谈谈自己学习贪心算法心得体会。

关键词:算法定义;算法特征;算法发展历程;贪心算法;心得体会

 

目录

1 算法设计简介

1.1 算法的定义

1.2 算法的特征

1.3 算法的发展流程

1.4 常见的算法

1.4.1 递归法

1.4.2 枚举法

1.4.3 迭代法

2 贪心算法

2.1 贪心算法简介

2.2 贪心算法的基本要素

2.3 贪心算法的问题描述

2.4 编码实现

2.5 运行结果

3 学习心得体会

参考文献


 

1 算法设计简介

1.1 算法的定义

算法是解决特定问题求解决步骤的描述,再计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。

不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度与时间复杂度来衡量。

算法的时间复杂度是指执行算法所需要的计算工作量。一般来说,计算机算法是问题规模n 的函数f(n),算法的时间复杂度也因此记做T(n)=Ο(f(n))。而算法的空间复杂度是指算法需要消耗的内存空间。其计算和表示方法与时间复杂度类似,一般都用复杂度的渐近性来表示。同时间复杂度相比,空间复杂度的分析要简单得多。

另外,算法的正确性、可读性以及健壮性也是判定算法优劣的重要标准。

1.2 算法的特征

算法的特征可分为输入、输出、有穷性、确定性以及可行性。

  1. 输入:算法具有零个或多个输入
  2. 输出:算法至少有一个或多个输出
  3. 有穷性:指算法再执行有限的步骤之后,自动结束而不会出现无心循环,并且每一个步骤再可接受的时间内完成
  4. 确定性:算法的每一个步骤都具有确定的意义,不会出现二义性
  5. 可行性:算法的每一步都必须是可行的,也就是说,每一步都能通过执行有限次数完成

 

1.3 算法的发展流程

算法思想源远流长,中国古代数学中就蕴涵了丰富的算法思想。随着现代信息技术飞速发展,算法在科学技术、社会发展中发挥着越来越大的作用,并且日益融入社会生活的许多方面,算法思想已成为现代人应具备的一种数学素养。希望通过本专题内容的学习,理解算法思想的特点,了解中学数学对算法教学的要求。

“算法”的英文名称Algorithm 来自于9世纪波斯数学家al-Khwarizmi,因为al-Khwarizmi在数学上提出了算法这个概念。“算法”原为"algorism",意思是阿拉伯数字的运算法则,在18世纪演变为"algorithm"。欧几里得算法被人们认为是史上第一个算法。 第一次编写程序是Ada Byron于1842年为巴贝奇分析机编写求解伯努利方程的程序,因此Ada Byron被大多数人认为是世界上第一位程序员。因为查尔斯·巴贝奇(Charles Babbage)未能完成他的巴贝奇分析机,这个算法未能在巴贝奇分析机上执行。 因为"well-defined procedure"缺少数学上精确的定义,19世纪和20世纪早期的数学家、逻辑学家在定义算法上出现了困难。20世纪的英国数学家图灵提出了著名的图灵论题,并提出一种假想的计算机的抽象模型,这个模型被称为图灵机。图灵机的出现解决了算法定义的难题,图灵的思想对算法的发展起到了重要作用。

1.4 常见的算法

 常见的算法有递推法、递归法、枚举法,贪心算法、回溯法以及迭代法等。下面简单介绍几个常见的算法:递归法、枚举法以及迭代法。本报告选取的题目是关于贪心算法的,下面会具体介绍。

1.4.1 递归法

程序调用自身的编程技巧称为递归(recursion)。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。

1.4.2 枚举法

在进行归纳推理时,如果逐个考察了某类事件的所有可能情况,因而得出一般结论,那么这结论是可靠的,这种归纳方法叫做枚举法。枚举法是利用计算机运算速度快、精确度高的特点,对要解决问题的所有可能情况,一个不漏地进行检验,从中找出符合要求的答案,因此枚举法是通过牺牲时间来换取答案的全面性。

1.4.3 迭代法

迭代法也称辗转法,是一种不断用变量的旧值递推新值的过程,跟迭代法相对应的是直接法(或者称为一次解法),即一次性解决问题。迭代法又分为精确迭代和近似迭代。“二分法”和“牛顿迭代法”属于近似迭代法。迭代算法是用计算机解决问题的一种基本方法。它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值。

 

2 贪心算法

 

2.1 贪心算法简介

 

贪心算法是一种对某些求最优解问题的更简单、更迅速的设计技术。用贪心法设计算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,它省去了为找最优解要穷尽所有可能而必须耗费的大量时间,它采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题, 通过每一步贪心选择,可得到问题的一个最优解,虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪心法不要回溯。

贪心算法是一种改进了的分级处理方法,其核心是根据题意选取一种量度标准,然后将这多个输入排成这种量度标准所要求的顺序,按这种顺序一次输入一个量,如果这个输入和当前已构成在这种量度意义下的部分最佳解加在一起不能产生一个可行解,则不把此输入加到这部分解中。这种能够得到某种量度意义下最优解的分级处理方法称为贪心算法。

对于一个给定的问题,往往可能有好几种量度标准。初看起来,这些量度标准似乎都是可取的,但实际上,用其中的大多数量度标准作贪心处理所得到该量度意义下的最优解并不是问题的最优解,而是次优解。因此,选择能产生问题最优解的最优量度标准是使用贪心算法的核心。

一般情况下,要选出最优量度标准并不是一件容易的事,但对某问题能选择出最优量度标准后,用贪心算法求解则特别有效。

 

2.2 贪心算法的基本要素

 

1.贪心选择性质。所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。

2.当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。

2.3 贪心算法的问题描述

键盘输入一个高精度的正整数 n(n<10位 ) , 去掉任意 s 个数字后剩下的数字按原左右次序组成一个新的正整数,寻求一种方案,使得新的正整数最小。

问题分析

1) 贪心法求解:删 k 个数符的全局最优解,包含了删除 1个数符的子问题的最优解。

2) 以字符串形式输入 s ,使用尽可能逼近目标的贪心法来逐一删去其中的 k 个数符, 每一步总是选择一个能使剩下的数最小的数符删去。

 

2.4 编码实现

采用C语言编写,具体代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
  char s[150];
  int len,n;
  while(~scanf("%s %d",s,&n))
    {
       int i;
       while(n>0)
          {
             i=0;
             len=strlen(s);//每次重新定义长度
             while(i<len&&s[i]<=s[i+1])
                   {
                       i++;}
             while(i<len)
                {
                    s[i]=s[i+1];
                     i++;
                 }
                 n--;
    }
    while(s[0]=='0')
    {
        i=0;
        len=strlen(s);
        while(i<len)
        {
            s[i]=s[i+1];
            i++;
        }
    }
    len=strlen(s);
    if(len==0) printf("0\n");
    else printf("%s\n",s);
//另一种重要输出方法,若为printf("%s",&s[n]);表示输出n之后的所有字符!!!!
}
    return 0;
}

 

2.5 运行结果

 

先输入一串数字(小于10位数),接着输入空格,再输入要去除的个数,最后回车。下面给出两个输出案例,如图1所示:

                                                                                     图1 运行结果测试

3 学习心得体会

首先,算法在我看来主要就是一种解题思路,能够帮我们更好的解决生活中的我们遇到的问题,解决我们遇到的各种问题,不只是现在学习的贪心算法,还有很多的其他的算法,比如:递归算法,迭代法等。

贪心算法主要的内容在我看来就是将复杂的问题转化为一步一步的小问题,再将这些简化后的问题分别的求出解,再将这些解整合得出最优解,贪心算法不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。

但是贪心算法的使用也是有界限的,不可能每一个的问题都能够使用贪心算法来解决,因此在做相关的题目的时候就要先考虑该题是否能用贪心算法,还有就是如何使用贪心算法来得到最优解,贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。

贪心算法在使用的过程中有一点贪心算法的每一次操作都对结果产生直接影响,即每一次得到的结果是不能后退的,不能够改变。对于上述的删数问题,给我们的几个数字我们要想得到的最小的数字,在我看来可以将其中的排列在前面的较大数字优先删除掉保证最高位的数字是附近几个数字中的最小就能保证得到的数字是比较小的。

现在感觉我们所学习的算法还是比较好理解的,能够很好的将问题按照算法的思路去解决,去代入。我们通过这样的算法能更好的使用现在所拥有的知识,算法我觉得更像是数学中的公式,知道清楚其中的原理就能很好的解决问题。

 

参考文献

[1] Thomas H.Cormen.算法导论》.机械工业出版社, 2013.1.

[2] 马克·艾伦·维斯.《数据结构与算法分析—C语言》.机械工业出版社. 2019.4

[3] Anany Levitin.《算法设计与分析基础(第3版)》.清华大学出版社. 2015.1.1

[4] 傅清祥,王晓东.《算法与数据结构》.电子工业出版社. 1998.1

 

 

  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
计算和分析,相对纸质记录更便于存储和共享。 缺点:数据输入容易出以下是一个使用贪心算法实现异形排样的示例代码: ```cpp #include <iostream> #include <vector错,难以进行复杂的数据处理和统计分析,不够智能化。 3. 自行开发的> #include <algorithm> struct Rect { int width; int height; }; bool compareRect(const Rect& rect1, const Rect&应用程序: 优点:可以根据实际需求进行定制开发,满足特定的业务 rect2) { // 按照面积从大到小排序 return rect1.width * rect1.height > rect2.width要求,数据处理和分析更加灵活。 缺点:开发周期长,成本高,需要专业 * rect2.height; } bool doesFit(const Rect& rect, int x, int y, int width, int height) { //的开发团队进行维护和更新,可能存在技术风险。 基于以上观察,设计一个基于MySQL 检查物体是否适合给定的位置和大小 return (x + rect.width <= width) && (y + rect数据库的药品进销存应用程序可以克服传统方式的缺点,具有以下优点: - 数据存.height <= height); } void packRects(const std::vector<Rect>& rects, int width, int height) { std::vector储可靠性高:MySQL数据库提供可靠的数据存储和管理机制,能够确保数据的完整<Rect> packedRects(rects.size()); std::vector<int> x(rects.size()); std::vector<int> y(rects.size()); // 按照面积从大到小排序 std::sort(rects.begin(), rects.end(), compareRect); for (int i = 0; i < rects.size(); ++i) { for (int j = 0; j <性和安全性。 - 数据处理和分析能力强:通过使用数据库的查询和统计功能,可以对药品进销存数据进行灵活的处理和分析。 - 多人协作和共享:基于应用程序的 i; ++j) { // 尝试在已放置的矩形周围找到合适的位置 if (doesFit(rects[i], x[j], y[j] + rects[j].height, width, height)) { x[i] = x设计,可以实现多用户同时使用和协作,提高工作效率。 - 可视化报表和图表[j]; y[i] = y[j] + rects[j].height; break; } else if (doesFit(rects:应用程序可以生成直观的统计报表和图表,帮助用户更好地理解和分析数据。 - 灵活定制和扩展:基于MySQL数据库的设计可以方便地进行功能定制和扩展,满足不同用户的需求。 综上所述,设计一个基于MySQL数据库的药品进销存应用程序能够有效地解决传统方式的问题,并提供更高效、准确的药品管理解决方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

硬核的无脸man~

你的鼓励是我创作的最大功力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值