zoukankan      html  css  js  c++  java
  • PAT (Basic Level) Practice 1033 旧键盘打字 (20分) (string中的判断函数、find函数、erase函数)

    1.题目

    旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及坏掉的那些键,打出的结果文字会是怎样?

    输入格式:

    输入在 2 行中分别给出坏掉的那些键、以及应该输入的文字。其中对应英文字母的坏键以大写给出;每段文字是不超过 10​5​​ 个字符的串。可用的字符包括字母 [a-zA-Z]、数字 0-9、以及下划线 _(代表空格)、,.-+(代表上档键)。题目保证第 2 行输入的文字串非空。

    注意:如果上档键坏掉了,那么大写的英文字母无法被打出。

    输出格式:

    在一行中输出能够被打出的结果文字。如果没有一个字符能被打出,则输出空行。

    输入样例:

    7+IE.
    7_This_is_a_test.
    

    输出样例:

    _hs_s_a_tst

    2.题目分析

    1.这种题目思路就是遍历较为长的字符串,在短的字符串中做判断,这样方便也较为节省时间,开始我并没有这样做,导致思路臃肿,代码繁杂

    2.开始的思路就是遍历短的字符串,如果长字符串中有该字符就将其使用erase函数删掉(细节处理在代码中有注释)

    3.之后的思路就是直接遍历长的字符串,如果该字符在短的字符串中存在,就不输出直接跳过,无需使用erase函数删除

    4.坑点:+上档键就是shift键,出现+表示A~Z都坏了(原谅我不知道上档键是啥……)

    还有就是可能没有坏键,第一个字符串为空

    要删除的字符可能重复(方法一)

    3.知识分析

    参考(https://www.cnblogs.com/mini-coconut/p/8977796.html

    isdigit( )  检测字符串是否只由数字组成

    islower( )   检测字符串是否由小写字母组组成

    isupper( )  检测字符串中所有的字母是否都为大写

    isalpha( )  检测字符串是否只由字母组成

    isspace( )  检测字符串是否只由空格组成

    toupper()从小写变为大写

    tolower()从大写变为小写

    find函数: 

    find()查找字符、字符串,为空返回string::npos

    rfind() 是从指定位置起向前查找,直到串首 eg:list.rfind('a',6);

    find_first_of()  只要在源串中遇到一个字符,该字符与目标串中任意一个字符相同,就停止查找,返回该字符在源串中的位置

    例如:

    string str1("bcgjhikl");
        string str2("kghlj");
        cout << str1.find_first_of(str2, 0) << endl;
    //从str1的第0个字符b开始找,b不与str2中的任意字符匹配;再找c,c不与str2中的任意字符匹配;再找g,
     //g与str2中的g匹配,于是停止查找,返回g在str1中的位置2

    find_last_of() 从后向前找

    find_first_not_of()在源串中从位置pos开始往后查找,只要在源串遇到一个字符,该字符与目标串中的任意一个字符都不相同,就停止查找,返回该字符在源串中的位置;

     string str("abcdefg");
        cout << str.find_first_not_of("kiajbvehfgmlc", 0) << endl;//3
    //   从源串str的位置0(a)开始查找,目标串中有a(匹配),再找b,b匹配,再找c,c匹配,
     //    再找d,目标串中没有d(不匹配),停止查找,返回d在str中的位置3

     find_last_not_of()从后向前

    erase函数:参考(https://www.cnblogs.com/ylwn817/articles/1967689.html

    (1)erase(pos,n); 删除从pos开始的n个字符,比如erase(0,1)就是删除第一个字符
    (2)erase(position);删除position处的一个字符(position是个string类型的迭代器)
    (3)erase(first,last);删除从first到last之间的字符(first和last都是迭代器
    int main ()
    {
      string str ("This is an example phrase.");
      string::iterator it;
    
      // 第(1)种用法
      str.erase (10,8);//删除位置10后面的8个字符
      cout << str << endl;        // "This is an phrase."
    
      // 第(2)种用法
      it=str.begin()+9;
      str.erase (it);//删除一个字符
      cout << str << endl;        // "This is a phrase."
    
      // 第(3)种用法
      str.erase (str.begin()+5, str.end()-7);//删除一段字符
      cout << str << endl;        // "This phrase."
      return 0;
    }

    4.代码 

    开始的代码:

    #include<iostream>
    #include<string>
    #include<cstring>
    using namespace std;
    int main()
    {
    	string a;
    	string list;
    	getline(cin, a);//这里不能使用cin,因为可能键盘一个未错,a为空只有回车,cin自动过滤导致程序出错,但是getline不会过滤回车,a为空程序继续执行
    	getline(cin, list);
    	if (a.find('+') != string::npos)//这里出现+,表示A~Z都坏了
    	{
    		for (int i = 0; i <= 26; i++)
    		{
    			for (int j = 0; j < list.length(); j++)//原来这里使用while(list.find('A'+i)!=string::npos)list.erase(list.find('A'+i),1);
    			{                                      //使用while是因为后面可能还有同样的字符未删除,必须直到找不见才是删除干净,但是这样最后一个测试点超时
    				if (list[j] == ('A' + i))
    				{
    					list.erase(j, 1); j--;//于是使用遍历查找,又想到如果找到一次erase后,字符串长度就会变,所以删除一个后就将j--;保证每个字符都检验一遍
    				}
    			}
    		}
    	}
    
    	for (int i = 0; i<a.length(); i++)
    	{
    		
    		if (a[i] >= 'A'&&a[i] <= 'Z')//出现大写字符,将大小写全部检测
    		{
    			for (int j = 0; j < list.length(); j++)if (list[j] == a[i]) { list.erase(j, 1); j--; }
    			for (int j = 0; j < list.length(); j++)if (list[j] == (a[i] + 32)) { list.erase(j, 1); j--; }
    		}
    		else
    		{
    			for (int j = 0; j < list.length(); j++)if (list[j] == a[i]) { list.erase(j, 1); j--; }
    		}
    
    	}
    	cout << list << endl;
    
    }

    改进的代码:

    #include<iostream>
    #include<string>
    #include<cstring>
    using namespace std;
    int main()
    {
    	string a;
    	string list;
    	getline(cin, a);
    	getline(cin, list);
    	/*cin >> a;
    	cin>>list;*/
    	for (int i = 0; i < list.length(); i++)
    	{
    		if (islower(list[i]) && a.find(toupper(list[i])) != string::npos)continue;//如果是小写字符并且对应的大写字符在坏键字符串中,就不必输出
    		else if (isupper(list[i]) && (a.find(list[i]) != string::npos || a.find('+') != string::npos))continue;//如果是大写字符,在坏键字符串中或者是有+,不必输出
    		else if (a.find(list[i]) != string::npos)continue;//在坏键字符串中,不输出
    		cout << list[i];
    	}
    	cout << endl;
    }

  • 相关阅读:
    MVC新手指南
    BufferedReader方法-----Scanner方法
    sin=in.readLine();
    STL:string 大小(Size)和容量(Capacity)
    2014=9=24 连接数据库2
    2014=9=24 连接数据库1
    常用英语单词
    Linux权限详解(chmod、600、644、666、700、711、755、777、4755、6755、7755)
    linux 常用快捷键
    启动sh文件注意的问题
  • 原文地址:https://www.cnblogs.com/Jason66661010/p/12788959.html
Copyright © 2011-2022 走看看