字符串去重、统计不同字符种类数问题

1、编写一个函数,计算字符串中含有的不同字符的个数。字符在ACSII码范围内(0~127),不在范围内的不作统计。

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

int main(){
    string str;
    int m,len,count=1;
    int flag = 0; //定义一个信号参数

    cin >> str;
    len = str.size();

    for(int i=0;i<len;++i){   //判断字符串中是否存在范围内字符,有则作为参照字符
    	if(str[i]<128&&str[i]>=0){
    		m = i;
    	}
        else{
            flag = 1; //若是所有字符均不在范围类,传递信号结束程序
        }
    }
    if(flag == 0){  
        for(int i=0;i<len-1;++i){   //先对字符串去超范围字符和重复字符,将不合要求的、重复的字符全部置为某个已存在的参照字符
           if(str[i]<128&&str[i]>=0){
                for(int j=i+1;j<len;++j){
                    if(str[i]==str[j]){
                        str[j]=str[m];
                    }
                }
           }
           else{str[i]= str[m];}
        }
        for(int i=0;i<len;++i){   //对去重后的范围内字符串求不同字符个数
    	    if(str[i]!=str[m]){
    		  count++;
    	    }
        }
    }
    else{
        count = 0;
    }
    cout << count << endl;
    return 0;
}

本题涉及到ASCII码表的的知识,需要考虑的情形比较多,首先是寻找范围内的参照字符顺便判断是否所有字符均在范围之外,因此定义信号参数。其次是去除重复、去除范围外的字符,最后遍历所有字符,得到不同字符的种类数目。

2、写出一个程序,接受一个(由字母和数字组成)字符串和一个字符,然后输出输入字符串中含有该字符的个数(不区分大小写)。

#include <iostream>
#include <string>

using namespace std;
int main(){
    int len,count=0;
    string str,c;
    cin >> str;
    len = str.size();
    cin >> c;
    for(int i=0;i<len;++i){
        if(str[i]==c[0]){
            count++; 
        }
    }
    cout << count << endl;
    return 0;
}

第一次编写这个程序时,直接考虑用string对象对字符和字符串进行比较操作,但是这种情形下,所有case的通过率为90%。是因为没有考虑大小写不区分的情形。本题也用到了ASCII码的相关知识,比较常见的知识点有:ASCII码0为空字符,ASCII码48~57为数字0~9,ASCII码65~90为字母A~Z,ASCII码97~122为字母a~z。加入对输入字符的判断

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

int main(){
    int len,count=0;
    string str,c;
    cin >> str;
    len = str.size();
    cin >> c;
    if(c[0]>64){ //若遍历寻找的目标字符是字母,那么要考虑字符串中字符ASCII码必须大于64
        for(int i=0;i<len;++i){
            if((str[i]==c[0]||str[i]+32==c[0]||str[i]-32==c[0])&&str[i]>64){ //无论字符串中字母是否大小写,考虑三种情形
                count++;
            }
        }
    }
    else{
        for(int i=0;i<len;++i){ //若输入字符为数字,那么字符串中字符只要与之相等即可
            if((str[i]==c[0]){
                count++;
            }
        }
    }
    cout << count << endl;
    return 0;
}

3、一道网易的字符串情景题:小易有一些彩色的砖块。每种颜色由一个大写字母表示。各个颜色砖块看起来都完全一样。现在有一个给定的字符串s,s中每个字符代表小易的某个砖块的颜色。小易想把他所有的砖块排成一行。如果最多存在一对不同颜色的相邻砖块,那么这行砖块就很漂亮的。请你帮助小易计算有多少种方式将他所有砖块排成漂亮的一行。(如果两种方式所对应的砖块颜色序列是相同的,那么认为这两种方式是一样的。)
例如: s = "ABAB",那么小易有六种排列的结果:
"AABB","ABAB","ABBA","BAAB","BABA","BBAA"
其中只有"AABB"和"BBAA"满足最多只有一对不同颜色的相邻砖块。

#include <iostream>
using namespace std;

void func(string&,int);
int main(){
    string str;
    int len;
    cin >> str;
    len = str.size();
    func(str,len);
    return 0;
}
void func(string& s,int length){  //定义一个字符串处理函数,传入string对象引用和string对象大小参数 
        int d, count = 0;
        for(int i=1;i<length-1;i++){  //第一步,去重,将重复的字符串全部置为首字符
            for(int j=i+1;j<length;j++){
                if(s[i]==s[j]){
                    s[j]=s[0];
                }
            }
        }
        for(int i=1;i<length;i++){ //第二步,统计不同于首字符的字符个数即为字符串中字符种类数目
            if(s[i]!=s[0]){
               count++;
            }
        }
        if(count > 1){
            cout << '0' << endl ;
        }
        else if(count == 0){
            cout << '1' << endl ;
        }
        else{
            cout << '2' << endl ;
        }
    }

本题题目结合了具体情境,抽象为字符串处理的程序之后,则比较简单。不外乎去重,统计字符串中不同字符的数目,因为砖的摆放方法只与颜色数目(字符种类)有关,因此转化为统计不同字符的数目即可。

4、找出字符串中第一个只出现一次的字符(考虑多个字符串输入)

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

int main(){
    string str;
    while(cin >> str){
        int len,count = 0;
        int flag = 0; //定义一个信号参数,在去重置空的两层循环中传递信号
        len = str.size();
        for(int i=0;i<len-1;i++){ //先将重复的字符全部置为空
                for(int j=i+1;j<len;j++){
                    if(str[i]==str[j]){
                        str[j]='\0';
                        flag ++;
                    }
                }
                if(flag > 0){
                     str[i]='\0';
                     flag = 0;
                }
        }
        for(int i=0;i<len;++i){ //遍历字符串输出第一个不为空的字符串
            if(str[i]!='\0'){
                cout << str[i] << endl;;
                count ++;
                break;
            }
         }
         if(count == 0){ //如果遍历字符串全部为空,则不存在“唯一”的字符
            cout << "-1" << endl;
         }
    }
    return 0;
}

之前在编写此程序时,牛客网上总显示通过case为90%,后来仔细检查才发现count初始化在while()语句之前,因此前一个字符串遍历后的count值会保留到之后的测试,所以出错。

编译和调试结果:

猜你喜欢

转载自blog.csdn.net/qq_34041083/article/details/81774478