删数问题
一、 贪心策略:从给定的数字中,找到升序的最后一个数,也可以说是降序的首个数。
如:
178543
4
1 7 8 为一个升序,8是最后一个,删除, 原数字变为17543
1 7 为一个升序, 7是最后一个,删除 ,原数字为 1543
以此类推,知道删除4个,最后即为 13
13
二、实现代码如下
#include<iostream>
#include<algorithm>
#include<string.h> // strlen() 的头文件
using namespace std;
int main(){
char D[1000]; // 默认空格初始化
// cout<<D[0]<<endl;
// cout<<D<<endl; // 输出D每个字符,相当于输出字符串
cin>>D;
int len=strlen(D); // 字符串求长度,不能用D.length(),因为非数组,此时D为字符串
int n;
cin>>n;
for(int i=0;i<n;i++){ // 总共删除n次,用for取每一次
int j=0;
while(D[j]<=D[j+1]){
j++;
}
while(j<=len-1){
D[j]=D[j+1]; // 后面的数字覆盖到前面过来
j++;
}
len--; // 总长度减1,因为删除一次
}
// 输出:注意0XX这样的输出,需要去掉前面的0
int is=0; // 用于判断首位是否为0,直到遍历出现 非0 数 则置 1
for(int i=0;i<len;i++){
if(D[i]=='0' && is==0)// 注意字符和数字的表达,D存的是字符,is是整数
continue; // 不搭理,跳过
if(D[i]!=0){ // 遍历到非0数了
is=1; // 置 1,可以输出0啦
cout<<D[i]; // 不需要换行
}
}
return 0;
}
-----------------------------------------------分割线----------------------------------------------------
可以利用string的erase()函数能更简洁实现,代码如下:
/*
贪心策略:
数字从高位到低位,如果一个数字比它后面的数字大,就删除该数字;
否则删除最后一位数字
*/
#include<iostream>
using namespace std;
int main()
{
string s;
int n;
cin>>s>>n;
while(s.size()>0 && n>0){ // s.size() 求s的长度,也可以用strlen(s)
n--;
int i=0;
while(i<s.size()-1 && s[i]<s[i+1] ) // s.size()-1 是因为总要跟后一个比较,防止越界
i++;
s.erase(i,1); // s.erase(位置,个数)
}
// 清首位0操纵
while(s.size()>1 && s[0]=='0'){ // >1 是因为可能s为000,那么必须保留一个
s.erase(0,1);
}
cout<<s<<endl;
return 0;
}