算法第四章上机实践报告

一、实践题目:删数问题

二、问题描述:

       给定一个n位的正整数a,去掉其中任意k(k≤n) 个数字后,剩下的数字按照原次序排列成一个的新的正整数。在给定的n位正整数a和正整数k的情况下,输出完成该操作后剩下的正整数。

三、算法描述:

       正整数的位数不定,用long long去存不一定存的下,所以用一个字符数组str[]来存储。此处运用一种贪心策略,不停的对这个整数进行扫描,当发现当前位的后一位比当前位小的情况,将当前位删除(例如1873,删除8肯定比删除7更优),若所有位数的数字按照升序排列,则删除最后一位。注意要将字符串前导的0删除掉,故要对得到的新数组进行分类讨论。

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 char str[1005];
 5 int main(){
 6     int k,flag=1;
 7     cin>>str>>k;
 8     int len=strlen(str);
 9     int temp=len;//temp用于记录已经保留的位数 
10     while(temp!=len-k){
11         for(int i=0;i<len;i++){
12             if(str[i]>str[i+1]){
13                 for(int j=i;j<len;j++){
14                     str[j]=str[j+1];    
15                 }
16                 temp--;
17                 break;
18             }
19         }
20     }
21     if(temp==0){
22         cout << '0';
23     }
24     else{
25         for(int i=0;i<len-k;i++){
26             if(str[i]=='0'&&i==(len-k-1)){
27                 cout <<'0'; 
28             }
29             else if(str[i]=='0'&&flag==1){
30                 continue;
31             }
32             else{
33                 flag++;
34                 cout<<str[i];
35             }
36         }
37     }
38 }   

四、算法分析

       时间复杂度:这段代码在一个长度为n的数组中删除k个,进行了k次的扫描,故循环的次数为k,时间复杂度为O(kn),最后输出结果的时候对剩余的位数进行了一次“去0操作”,复杂度为O(n-k),因为k为整数,故综合的时间复杂度为O(n)。

       空间复杂度:运用了一个字符型数组进行存储,故空间复杂度为O(n)。

五、心得体会

       第三题时队友将问题过分复杂化了,以为是一个0-1背包,后来经过讨论觉得只需将数组进行排列,从小到大放入即可。在做这道题的时候,在贪心策略方面想的比较久,在有思路后处理字符串删除的过程中又出现了问题,并且在答案错误后发现遗漏了全删和前导0的情况,又增加了一些代码。这道题考察了许多的细节,而且贪心策略也不是非常的明显,让我们在结对编程中更加注意细节,更加的耐心。

posted @ 2018-12-01 11:49  晓风长路  阅读(143)  评论(0编辑  收藏  举报