【入门5】字符串
字符串
- P5733 大小写转换
- P1914 小书童——凯撒密码
- P1125 笨小猴
- P1957 口算练习题
- P5734 【深基6.例6】文字处理软件
- P1308 统计单词数
- P1765 手机
- P3741 honoka的键盘
- P1321 单词覆盖还原
- P1553 数字反转(升级版)
- P1603 斯诺登的密码
- P1597 赋值语句
- P1598 垂直柱状图
P5733 大小写转换
toupper 小–>大
tolower 大–>小
只能一个字母一个字母的来!!
#include
using namespace std;int main(){string s;cin>>s;for(int i=0;i<s.size();i++) s[i]=toupper(s[i]);cout<<s;
}
P1914 小书童——凯撒密码
大致题意 :输一串字符,向后移动n位,输出字符串
用string中的find()找到所求位置,输出下一位即可。
STL大法好
zi.find(a[i] 返回a[i]在zi中的下标位置
a[0]=q 在zi中下标是16 16+1=17
#include
using namespace std;string a,zi("abcdefghijklmnopqrstuvwsyzabcdefghijklmnopqrstuvwsyz");int main(){int n;//1 qwecin>>n>>a;cout<<zi.find(a[0]);for(int i=0;i<=a.length()-1;i++)cout<<zi[zi.find(a[i])+n];return 0;
}
P1125 笨小猴
maxn是单词中出现次数最多的字母的出现次数,minn是单词中出现次数最少的字母的出现次数,如果maxn-minn是一个质数,那么笨小猴就认为这是个Lucky Word
输出格式
第一行是一个字符串,假设输入的的单词是Lucky Word,那么输出“Lucky Word”,否则输出“No Answer”;
第二行是一个整数,如果输入单词是Lucky Word,输出maxn-minn的值,否则输出00。

#include
#include
#include
#include
using namespace std;char c;
map<char, int> vis;
int maxx = 0, minx = 0x3fffffff;bool sushu(int n) {if(n <= 1) return 0;for(int i = 2; i <= sqrt(n); ++i) if(!(n % i)) return 0;return 1;
}
int main() {while((c = getchar()) != '\n') vis[c]++;for(char ch = 'a'; ch <= 'z'; ++ch)if(vis[ch]) {maxx = max(maxx, vis[ch]);minx = min(minx, vis[ch]);}if(!sushu(maxx - minx))printf("No Answer\n0");else printf("Lucky Word\n%d", maxx - minx);return 0;
}
P1957 口算练习题

#include //cin & cout 用iostream
#include //memset & strlen 用cstring
#include //sscanf & sprintf 用cstdio
using namespace std;
int main(){char a;//a用于存储运算符int n,c,d;//n存储个数不解释,cd存储两个数字char s[100],b[10];//s存储最终的字符串,b临时变量cin>>n;for(int i=0;i<n;i++){cin>>b;//输入一串字符,有可能是运算符,也有可能是数字if(b[0]>='a' && b[0]<='z'){a=b[0];//如果是运算符就存入a,然后输入数字cin>>c>>d;}else{sscanf(b,"%d",&c);//如果是数字就转换b为int存储到第一个数字cin>>d;//然后输入剩下的第二个数字}memset(s,0,sizeof(s));//清空原有的字符串,防止长度判断错误if(a=='a') sprintf(s,"%d+%d=%d",c,d,c+d);else if(a=='b') sprintf(s,"%d-%d=%d",c,d,c-d);else if(a=='c') sprintf(s,"%d*%d=%d",c,d,c*d);cout<<s<<endl<<strlen(s)<<endl;//输出字符串和字符串长度}return 0;
}
P5734 【深基6.例6】文字处理软件
substr 生成子串,输入位置和长度
insert 在字符串中插入字符串
find 查找字符串中某个字符串的位置并返回它的位置
具体请见 :www.cplusplus.com
#include
using namespace std;int n,a;
string qwq;
string c1;
string b1;
int b,c,d=-1,e;int main(){cin>>n; cin>>qwq;for(int i=0;i<n;i++){cin>>a;if(a==1)//操作{cin>>b1;qwq+=b1; //后接插入,在文档后面插入字符串 str,并输出文档的字符串。 cout<<qwq<<endl;} else if(a==2){cin>>b>>c;qwq=qwq.substr(b,c);//截取文档部分,只保留文档中从第 b 个字符起 c 个字符,并输出文档的字符串。cout<<qwq<<endl;}else if(a==3){cin>>b>>b1;qwq.insert(b,b1);//插入片段,在文档中第 b 个字符[前]面插入字符串 b1,并输出文档的字符串。cout<<qwq<<endl;}else if(a==4){cin>>b1;if(qwq.find(b1)<qwq.size())//找不到会返回一个诡异的数字(反正比字符串长)cout<<qwq.find(b1)<<endl;//查找子串,查找字符串 str 在文档中最先的位置并输出;如果找不到输出 -1。elsecout<<-1<<endl;}}return 0;
}
P1308 统计单词数

C++重要的函数find
#include
#include
using namespace std;int main(){string s,ss;getline(cin,s);getline(cin,ss);for(int i=0;i<s.size();i++)s[i]=tolower(s[i]);for(int i=0;i<ss.size();i++)ss[i]=tolower(ss[i]);s=' '+s+' ';//必须加两个空格 ss=' '+ss+' ';if(ss.find(s)==-1)cout<<-1;else {int sum=0,n=0;while(ss.find(s,n)!=-1)//find找不到会返回npos也就是-1 {sum++;n=ss.find(s,n)+1; } cout<<sum<<" "<<ss.find(s);}return 0;
}
P1765 手机


#include
using namespace std;
int ans;
string a;
int num[26]={1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4}; //26个字母打表需要按几次
int main()
{getline(cin,a);for(int i=0;i<a.length();i++){if(a[i]>='a'&&a[i]<='z') ans+=num[a[i]-'a']; //不能写a[i]!=' ',因为还有'\n'和'\r' if(a[i]==' ') ans++; //不能写else因为也有'\n'和'\r',这就是这个题的坑点,我交了好几次,欲哭无泪 }cout<<ans;return 0;
}
#include
int sum,i,n;
char x,a[]={'a','p','t','w','z'+1};
int main()
{while (scanf("%c",&x)!=EOF)if (x>='a') {for (i=0;i<4&&x>=a[i+1];++i);sum+=(x-a[i])%((i&1)+3)+1;} else if (x==' ')++sum;printf("%d",sum);return 0;
}
P3741 honoka的键盘
这道题就是找两种子串
-
“VK”
-
“VV”或“KK”
第一个我们要判断;
第二个只要判断相邻两个字符相同就行了。
##注意:要用分类讨论的方法,不能两个两种条件一起判断,我就是这里坑了,费了我好长的时间。
#include
using namespace std; //头文件激活;
int main()
{int n,ans=0,x;//ans记达到条件的数量,要记得清零;string s;//我们伟大的字符串;cin>>n;//n是s的长度。cin>>s;//因为我们要输入的字符串里只有“V”和“K",所以用cin就行了;for(x=0;x<n-1;x++)//字符串的第一位都在是s[0]上,我们就从0开始判断到n-1,0位上有了就可以到s的长度减一。if (s[x]=='V'&&s[x+1]=='K') {ans++;s[x]='v';s[x+1]='k';}//s[x]和s[x+1]是两相邻的字符。如果条件符合,ans++,把这两的字符标记成以符合,注意,两个标记得不能相同。for(x=0;x<n-1;x++)//第二步;if (s[x+1]==s[x]) { ans++;cout<<ans;return 0;}//如果相邻两个相同,也就是“VV”或“KK”,就ans加一,输出答案,结束程序。cout<<ans;//如果没有相邻相同的就输出原来的数。return 0;//就这样,愉快的结束程序。
}
用c++的 STL解 把已经计入cnt的VK 转化成T 然后找VV 或者KK
#include
#include
#include
#include
using namespace std;
int main()
{int n,c=-1,cnt=0;string s,a="VK";cin >> n >> s;while (s.find(a, c + 1) != -1){cnt++;int t = s.find(a, c + 1);s[t] = 'T';s[t + 1] = 'T';c = t;}for (int i = 0; i < s.length()-1; i++){string w = "KK";string e = "VV";if (s.find(w) != -1){ cnt++; break; }if (s.find(e) != -1){ cnt++; break; }}cout << cnt;
}
改变一个字符,我们可以将VV或KK变为VK,从而增加一个答案。
所以说,如果当前的VV或KK没有一个在VK中出现过(因为如果出现过再修改是没有用的),那么我们就可以通过改变一个字符,将答案中VK的个数增加1,注意修改操作只能进行一次。
如何判断这个VV或KK有没有被使用过呢?我们可以记录一个数组,如果被使用过,就标记为true。
#include
#include
#include
using namespace std;
const int maxn=110;
int n,ans;
char s[maxn];
bool tf,f[maxn];//f数组表示第i个字符有没有被使用过
int main()
{scanf("%d%s",&n,s);for(int i=1;i<n;i++)if(s[i-1]=='V'&&s[i]=='K')ans++,f[i-1]=f[i]=true;//如果出现了VK,将答案+1,标记为已经使用for(int i=1;i<n;i++)if(!tf&&!f[i-1]&&!f[i]&&s[i-1]==s[i])tf=true,ans++;//如果有连续两个字符相同且没有被使用过,将答案+1,并不再进行此操作printf("%d\n",ans);return 0;
}
P1321 单词覆盖还原

拿boy举例
因为是覆盖的,所以如果是 b 就一定有一个boy
如果是 o ,就要分两种情况:
1:前面是 b ,那就是同一个单词
2:前面不是 b ,那就是被覆盖的单词, 是另一个单词,即另一个boy
y 同理,如果前面是 o ,那就是同一个单词,若果不是 o ,就是另一个单词
girl也是一样
从所输入的原字符串里去分别统计单词“boy”和“girl”的出现次数,其中
要注意的就是,有一部分的单词“boy”和“girl”是被覆盖了的,所以
我们不仅要统计已知的单词还要统计被覆盖了的单词,只有这样去统计
才能得到我们所要的正确结果
=============
首先,我们要有一个字符串,一个计算boy与一个计算girl的变量
用询问字符串来统计个数
如果是BOY,那要么是那一位是“b”,要么下一位是“o”
要么下一位是“y”;
同理,girl也是如此
#include
using namespace std;
int main() {int boy=0,girl=0;//boy和girl用来记下各自的个数 string st; cin>>st;for(int i=0;i<=st.length();i++){//开始发挥计算机的强大功能!if (st[i]=='b'||st[i+1]=='o'||st[i+2]=='y')//判断连着的三个字母是否为b、o、y boy++;//boy计数器加一 if (st[i]=='g'||st[i+1]=='i'||st[i+2]=='r'||st[i+3]=='l')//判断连着的三个字母是否为g、i、r、l girl++;//girl计数器加一 }cout<<boy<<endl;cout<<girl<<endl;return 0;
}
P1553 数字反转(升级版)

https://anguei.blog.luogu.org/solution-p1553
读如字符串后,判断字符串中是属于哪一种类型的数字。一共有四种情况:正整数、正实数、正分数、正百分数。
- 如果是正整数,先反转,再去掉前导零,输出。
- 如果是百分数,先按正整数方案做,最后输出一个百分号。
- 如果是分数或者实数,以分数线 / 小数点为分界,将字符串分为左右两部分,分别进行反转。
综上,我们有以下几个问题需要解决:
- 如何反转?用 STL 中的 std::reverse()。
- 如何去掉前导零?先遍历一遍字符串,看看有多少前导零,然后 std::string::erase() 即可。
- 如何提取出子字符串?std::string::substr()。
对于以上三个函数不是很懂?没关系,文末会有具体解释。 还有两点需要注意,分别是:
- 如果数字本身就是零,按照上面的做法会得到空串。所以需要特判。
- 小数点之后的部分还需要去掉“后导零”。
#include
#include
#include
using namespace std;
// 自己写的反转函数,返回反转并去掉前导零之后的字符串
string reverse(string s) {int zeroCount = 0;reverse(s.begin(), s.end()); // 反转// 范围 for 循环,用于统计前导零个数for (auto i : s)if (i == 48) ++zeroCount;else break;s.erase(s.begin(), s.begin() + zeroCount);return (s != "" ? s : "0"); // 特判
}// 用于去掉后导零
string deleteTail(string s) { int zeroCount = 0;for (int i = s.size() - 1; i >= 0; --i)if (s[i] == 48) ++zeroCount;else break;s.erase(s.end() - zeroCount, s.end());return (s != "" ? s : "0");
}int main() {string s;cin >> s;if (s.back() == '%') {cout << reverse(s.substr(0, s.size() - 1)) << "%" << endl;return 0;}for (auto i : s) {string left, right;// 其实还有一种不需要遍历字符串的做法,直接 find() 即可,但是当时没想到if (i == '/') {left = s.substr(0, s.find("/"));right = s.substr(s.find("/") + 1);cout << reverse(left) << "/" << reverse(right) << endl;return 0;}if (i == '.') {left = s.substr(0, s.find("."));right = s.substr(s.find(".") + 1);cout << reverse(left) << "." << deleteTail(reverse(right)) << endl;return 0;}}// 最后剩下的一种情况是正整数cout << reverse(s) << endl;return 0;
}
std::reverse(),顾名思义,用于反转序列。需要提供首尾迭代器作为参数。
std::string::erase(),传入两个迭代器 l,r,清除[l,r)范围内的字符。
std::string::substr(),用于提取子字符串,用法与前者类似。
std::string::find(),用来查找字串在母串中第一次出现的位置。
P1603 斯诺登的密码

当需要字符串对应数字时,map是非常好用的。
#include
#include
#include
using namespace std;
const int MX=66;map<string,int>q;
int st[MX],top;
string s;int main(){q["one"]=1;q["two"]=2;q["three"]=3;q["four"]=4;q["five"]=5;q["six"]=6;q["seven"]=7;q["eight"]=8;q["nine"]=9;q["ten"]=10;q["eleven"]=11;q["twelve"]=12;q["thirteen"]=13;q["fourteen"]=14;q["fifteen"]=15;q["sixteen"]=16;q["seventeen"]=17;q["eighteen"]=18;q["nineteen"]=19;q["twenty"]=20;q["a"]=1;q["both"]=2;q["another"]=1;q["first"]=1;q["second"]=2;q["third"]=3;//打表for(int i=1;i<=6;i++){//6个单词 cin>>s;if(q[s])//如果可以构成数字!!{int sum=q[s]*q[s]%100;if(sum==0)continue;//要是为0就没有必要存了st[++top]=sum;//从st[1]开始记录 } } sort(st+1,st+top+1);//从小到大排cout<<st[1];for(int i=2;i<=top;i++){if(st[i]<10)cout<<0;//不这样只能拿10分cout<<st[i];} return 0;
}
P1597 赋值语句

#include
#include
using namespace std;int a[3];
char s1,s2;
//a:=3;b:=4;c:=5;
int main(){while(scanf("%c:=%c;",&s1,&s2)==2)//scanf的返回值等于2是输入个数的意思a[s1-'a'] = isdigit(s2) ? s2-'0' : a[s2-'a'];//判断是否是0-9的 ,是的话就计入 printf("%d %d %d",a[0],a[1],a[2]);return 0;
}
P1598 垂直柱状图

#include
#include
using namespace std;map<char, int> m;
char c;int main()
{ //输入 while (cin >> c)if (c >= 'A' && c <= 'Z')m[c]++;//找最大值 int Max = -1;for (auto i : m)//map可以用auto便利 if (i.second > Max)Max = i.second;//取直方图高度//输出 for (int i = 0; i < Max; i++)//max行x {for (int j = 0; j < 26; j++)//26列y if (i >= Max - m[j + 'A'])//确保底在下面cout << "* ";elsecout << " ";cout << endl;}//输出 for (auto i : m)//map可以用auto便利 cout << i.first << " ";return 0;
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
