
༺ 个人主页 · 纪念229 ༻
༒专栏目录:《算法》༒
༒专栏目录:《C++》༒
༒专栏目录:《MySQL数据库》༒
༒专栏目录:《前端开发》༒
༺世上本没有路,走的人多了自然就有了༻
本篇文章讲述的是有关string类的一些算法题,希望对你有所帮助
题目链接:
文章目录
1.字符串转整形数字

代码展示:
c
class Solution {
public:
int myAtoi(string str) {
int i = 0;
while(str[i] == ' ')
{
i++;
}
int flag = 1;
if(str[i] == '+' || str[i] == '-')
{
flag = str[i] == '-' ? -1 : 1;
i++;
}
int num = 0;
int degit;
while(i < str.size() && (str[i] >= '0' && str[i] <= '9'))
{
//int_max=2147483647 int_min=-2147483648
//如果num > int_max / 10 || (num == int_max / 10 && degit > 7)就说明已经超越int最大范围(如果10 && degit == 8也会结束因为这里该值为最小值也是直接返回int_min只要超范围就会返回int_max||int_min(digit大于7可以解决int_a=max和int_min的问题)))
//int类型最大值最小值是INT_MAX INT_MIN不是int_max int_min
degit = str[i] - '0';
if(num > INT_MAX / 10 ||(num == INT_MAX / 10 && degit > 7))
// if(num > INT_MAX / 10 ||(num == INT_MAX / 10 && degit > 7))这两个INT_MAX都要整除10
return flag == 1 ? INT_MAX : INT_MIN;
num = num * 10 + degit;
i++;
}
return num * flag;
}
};
题目要求是将一个字符串数组前面的空格全跳过跳过后下一个字符可能是'+'/'-'有符号的话最后将数据取该符号即可,然后我们遍历字符串遇到非数字字符或读取结束就停止读取若是整个字符串都是不符合要求的就返回0若是最后读取转化后的数据超出整型范围即取边界值即可
首先它给的是string类的对象我们先用一个下标i遍历开头遇到空格就++i利用whlie循环
c
int i = 0;
while(str[i] == ' ')
{
i++;
}
```
然后我们默认数据是正数我们定义一个flag为1然后我们继续往后判断下一个字符是否是'+'/'-'是的话就进入条件我们利用条件运算符( str[i] == '-' ? -1 : 1;)
如果是'-'就定义flag为-1不是就为1然后++i继续遍历
```c
int flag = 1;
if(str[i] == '+' || str[i] == '-')
{
i++;
}
这里我们到了读取数字字符转化为数字的时候将数字字符串转化为数字用这个方法
degit = str[i] - '0';
num = num * 10 + degit;
c
while(i < str.size() && (str[i] >= '0' && str[i] <= '9'))
{
//int_max=2147483647 int_min=-2147483648
//如果num > int_max / 10 || (num == int_max / 10 && degit > 7)就说明已经超越int最大范围(如果10 && degit == 8也会结束因为这里该值为最小值也是直接返回int_min只要超范围就会返回int_max||int_min(digit大于7可以解决int_a=max和int_min的问题)))
//int类型最大值最小值是INT_MAX INT_MIN不是int_max int_min
degit = str[i] - '0';
if(num > INT_MAX / 10 ||(num == INT_MAX / 10 && degit > 7))
// if(num > INT_MAX / 10 ||(num == INT_MAX / 10 && degit > 7))这两个INT_MAX都要整除10
return flag == 1 ? INT_MAX : INT_MIN;
num = num * 10 + degit;
i++;
}
我们用num和digit将数字字符串转化为数字
进入while循环的条件是下标不超过有效数字str.size(),而且遇到的字符都是数字字符
i < str.size() && (str[i] >= '0' && str[i] <= '9'
然后我们将取到的字符-'0'就是0~9的数字了
degit = str[i] - '0';
这里我们先不讲这个条件语句 if(num > INT_MAX / 10 ||(num == INT_MAX / 10 && degit > 7))
c
num = num * 10 + degit;
i++;
然后将num * 10 + digit更新数据再将i++继续循环
循环到一定的时候有可能num就超范围了所以我们在将数字字符转化为数字的下一步写一个条件语句
if(num > INT_MAX / 10 ||(num == INT_MAX / 10 && degit > 7))
return flag == 1 ? INT_MAX : INT_MIN;
这里先补充一下INT_MAX和INT_MIN第一个是int的最大值2147483647第二个是int的最小值且必须是用大写英文字符
两种情况
如果num小于INT_MAX / 10
如果num 等于 INT_MAX / 10 且 digit > 10
if(num > INT_MAX / 10 ||(num == INT_MAX / 10 && degit > 7))
这里我们也许会有疑问为啥用INT_MAX / 10判断不用 INT_MIN / 判断因为只要是超出INT_MAX那么要么大于INT_MIN要么等于INT_MIN用INT_MIN返回判断复杂
就说明超出范围返回最值
return flag == 1 ? INT_MAX : INT_MIN;
然后利用条件运算符flag为1就返回INT_MAX,flag为-1就返回INT_MIN
循环过后还没返回就返回num * flag就是我们所要转换的数据
2.字符串相加

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。
你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。
c
class Solution {
public:
string addStrings(string num1, string num2) {
int i = num1.size() - 1; //num1的个位指针
int j = num2.size() - 1;//num2的个位指针
int carry = 0; //进位
string res = ""; //存放结果
while(i >= 0 || j >= 0 || carry > 0)
// while(i > 0 || j > 0 || carry > 0) 0是数组下标肯定要算
{
//取当前的数字,如越界这视为0
int degit1 = i >= 0 ? num1[i] - '0' : 0;
int degit2 = j >= 0 ? num2[j] - '0' : 0;
//计算总和,取进位与个位
int sum = degit1 + degit2 + carry;
carry = sum / 10; //新进位
int current = sum % 10; //当前数字
//数字转换为字符,存入结果
res.push_back(current + '0');
//指针左移
i--;
j--;
}
//最后反转字符
reverse(res.begin(),res.end());
// reverse(res.begin(),res.end())用函数调用时一定要在函数名后加();
return res;
}
};
题目的意思是将两个字符数组变为整数相加在将相加后的数据变为字符数组返回
这里不允许我们将字符串直接转化为整数就是用num = num * 10 + degit循环遍历转化为整数所以我们要一个个从字符数组中每次各取两个字符转化利用个位整数相加进位再将余数一个个放入新的string对象即可
c
int i = num1.size() - 1; //num1的个位指针
int j = num2.size() - 1;//num2的个位指针
int carry = 0; //进位
string res = ""; //存放结果
这里我们用i与j遍历num1 和num2对象定义一个carry当进位数大于1时进入循环继续给sting对象插入数据,res对象就是将num1 与num2两数据变为整数相加后再转化为字符串
c
while(i >= 0 || j >= 0 || carry > 0)
// while(i > 0 || j > 0 || carry > 0) 0是数组下标肯定要算
{
//取当前的数字,如越界这视为0
int degit1 = i >= 0 ? num1[i] - '0' : 0;
int degit2 = j >= 0 ? num2[j] - '0' : 0;
//计算总和,取进位与个位
int sum = degit1 + degit2 + carry;
carry = sum / 10; //新进位
int current = sum % 10; //当前数字
//数字转换为字符,存入结果
res.push_back(current + '0');
//指针左移
i--;
j--;
}
先定义degit1 和 degit2将字符串中的字符转化为整数只要它们对应的下标大于等于0就可以继续转化
c
int degit1 = i >= 0 ? num1[i] - '0' : 0;
int degit2 = j >= 0 ? num2[j] - '0' : 0;
将数字字符转化为数字只要将其 - '0'即可
int sum = degit1 + degit2 + carry;
然后我们定义一个sum将转换的数据以及进位数相加(进位数刚开始为0加法进位数最大为1)
c
carry = sum / 10; //新进位
int current = sum % 10; //当前数字
然后更新进位数carry定义余数current (两数相加不会大于两位数用/ 10 ,% 10就可以得到进位数和余数)
res.push_back(current + '0');
然后将余数 + '0'变为数字字符在用stirng对象push_back()插入数据这里我们一个个插入数据后得到的和字符串是反向的原因是push_bakc会把数据放入最后一个数据后面
最后将--i,--j即可直到循环结束
whlie循环结束将新对象string反转字符串用reverse
reverse(res.begin(),res.end());
这个reverse头文件是#include可以将大多数类型数组数据反转参数是迭代器迭代器范围是左闭右开
最后返回 string类的res对象即可
3.翻转字符串II:区间部分翻转
这个有兴趣可以写一下,这里我就不讲解了
代码展示
c
class Solution {
public:
string reverseStr(string s, int k) {
int prev;//这里指的是字符个数
//字符个数和所在下标位置要看清(这里的下标指的是未反转位置的下标不用prev - 1)
for(prev = 0; prev < s.size(); prev += 2 * k)//这里是+=不是 *=
{
//如果剩余字符剩k个就交换k个其余的就反转剩余的
if(prev + k <= s.size())//只要prev + k >= s.size()说明有k个字符可以交换,剩下的就交换剩下的(这里不是prev + k >= s.size()是prev + k <= s.size())
reverse(s.begin() + prev, s.begin() + prev + k);
else
reverse(s.begin() + prev, s.end());
}
return s;
}
};
4.翻转字符串III:翻转字符串中的单词
代码展示
c
class Solution {
public:
string reverseWords(string s) {
int i =0;
while(1)
{
int d1 = s.find(' ',i);
// int d1 = s.find(' ' || '\0',i);没有这样的写法
//只需要考虑当' '找不到的时候去找空格(一定找得)循环到结束
if(d1 == string::npos)
{
reverse(s.begin() + i,s.end());
break;
}
reverse(s.begin() + i,s.begin() + d1);
i = d1 + 1;
}
return s;
}
};
文章到此就告一段落,希望对你有所帮助,感谢观看!