
🫧个人主页:小年糕是糕手
🎨你不能左右天气,但你可以改变心情;你不能改变过去,但你可以决定未来!
目录
一、标题统计
思路一
我们直接通俗来解释这个题目就是输入一个字符串(可能有空格),统计不含空白符的字符个数,这里我们的直观想法就是定义一个size_t类型的count来统计,然后通过循环遍历这个字符串的形式来统计,如果遇到空格就跳过,不是空格count就++:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
getline(cin, s);
size_t count = 0;
for (auto it1 = s.begin(); it1 != s.end(); it1++)
{
if ((*it1) == ' ')
continue;
else
count++;
}
cout << count << endl;
return 0;
}
isspace
这里给大家介绍一个函数:isspace
✅ isspace 是函数
✅ 作用:判断字符是不是空白
✅ 必须加:#include <cctype>
✅ 比手动判断空格更通用
下面我们来对上述的代码进行优化:
#include<iostream>
#include<string>
#include<cctype>
using namespace std;
int main()
{
string s1;
getline(cin, s1);
size_t count = 0;
for (auto st1 = s1.begin(); st1 != s1.end(); st1++)
{
// 只判断:不是空格就计数
if (isspace(*st1))
continue;
else
count++;
//这里不用判断换行符,因为getline读的没有换行符
}
cout << count << endl;
return 0;
}
思路二
其实这里还有一种方法就是按照单词读取
有时候处理一个字符串的时候,也不一定要一次性读取完整个字符串,如果字符串中有空格的话,其实可以当做多个单词,依次读取
cin >> s会返回一个流对象的引用,即cin本身。在 C++ 中,流对象(如cin)可以被用作布尔值来检查流的状态。如果流的状态良好(即没有发生错误),流对象的布尔值为true。如果发生错误(如遇到输入结束符或类型不匹配),布尔值为false。
在
while (cin >> s)语句中,循环的条件部分检查cin流的状态。如果流成功读取到一个值,cin >> s返回的流对象cin将被转换为true,循环将继续。如果读取失败(例如遇到输入结束符或无法读取到一个值),cin >> s返回的流对象cin将被转换为false,循环将停止。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
int ans = 0;
while (cin >> s)
{
ans += s.size();
}
cout << ans << endl;
return 0;
}
真实执行过程
输入:
hello world zmzz第一步:
cin >> s开始工作→ 先看前面有没有空格?有!跳过!→ 读到hello→ 遇到空格,停下→ 把hello放进 s第二步:
下一次
cin >> s→ 中间的空格直接跳过!根本不读!→ 读到world→ 遇到空格,停下第三步:
再一次
cin >> s→ 空格继续跳过→ 读到zmzz
重点:空格去哪了?
空格根本没进入 s 里面!
cin 自动把它们当成 “分隔符”,直接忽略!
最终总结(你必须记住)
cin >> 字符串= 自动跳过所有空白 → 读一个完整单词 → 停下
所以:
hello world zmzz会被自动拆成hello、world、zmzz一个一个读进去!
while (cin >> s)到底怎么工作?
cin >> s自带跳过空格、换行、Tab它会自动忽略所有空白,只抓单词。- 每次只读一个单词读到空格 / 换行就停,空格绝对不会读进字符串里。
- 循环条件
cin >> s读到单词 → true → 继续循环读不到了 → false → 结束循环- 输入
hello world zmzz会自动拆成:hello→world→zmzz三次循环,依次读取。
二、石头剪子布
这个题目其实没啥好赘述的就是单纯多次输入加判断即可,下面给出代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1;
string s2;
int N = 0;
cin >> N;
while (N--)
{
cin>>s1;
cin>>s2;
if (s1 == s2)
cout << "Tie" << endl;
else if (s1 == "Rock" && s2 == "Scissors")
cout << "Player1" << endl;
else if (s1 == "Scissors" && s2 == "Paper")
cout << "Player1" << endl;
else if (s1 == "Paper" && s2 == "Rock")
cout << "Player1" << endl;
else
cout << "Player2" << endl;
}
return 0;
}
三、密码翻译
这个题目与第一题其实是有类似的地方的,但是这里我们需要注意的是解密与加密:

#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
getline(cin, s);
for (int i = 0; i < s.size(); i++)
{
if ((s[i] >= 'b' && s[i] <= 'z') || (s[i] >= 'B' && s[i] <= 'Z'))
s[i] -= 1;
else if (s[i] == 'a')
s[i] = 'z';
else if (s[i] == 'A')
s[i] = 'Z';
}
cout << s << endl;
return 0;
}
四、文字处理软件
这是一道相对综合的题目,我们需要熟练使用string中的一些重载的成员函数,知道+=,substr()、find(),这些成员函数会大大提高我们的解题速度
#include<iostream>
#include<string>
using namespace std;
int main()
{
int n;
cin >> n;
string s;
cin >> s;
int a, b;
string str;
while (n--)
{
int m = 0;
cin >> m;
switch (m)
{
case 1:
cin >> str;
s += str;
cout << s << endl;
break;
case 2:
cin >> a >> b;
s = s.substr(a, b);
cout << s << endl;
break;
case 3:
cin >> a;
cin >> str;
s.insert(a, str);
cout << s << endl;
break;
case 4:
cin >> str;
size_t pos = s.find(str);
if (pos == string::npos)
cout << -1 << endl;
else
cout << pos << endl;
break;
}
}
return 0;
}
五、单词的长度
思路一
这里我们的第一个思路大家都能想到的肯定是读取整个字符串的长度,然后统计字符个数,跳过空格
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
getline(cin, s); // 一次读完整行(包括空格)
int count = 0; // 记录当前单词长度
bool first = true;
// 逐个字符遍历
for (int i = 0; i < s.size(); i++)
{
// 如果不是空格 → 计数+1
if (s[i] != ' ')
{
count++;
}
// 如果是空格 且 前面有计数 → 输出
else
{
if (count > 0)
{
if (!first)
cout << ",";
cout << count;
first = false;
count = 0; // 重置
}
}
}
// 最后一个单词(因为结尾没有空格)
if (count > 0)
{
if (!first) cout << ",";
cout << count;
}
cout << endl;
return 0;
}
思路二
这里我们可以使用while(cin>>s),将他一段一段读取进去,然后统计:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
cin >> s;
cout << s.size(); // 先处理⼀下第⼀个单词,因为最后⼀个单词不需要加逗号
while (cin >> s) // ⼀个字符串⼀个字符串的读,跳过空格,并且读取结束后终⽌循环
{
cout << "," << s.size();
}
return 0;
}
六、单词翻转
思路一
这题其实非常的常见,关于翻转字符类的,我们可以定义一个left和right分别指向两边,然后进行交换,left++,right--以实现操作,记住在进行操作的时候我们需要一个中间变量进行存储,否则无法实现交换:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
while (cin >> s)
{
//翻转单词
int left = 0;
int right = s.size() - 1;
while (left < right)
{
char tmp = s[left];
s[left] = s[right];
s[right] = tmp;
left++;
right--;
}
cout << s << endl;
}
return 0;
}
reverse
但是这种翻转是我们手写的,其实有更简单的方法,思路还是一样,其实在C++的STL中,包含一个算法叫reverse,可以完成字符串的逆序(翻转),需要的头文件是<algorithm>,之前我们说过这是一个关于算法的头文件:
void reverse (BidirectionalIterator first, BidirectionalIterator last);
//first: 指向要反转范围的第⼀个元素的迭代器(也可以是地址)
//last: 指向要反转范围的最后⼀个元素的下⼀个位置的迭代器(也可以是地址)(翻转时不包括此元
素)。
reverse(s.begin(), s.end());
reverse会逆序范围[first,last)内的元素
下面我们来做个测试:
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
//反转字符串
string s("zhui ming zhen zhou");
reverse(s.begin(), s.end());
cout << s << endl;
//反转数组
int arr[] = { 2,6,3,6,5,5,3,9,3 };
int size = sizeof(arr) / sizeof(arr[0]);
//对数组中的元素进⾏反转
reverse(arr, arr + size);
for (auto e : arr)
{
cout << e << " ";
}
cout << endl;
return 0;
}

最后给出此题的代码:
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
string str;
while (cin >> str)
{
reverse(str.begin(), str.end());
cout << str << endl;
}
return 0;
}
七、回文字符串
思路一
其实这题和翻转字符的思路特别像,只不过中间多了对字符串的判断,下面给出代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
cin >> s;
int left = 0;
int right = s.size() - 1;
while (left < right)
{
if (s[left] == s[right])
{
left++;
right--;
}
else
{
cout << "no" << endl;
return 0;
}
}
cout << "yes" << endl;
return 0;
}
思路二
这里还有一种思路就是我们利用上面说过的reverse对字符串进行逆序,然后用逆序完的字符串和之前的字符串进行比较,如果一致则可以判断这是个回文字符串:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
string s1;
cin >> s1;
string s2 = s1;
reverse(s1.begin(), s1.end());
if (s1 == s2)
cout << "yes" << endl;
else
cout << "no" << endl;
return 0;
}
八、手机
这里我们的思路就是把26个字母的按键次数存储下来,当有一个字符来的时候,就将这个按键次数累加上去就行

这里我们需要知道的一点是'a' - 'a' = 0、'b' - 'a' = 1、下面给出代码:
#include<iostream>
#include<string>
using namespace std;
int count[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 };
// a b c d e f g h i j k l m n o p q r s t u v w x y z
int main()
{
string s;
int sum = 0;
getline(cin, s);
for (auto ch : s)
{
if (ch == ' ')
sum += 1;
else
sum += count[ch - 'a'];
}
cout << sum << endl;
return 0;
}
九、口算练习题
#include<iostream>
#include<string>
using namespace std;
int main()
{
int i = 0;
cin >> i;
string op;//操作
string last;
while (i--)
{
string ans;
//输入数据
cin >> op;
if (op == "a" || op == "b" || op == "c") //说明这一行有三个数据
{
int n1, n2;
int ret = 0;//计算的结果
cin >> n1 >> n2;
ans += to_string(n1);
if (op == "a")
{
ret = n1 + n2;
ans += "+";
ans += to_string(n2);
ans += "=";
ans += to_string(ret);
}
else if (op == "b")
{
ret = n1 - n2;
ans += "-";
ans += to_string(n2);
ans += "=";
ans += to_string(ret);
}
else
{
ret = n1 * n2;
ans += "*";
ans += to_string(n2);
ans += "=";
ans += to_string(ret);
}
last = op;
}
else //说明这一行只有两个数据,执行上一次的运算
{
int n1, n2;
int ret = 0;
n1 = stoi(op);
ans += to_string(n1);
cin >> n2;
if (last == "a")
{
ret = n1 + n2;
ans += "+";
ans += to_string(n2);
ans += "=";
ans += to_string(ret);
}
else if (last == "b")
{
ret = n1 - n2;
ans += "-";
ans += to_string(n2);
ans += "=";
ans += to_string(ret);
}
else
{
ret = n1 * n2;
ans += "*";
ans += to_string(n2);
ans += "=";
ans += to_string(ret);
}
}
cout << ans << endl;
cout << ans.size() << endl;
}
return 0;
}
一、头文件与命名空间
#include<iostream> // 用于输入输出(cin/cout) #include<string> // 用于字符串操作(string) using namespace std; // 简化代码,不用写std::cin/std::cout
二、主函数入口 & 基础变量
int main() { int i = 0; cin >> i; // 输入一个整数i,表示**要计算的总次数** string op; // 存储当前输入的**运算符**(a/b/c/数字) string last; // 存储**上一次使用的运算符**(复用功能用)
i:控制循环次数,比如输入3,就计算 3 次op:核心变量,判断本次输入是运算符还是数字last:记忆功能,记录上一次用的是 +/-*
三、核心循环(执行 i 次计算)
while (i--) // 循环i次,每次i减1 { string ans; // 存储最终要输出的完整算式(如 3+5=8)
四、分支 1:输入带运算符(a/b/c)
cin >> op; // 读取第一个输入值 // 如果op是a/b/c,说明本次输入:运算符 + 数字1 + 数字2 if (op == "a" || op == "b" || op == "c") { int n1, n2; // 两个运算数字 int ret = 0; // 存储计算结果 cin >> n1 >> n2; // 读取两个数字 ans += to_string(n1); // 把数字转字符串,拼接到算式里运算逻辑(a = 加,b = 减,c = 乘)
if (op == "a") // 加法 { ret = n1 + n2; ans += "+"; ans += to_string(n2); ans += "="; ans += to_string(ret); } else if (op == "b") // 减法 { ret = n1 - n2; ans += "-"; ans += to_string(n2); ans += "="; ans += to_string(ret); } else // 乘法(op==c) { ret = n1 * n2; ans += "*"; ans += to_string(n2); ans += "="; ans += to_string(ret); } last = op; // ✨关键:把本次运算符存起来,下次复用 }
五、分支 2:输入不带运算符(纯数字)
else // op不是a/b/c,说明是**数字**,本次输入:数字1 + 数字2 { int n1, n2; int ret = 0; n1 = stoi(op); // 把第一个输入的字符串数字 → 整数 ans += to_string(n1); cin >> n2; // 读取第二个数字沿用上一次的运算符计算
if (last == "a") // 上次是加法 else if (last == "b") // 上次是减法 else // 上次是乘法 { // 逻辑和上面完全一样,拼接算式、计算结果 } }
六、输出结果
cout << ans << endl; // 输出完整算式(如 10*2=20) cout << ans.size() << endl; // 输出算式的字符个数(长度) } return 0; }
程序运行示例(一看就懂)
输入:
3 a 1 2 5 3 c 4 5执行过程:
第一次输入
a 1 2
- 运算符:a (+) → 1+2=3
- 输出:
1+2=3和 长度5- 记录
last = a第二次输入
5 3
- 第一个值是数字,沿用上次 +
- 5+3=8
- 输出:
5+3=8和 长度5第三次输入
c 4 5
- 运算符:c (×) →4×5=20
- 输出:
4*5=20和 长度5最终输出:
1+2=3 5 5+3=8 5 4*5=20 5
核心功能总结
- 三种运算:
a= 加、b= 减、c= 乘- 记忆功能:不输入运算符时,自动用上一次的运算
- 输出格式:先打印完整算式,再打印算式的字符长度
- 循环计算:可以连续计算 N 次,输入 N 即可
总结
- 这是一个带记忆功能的控制台计算器,用字符串判断运算类型
- 核心逻辑:判断第一个输入是运算符还是数字,分支处理
- 关键知识点:
string字符串拼接、to_string()数字转字符串、stoi()字符串转数字
转载自CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/2501_91731683/article/details/159083778




