《华为机试在线训练》之删除字符串中出现次数最少的字符

题目描述

实现删除字符串中出现次数最少的字符,若多个字符出现次数一样,则都删除。输出删除这些单词后的字符串,字符串中其它字符保持原来的顺序。 

输入描述:

字符串只包含小写英文字母, 不考虑非法输入,输入的字符串长度小于等于20个字节。

输出描述:

删除字符串中出现次数最少的字符后的字符串。

示例1

输入

abcdd

输出

dd
        刚开始我看到这个题目的时候,第一反应是怎么将26个字母出现的次数记录下来,只要我将每个字母出现的次数记录下来,就可以将每个字母出现的次数排序,选出出现次数最少的那些,然后在输出的剔除那些就可以,原理很简单,但是最开始我的做的时候采用了结构体,将26个字母跟对应的次数联系在一起。

一,第一版代码

       如下所示:

typedef struct
{
    int word;
    int num;
}stu;

    stu stu_count[27];
    for(int i=0;i<27;i++)
    {
        stu_count[i].word='a'+i;
        stu_count[i].num=0;
    }
        这个时候自己单纯地以为这样处理很方便但是我没有想到隐藏的问题所在,继续往下,我目的是想要将出现的字母的次数都记录在stu[i].num中,但是却没有实现应有的功能,原因是我没有将字母跟下标的关系理解清楚,导致出现了错误,这时是不可行的,错误代码为:

for(int j=0;j<27;++j)
       {
           for(unsigned int i=0;i<str.length();++i)
           {
              if(str[i]==stu_count[j].word)
                 stu_count[j].num++;
                 //cout<< stu_count[j].num<<endl;
           }

       }

      假如这一步处理成功,那么下一步是不是应该求出出现的最小次数了,我天真地写出代码:

 

 int min = stu_count[0].num;
       cout<<min<<endl;
       for(int i=1;i<27;++i)
       {
            if(stu_count[i].num<min)
                min=stu_count[i].num;
       }
    写到这个的时候我还没有发现问题所在,于是我将输出写完,代码如下:

     

 for(unsigned int i=0;i<str.length();++i)
       {
           for(int j=0;j<27;++j)
           {
              if(stu_count[j].num>min)
                 cout<<str[i];
           }

       }
    到这个时候运行后我才发现,我没有将下标跟字母联系在一起,这是所有问题所在,肯定不会得出正确的输出。

二,于是改正代码如下:

      仔细想想怎样才可以将字母跟下标联系在一起,那就是将字母转换为数字,这个时候就出现了字符间的相减,如下所示

  

for(int i=0;i<26;i++)
            a[i]=0;
        for(unsigned int i=0;i<str.length();++i)
            a[str[i]-'a']++;

     是不是很巧妙地实现了要求,这个时候a[]数组中存放的就是对应字母的个数,接下来同样是进行最小值求解,直接在循环中使用If语句进行判断,如下所示:

min=a[str[0]-'a'];
        for(unsigned int i=0;i<str.length();++i)
        {
            if(a[str[i]-'a']<=min)
            min=a[str[i]-'a'];
        }

      上面提取出了最小的出现的次数,下面输出的时候就可以根据这个最小值进行判断,然后输出正确的结果,如下

for(unsigned int i=0;i<str.length();++i)
        {
            if(a[str[i]-'a']>min)
                cout<<str[i];
        }
        cout<<endl;
      这里一定要注意加上cout<<endl;不加上结果输出不正确,这是一个要注意的点,

三,最后的完整代码

      

#include <iostream>
#include <string>
using namespace std;


int main()
{
    string str;
    int min;
    int a[26];
    while(cin>>str)
    {
        for(int i=0;i<26;i++)
            a[i]=0;
        for(unsigned int i=0;i<str.length();++i)
            a[str[i]-'a']++;
        min=a[str[0]-'a'];
        for(unsigned int i=0;i<str.length();++i)
        {
            if(a[str[i]-'a']<=min)
            min=a[str[i]-'a'];
        }

        for(unsigned int i=0;i<str.length();++i)
        {
            if(a[str[i]-'a']>min)
                cout<<str[i];
        }
        cout<<endl;
    }
    return 0;
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值