PAT字符串专题复习
-
最长连续公共子串求解
-
用最长不连续公共子序列的变形来做
-
思路:
①令dp[i] [j]表示字符串a中结尾为i和字符串b中结尾为j的前一段字符子串中连续公共子串的长度。例如afbc和abcde中,dp[4] [3] = 2, dp[4] [4] = 0.
②状态转移方程:
int maxlen = 0; //记录最长连续子串长度,注意不能最后直接输出dp[i][j]. if(a[i] == b[j]){ dp[i][j] = dp[i-1][j-1] + 1; maxlen = max(maxlen, dp[i][j]); }else{ dp[i][j] = 0; } cout << maxlen;
-
-
-
字符串排序
-
PAT A 1047 vector+char数组
-
当题目所给数据过大时,例如40000级别;使用string类型进行排序比使用char数组类型进行排序将慢的多。如果遇到string类型超时的时候,不妨换做char数组类型试一下。
-
此外,cmp函数对char数组排序需要熟练掌握。
char s[1010][5]; bool cmp(int a, int b){ return strcmp(s[a]), s[b]) < 0; //升序排序 }
-
#include<bits/stdc++.h> using namespace std; char name[40005][5]; vector<int> ans[40005]; //字符数组排序 bool cmp(int a, int b){ return strcmp(name[a], name[b]) < 0; } int main(){ int n, k, num, id; cin >> n >> k; for(int i = 0; i < n; i++){ cin >> name[i] >> num; while(num--){ cin >> id; ans[id].push_back(i); } } for(int i = 1; i <= k; i++){ printf("%d %d\n", i, ans[i].size()); sort(ans[i].begin(), ans[i].end(), cmp); for(int j = 0; j < ans[i].size(); j++){ printf("%s\n", name[ans[i][j]]); } } return 0; }
-
-
-
包含空格的字符串分割处理
-
题目描述:PAT A 1071
-
思路:
①首先使用getline(cin, str);读入一行包含空格的字符串。
②然后,使用isalnum函数判断是否是符合条件的字母和数字;如果是,就让t加上这个字符;如果不是则表明是分隔符,同时注意,最后一个单词右端不会出现分隔符,需要进行特判。
③另外,在使用map时,要先判断字符串是否为空,因为空的字符串也可以存入到map中。
string s = ""; mp[s] = 1; printf("%d", mp[s]); //输出 “1”
-
代码实现
#include<bits/stdc++.h> using namespace std; int main(){ string s, t; getline(cin, s); map<string, int> m; for(int i = 0; i < s.length(); i++){ if(isalnum(s[i])){ s[i] = tolower(s[i]); t += s[i]; } //当遇到不是数字字母即为分隔符或者到整行字符串末尾时 if(!isalnum(s[i]) || i == s.length() - 1){ //只有当t不为空时,才能进行map的相关操作;不然,空字符串也可以存储下来。 if(t.length() != 0)m[t]++; t = ""; } } int maxn = 0; for(auto it = m.begin(); it != m.end(); it++){ if(it->second > maxn){ t = it->first; maxn = it->second; } } cout << t << " " << maxn; return 0; }
-
-
-
字符串函数
-
isalnum(int c)函数,检查所传的字符是否是字母和数字。
//参数c是要检查的字符,函数返回bool类型值 char c = 'a'; if(isalnum(c)){ printf("'a'是字母"); } int a = 0; if(isalnum(a)){ printf("a是数字"); }
-
将字符转为大写字符或小写字符函数。tolower和toupper函数。【注意:只能对单个字符进行转换】
string s; for(int i = 0; i < s.length(); i++){ s[i] = tolower(s[i]); //转为小写字母 s[i] = toupper(s[i]);//转为大写字母 }
-
strcmp函数使用
①strcmp函数使用。返回值 < 0,表示str1 小于 str2;返回值 = 0, 表示相等;返回值 > 0,表示str1大于str2.
②在cmp函数中比较和与类似字符串“in”判断是否相等。
//strcmp函数在cmp中比较字符数组
struct node{
char s[30];
int time;
}
bool cmp(node a, node b){
if(strcmp(a.s, b.s) != 0){//表示两个字符数组不相等
return strcmp(a.s, b.s) < 0; //表示升序排序
}
else return a.time < b.time;
}//strcmp函数比较一个字符串和一个字符数组变量
char s[10];
if(strcmp(s, “in”) == 0){
……
}- map<string, int> 使用 ②map<string, int> 中可以存放字符数组类型。放入后会从字符数组类型变为string类型。 ```c++ char s[100]; cin >> s; mp[s] = 2;//char数组类型可以直接存入到map的string类型中,存入后char数组将变成string类型 auto it = mp.begin(); printf("%s %d", (it->first).c_str(), it->second);
-
-
字符串处理模拟题
-
A 1082 : 用中文表示数据读法
-
思路:
①整体思路是将数字按字符串方式处理,并设置下标left和right来处理数字的每一个节(个节、万节、亿节)的输出,即令left指向当前需要输出的位,而right指向与left同节的个位。
②在需要输出的某个节中,需要解决的问题是如何处理额外发音的零。处理方法如下:设置bool型变量flag表示当前是否存在累积的零。当输出left指向的位之前,先判断该位是否为0;如果为0,则令flag为true,表示存在累积的0;如果非0,则根据flag的值来判断是否需要输出额外的零。在这之后,就可以输出该位本身以及该位对应的位号(十、百、千)。而当整一小节处理完毕之后,再输出万或者亿。
-
代码实现
//太过复杂,看书上题解 #include<bits/stdc++.h> using namespace std; char num[10][5] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"}; char wei[5][5] = {"Shi", "Bai", "Qian", "Wan", "Yi"}; int main(){ char str[15]; cin >> str; int len = strlen(str); int left = 0, right = len - 1; //left与right分别指向字符串首尾元素 if(str[0] == '-'){ printf("Fu"); left++; } while(left + 4 <= right){ right -= 4; //让left与right到同一节 } while(left < len){//每次循环处理数字的一节 bool flag = false; //flag==false表示没有积累的0要输出 bool isPrint = false; //isPrint==false表示该节没有输出过其中的位 while(left <= right){//从左至右处理数字中某节的每一位 if(left > 0 && str[left] == '0'){//如果当前位不是首尾,且值为0 flag = true; } else{ if(flag){//等到遇到不是0的一位之后,输出积累的0 printf(" ling"); flag = false; } //只要不是首位, 后面的每一位前都要输出空格 if(left > 0)printf(" "); printf("%s", num[str[left] - '0']);//输出当前数字 isPrint = true;//该节至少有一位输出,所以这一节不能省略 if(left != right){//某一节中除了个位,其他位需要输出十百千 printf(" %s", wei[right - left - 1]); } } left++;//left往右移动1位 } if(isPrint == true && right!= len - 1){//只要不是个位,就输出万或亿 printf(" %s", wei[(len - 1 - right) / 4 + 2]); } right += 4; //right右移4位,输出下一节 } return 0; }
-
-