本篇博客主要记录string
类的相关oj
题,后续会持续更新,题目为入门基础题,目的是帮助初学string
类的友友们熟悉使用string
类.
题目包含:字符串最后一个单词的长度、 2.反转字符串 II、字符串相加
题目来源于:牛客
题目链接:传送门
计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000
。(注:字符串末尾不以空格为结尾)
输入描述:
输入一行,代表要计算的字符串,非空,长度小于
5000
。
输出描述:
输出一个整数,表示输入字符串最后一个单词的长度。
示例1:
输入:
hello nowcoder
输出:
8
说明:
最后一个单词为nowcoder,长度为8
string
类对象input
.getline
函数获取带有空格的字符串.空格
就将num
清零.(因为表示不是最后一个单词)num
即可.#include
using namespace std;
int main() {
string input;
getline(cin, input);//获取一行字符串
int num=0;//记录单词的长度
for(int i=0;i<input.size();i++)
{
if(input[i]==' ')num=0;//每次遇到空格都清零
else num++;
}
cout<<num<<endl;
return 0;
}
方法二:
从后往前
遍历,遇到第一个空格,则表示最后一个单词结束,即返回长度.#include
using namespace std;
int main() {
string input;
getline(cin, input);//获取行
int num=0;
for(int i=input.size()-1;i>=0;i--)
{
if(input[i]==' ')break;
num++;
}
cout<<num<<endl;
return 0;
}
知识点:
getline
函数可以获取带有空格的字符串.string
对象的长度通过调用对象的size()
函数获得.题目来源于:力扣
题目链接:传送门
给定一个字符串 s
和一个整数 k
,从字符串开头算起,每计数至 2k
个字符,就反转这 2k
字符中的前 k
个字符。
k
个,则将剩余字符全部反转。2k
但大于或等于 k
个,则反转前 k
个字符,其余字符保持原样。示例1:
输入:s = “abcdefg”, k = 2
输出:“bacdfeg”
示例2:
输入:s = “abcd”, k = 2
输出:“bacd”
string
类对象,每次走到2k
的倍数时,反转前k
个字符.k
个的时候,反转剩下的所有字符.class Solution {
public:
string reverseStr(string s, int k) {
int n = s.size();
for (int i = 0; i < n; i += 2 * k) {
if(i+k>n)//剩余字符串不足k
{
reverse(s.begin() + i ,s.begin()+n);//反转剩下的所有字符
}
else
reverse(s.begin() + i, s.begin() +i+k);反转前k个字符
}
return s;
}
};
知识点:
begin()
用于返回string对象的起始位置. reverse
函数可以用于实现反转,reverse(开始位置,结束位置)
;题目来源于:力扣
题目链接:传送门
给定两个字符串形式的非负整数 num1
和num2
,计算它们的和并同样以字符串形式返回。
你不能使用任何內建的用于处理大整数的库(比如 BigInteger
), 也不能直接将输入的字符串转换为整数形式。
示例 1:
输入:num1 = “11”, num2 = “123”
输出:“134”
示例 2:
输入:num1 = “456”, num2 = “77”
输出:“533”
示例 3:
输入:num1 = “0”, num2 = “0”
输出:“0”
string
类对象.carry
记录是否需要进位.sum
对象(用于保存最后的和的输出结果).剩余部分+进位
继续处理尾插入sum
对象.剩余部分+进位
继续处理尾插入sum
对象.为何要反转?
因为计算结果是尾插进入sum对象的,那为啥非要尾插呢?头插不行吗?
学过顺序表的友友们应该知道:
进位数说明:
题目要求一个结点只能存个位数,所以需要保留进位数到下一个结点.
算进位数:
这是很基本的数学问题,两数相加,大于10的部分需要进位.
class Solution {
public:
string addStrings(string num1, string num2) {
int carry = 0;
string sum;
//分别获取两个对象最后一个字符的小标位置
int end1 = num1.size() - 1;
int end2 = num2.size() - 1;
while (end1>=0 && end2>=0)
{
int num = num1[end1--] - '0' + num2[end2--] - '0' + carry;
//处理进制
carry = num / 10;
//只保留个位数
num %= 10;
//将和的结果尾插入sum对象
sum.push_back(num + '0');
}
//如果对象1没有走完
while (end1>=0)
{
int num = num1[end1--] - '0' + carry;
//处理进制
carry = num / 10;
//只保留个位数
num %= 10;
sum.push_back(num + '0');
}
//如果对象2没有走完
while (end2>=0)
{
int num = num2[end2--] - '0' + carry;
//处理进制
carry = num / 10;
//只保留个位数
num %= 10;
sum.push_back(num + '0');
}
//最后一个位是否需要进位
if(carry==1)
{
sum.push_back('1');
}
//将最终结果反转
reverse(sum.begin(), sum.end());
return sum;
}
};
建议画图分析:
class Solution {
public:
string addStrings(string num1, string num2) {
int carry = 0;
string sum;
//计算最后一个字符的下标
int end1 = num1.size() - 1;
int end2 = num2.size() - 1;
while (end1 >= 0 || end2 >= 0)
{
//谁短,谁就为'0'
char s1 = end1 >= 0 ? num1[end1] : '0';
char s2 = end2 >= 0 ? num2[end2] : '0';
int num = s1-'0' + s2-'0' + carry;
//处理进制
carry = num / 10;
//只保留个位数
num %= 10;
sum.push_back(num + '0');
end1--;
end2--;
}
//防止最后一个字符的进位问题
if (carry == 1)
{
sum.push_back('1');
}
//最后反转字符串
reverse(sum.begin(), sum.end());
return sum;
}
};