算法第四章实践报告

1、实践题目:

7-2 删数问题 (110 分)

2、问题描述:

给定n位正整数a,去掉其中任意k≤n 个数字后,剩下的数字按原次序排列组成一个新 的正整数。对于给定的n位正整数a和正整数 k,设计一个算法找出剩下数字组成的新数最 小的删数方案。

输入格式:

第 1 行是1 个正整数 a。第 2 行是正整数k。

输出格式:

输出最小数。

比如第一次输入: 178543
再次输入: 4
那么将得出的输出答案是: 13

3、算法描述:

我们删除数字时,应从高位开始删除,例如上面的范例数字178543,要从中删除4位数字使得剩下的数字最小,那么第一个应该删除的是数字8,然后删除的是7,再然后就是5,最后删除的是4,最终看到结果就是13。基于此想法,并总结出规律:按高位到低位的顺序搜索,若各位数字递增,则删除最后一个数字;否则删除第一个递减区间的首字符,这样删一位便形成了一个新的数字串。然后回到串首,按上述规则再删除下一个数字。删除之后,其他数字往前移动一位,填补位置。最后把剩下的几个数字,组成一个整数。

while (k--) 
		{
			for (int i = 0; i < n; i++) 
			{
				if (a[i] > a[i + 1]) 
				{
					for (int j = i; j < n; j++) 
					{
						a[j] = a[j + 1];
					}
					break;
				}
			}
		}

4、算法时间及空间复杂度分析:

删数问题将字符串从头到尾遍历了一遍,如果前面的大于后面的就删掉,要遍历k遍,所以时间复杂度O(n*k)

空间复杂度跟数组大小有关,空间复杂度为O(n)

5、心得体会:

在做这道题时,经过和结对同学的激烈讨论,我们发现了删数的规律,并将其通过代码实现,但是在输出的时候遇到了一点问题,如何实现处理删除后的数字前面的0这个问题的代码让我们想了一段时间,最后终于找到了正确的能表达内心算法的代码,当最后得到的数前面好几位数字都是0时,设置一个m来标记第一个不为0的数字,从该位置m开始输出即可,

for (int i = 0; i < n; i++) 
        {
            if (a[i] != '0') 
            {
                m = i;
                break;
            }
        }
       for (int i = m; i < n; i++) 
       {
        cout << a[i];
       }

另外还有个小细节,当k=n的时候用我们的代码运行得到的输出是空的,于是我们又加了一个if语句设置这种情况下输出0 。该问题也用到了贪心的思想,贪心算法和动态规划类似,但没有动态规划那么繁琐,寻找问题的最优子结构这一步是关键。最后,还要感谢我的结对队友,如果没有你,就没有这么快乐高效的a题过程!当然还要感谢郑琪老师,教学严谨认真负责有趣,真的是位优秀的老师啊!

posted @ 2018-11-28 19:15  嘉兰  阅读(204)  评论(0编辑  收藏  举报