【C/C++】涉及string类的经典OJ编程题
- [一. 把字符串转化成整数(atoi)](#一. 把字符串转化成整数(atoi))
- 二.字符串相加
- 三.反转字符串
- 四.字符串中的第一个唯一字符
一. 把字符串转化成整数(atoi)
点这里:本题LeetCode链接
该题源代码声明:
作者:Krahets
链接:https://leetcode.cn/problems/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof/solutions/201301/mian-shi-ti-67-ba-zi-fu-chuan-zhuan-huan-cheng-z-4/
来源:力扣(LeetCode)
解法一:(不用long)
首先来看该题要用到的所以的变量的定义和初始化
cpp
int res = 0, bndry = INT_MAX / 10;
int i = 0, sign = 1, length = str.size();
第一步:
- 判断字符串是否为空字符串
- 读取字符串并丢弃无用的前导空歌并且 判断该字符串是否为全为空格的字符串。通过对下标 i 的控制来实现。
代码实现:
cpp
if(length == 0) return 0;
while(str[i] == ' ')
if(++i == length) return 0;//若不是空字符串,i走到符号位
第二步:
判断字符的正负
代码实现:
cpp
if(str[i] == '-') sign = -1;
if(str[i] == '-' || str[i] == '+') i++;//让i走到符号位后的第一个数字字符
第三步:(关键)
(最大最小数值)边界的处理
一旦遇到非数字字符直接返回0;此时的 j 为第一个数字字符。
变量的定义和初始化:int res = 0, bndry = INT_MAX / 10; (INT_MAX )等于2147483647,注意这里的个位数字7;注意初始化的bndry = 214748364;
再看这句代码:res = res * 10 + (str[j] - '0');通过这句代码可以将字符数字转发为对应大小的整形数值。现在就可以理解 if 语句里面的条件判断:
- 当res一旦大于bndry = 214748364;往下走完语句res = res * 10 + (str[j] - '0');时,res就会越界;
- 当(res == bndry && str[j] > '7'),此时下标 j 指向的字符大于7时,往下走完语句res = res * 10 + (str[j] - '0');时,res也会越界;
代码实现:
cpp
for(int j = i; j < length; j++) {
if(str[j] < '0' || str[j] > '9') break;
if(res > bndry || res == bndry && str[j] > '7')
return sign == 1 ? INT_MAX : INT_MIN;
res = res * 10 + (str[j] - '0');
}
完整代码:
cpp
class Solution {
public:
int myAtoi(string str) {
int res = 0, bndry = INT_MAX / 10;
int i = 0, sign = 1, length = str.size();
if(length == 0) return 0;
while(str[i] == ' ')
if(++i == length) return 0;
if(str[i] == '-') sign = -1;
if(str[i] == '-' || str[i] == '+') i++;
for(int j = i; j < length; j++) {
if(str[j] < '0' || str[j] > '9') break;
if(res > bndry || res == bndry && str[j] > '7')
return sign == 1 ? INT_MAX : INT_MIN;
res = res * 10 + (str[j] - '0');
}
return sign * res;
}
};
解法二:(用long)
用long的前提:(操作系统)环境能存储 64 位大小的有符号整数
cpp
class Solution {
public:
int myAtoi(string str) {
long int res = 0, bndry = INT_MAX / 10;
int i = 0, sign = 1, length = str.size();
if(length == 0) return 0;
while(str[i] == ' ')
{
i++;
if(i == length)
return 0;
}
if(str[i] == '-')
sign = -1;
if(str[i] == '-' || str[i] == '+') i++;
for(int j = i; j < length; j++)
{
if(str[j] > '9' || str[j] < '0')
return sign * res;
res = res * 10 + str[j] - '0';//如果不用long,这句代码可能会造成res溢出int max;无法通过部分测试
if(res > INT_MAX)
return sign == 1 ? INT_MAX : INT_MIN;
}
return sign * res;
}
};
二.字符串相加
代码实现(含注释):
cpp
class Solution {
public:
string addStrings(string num1, string num2) {
string tmp;
int count = 0;//用于进位
int gap1 = num1.end() - num1.begin() - 1;//字符串1尾下标
int gap2 = num2.end() - num2.begin() - 1;//字符串2尾下标
while(gap1 >= 0 || gap2 >= 0)
{
int x = gap1 >= 0 ? num1[gap1] - '0' : 0;//将数字字符串转换为对应整形数字
int y = gap2 >= 0 ? num2[gap2] - '0' : 0;//当下标走到负数将其转换为0
int sum = x + y + count;//对应两两相加,在加上进位数值
count = sum / 10;//得进位数值
sum %= 10;//得个位数值
tmp += (sum + '0');//依次拼接(逆序)
gap1--;
gap2--;
}
if(count == 1)//解决一个字符串为"0",另一个为"9",还有最高位未进位的情况
{
tmp += '1';
}
reverse(tmp.begin(), tmp.end());//颠倒为顺序
return tmp;
}
};
三.反转字符串
代码实现:
cpp
class Solution {
public:
void reverseString(vector<char>& s) {
int begin = 0;
int end = s.size() - 1;
while(begin < end)
{
swap(s[begin], s[end]);
begin++;
end--;
}
}
};
四.字符串中的第一个唯一字符
解法一:
原理:两两比较字符串中的所以字符,通过计数来判断是否有相同字符
cpp
class Solution {
public:
int firstUniqChar(string s) {
for(int i = 0; i < s.size(); i++)
{
int count = 0;
int j = 0;
for(; j < s.size(); j++)
{
if(s[i] == s[j] && i != j)
break;
if(s[i] != s[j])
count++;
}
if(count == s.size() - 1)
return i;
}
return -1;
}
};
解法二:(推荐)
原理:如果从左往右找,和从右往左找同一个字符,返回它们的下标相同,则在给出的字符串中该字符有且只有这一个
s.find(s[i]) : 返回字符串s中从左向右查找s[i]第一次出现的位置;
s.rfind(s[i]) : 返回字符串s中从右向左查找s[i]第一次出现的位置;
解法二声明:
作者:WTY2002
来源:力扣(LeetCode)
cpp
class Solution {
public:
int firstUniqChar(string s) {
for(int i = 0; i < s.size() ; i++){
if(s.find(s[i]) == s.rfind(s[i])){
return i;
}
}
return -1;
}
};