有关 string 类的练习(下)

有关 string 类的练习(下)_第1张图片


目录

一、反转字符串 II

二、反转字符串中的单词 III

三、找出字符串中第一个只出现一次的字符

四、字符串相乘

五、把字符串转换成整数



一、反转字符串 II

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。
  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

示例 1:

输入:s = "abcdefg", k = 2

输出:"bacdfeg"

示例 2:

输入:s = "abcd", k = 2

输出:"bacd"

提示:

  • 1 <= s.length <= 10^4
  • s 仅由小写英文组成
  • 1 <= k <= 10^4

代码实现: 

class Solution {
public:
    string reverseStr(string s, int k) {
        size_t pos = 0;  // pos 为每次计数的起点
        while (pos < s.size())
        {
            if (pos + k <= s.size())  // 剩余字符大于等于 k
                reverse(s.begin() + pos, s.begin() + pos + k);
            else  // 剩余字符小于 k
                reverse(s.begin() + pos, s.end());
            pos += 2 * k;
        }
        return s;
    }
};


二、反转字符串中的单词 III

给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

示例 1:

输入:s = "Let's take LeetCode contest"

输出:"s'teL ekat edoCteeL tsetnoc"

示例 2:

输入: s = "God Ding"

输出:"doG gniD"

提示:

  • 1 <= s.length <= 5 * 10^4
  • s 包含可打印的 ASCII 字符。
  • s 不包含任何开头或结尾空格。
  • s 里 至少 有一个词。
  • s 中的所有单词都用一个空格隔开。

代码实现: 

class Solution {
public:
    string reverseWords(string s) {
        size_t pos = 0;  // pos 为每个待反转的单词的起点
        size_t found = s.find(' ', pos);  // found 为每个待反转的单词的终点的下一个位置
        while (found != string::npos)
        {
            reverse(s.begin() + pos, s.begin() + found);
            pos = found + 1;
            found = s.find(' ', pos);
        }
        reverse(s.begin() + pos, s.end());  // 反转最后一个单词
        return s;
    }
};


三、找出字符串中第一个只出现一次的字符

描述:

找出字符串中第一个只出现一次的字符

数据范围:

输入的字符串长度满足 1≤ n ≤1000 

输入描述:

输入一个非空字符串

输出描述:

输出第一个只出现一次的字符,如果不存在输出 -1

示例 1:

输入:asdfasdfo

输出:o

代码实现: 

#include 
using namespace std;
​
int main() 
{
    string s;
    cin >> s;
    // 统计 s 中的每个字符出现的次数
    int count[256] = { 0 };
    for (size_t i = 0; i < s.size(); ++i)
    {
        count[s[i]] += 1;
    }
​
    // 找出字符串中第一个只出现一次的字符
    bool flag = false;  // 假设字符串中不存在只出现一次的字符
    for (size_t i = 0; i < s.size(); ++i)
    {
        if (count[s[i]] == 1)
        {
            flag = true;
            cout << s[i] << endl;
            break;
        }
    }
    if (flag == false)
        cout << -1 <


四、字符串相乘

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

示例 1:

输入: num1 = "2", num2 = "3"

输出: "6"

示例 2:

输入: num1 = "123", num2 = "456"

输出: "56088"

提示:

  • 1 <= num1.length, num2.length <= 200
  • num1 和 num2 只能由数字组成。
  • num1 和 num2 都不包含任何前导零,除了数字0本身。

代码实现: 

class Solution {
public:
    // 字符串相加
    string add(string num1, string num2) {
        string ans;
        int end1 = num1.size() - 1, end2 = num2.size() - 1;
        size_t carry = 0;  // 进位
        while (end1 >= 0 || end2 >= 0 || carry > 0)
        {
            size_t val1 = end1 >= 0 ? (num1[end1--] - '0') : 0;
            size_t val2 = end2 >= 0 ? (num2[end2--] - '0') : 0;
            size_t sum = val1 + val2 + carry;
​
            ans.insert(ans.begin(), sum % 10 + '0');  // 头插
            carry = sum / 10;
        }
        return ans;
    }
​
    // 字符串相乘
    string multiply(string num1, string num2) {
        if (num1 == "0" || num2 == "0")  // 特殊情况
        {
            return string("0");
        }
        
        // 思路:
        // 123 * 456 
        // = 123 * (400 + 50 + 6) 
        // = [(123 * 4) * 100] + [(123 * 5) * 10] + (123 * 6)
        // 所以首先考虑计算出 123 * 6/5/4,然后在其后面添加适当的 '0',最后再将所有的积相加
        string ans;
        int end2 = num2.size() - 1;
        size_t count = 0;  // 需要添加的 '0' 的数量
        while (end2 >= 0)
        {
            size_t val2 = num2[end2--] - '0';
            
            string product;
            size_t carry = 0;
            int end1 = num1.size() - 1;
            while (end1 >= 0 || carry > 0)
            {
                size_t val1 = end1 >= 0 ? (num1[end1--] - '0') : 0;
                size_t sum = val1 * val2 + carry;
​
                product += sum % 10 + '0';
                carry = sum / 10;
            }
            reverse(product.begin(), product.end());
            product.append(count++, '0');
            ans = add(ans, product);
        }
        return ans;
    }
};


五、把字符串转换成整数

描述:

将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为 0 或者字符串不是一个合法的数值则返回 0

数据范围:

字符串长度满足 0≤ n ≤100 
进阶:

空间复杂度 O(1)  ,时间复杂度 O(n) 

注意:

① 字符串中可能出现任意符号,出现除 +/- 以外符号时直接输出 0

② 字符串中可能出现 +/- 且仅可能出现在字符串首位。

输入描述:

输入一个字符串,包括数字字母符号,可以为空

返回值描述:

如果是合法的数值表达则返回该数字,否则返回0

示例 1:

输入:"+2147483647"

返回值:2147483647

示例 2:

输入:"1a33"

返回值:0

代码实现:

class Solution {
public:
    int StrToInt(string str) {
        // 如果是空字符串,则直接返回 0
        size_t sz = str.size();
        if (sz == 0)
            return 0;
        
        // 确定正负号
        size_t i = 0; 
        int sign = 1;  // 默认为正号
        if (str[0] == '+')
        {
            ++i;
        }
        else if (str[0] == '-')
        {
            ++i;
            sign = -1;
        }
​
        // 确定绝对值
        int res = 0;
        while (i < sz)
        {
            if (str[i] >= '0' && str[i] <= '9')
                res = res * 10 + (str[i] - '0');
            else
                return 0;
            ++i;
        }
        return sign * res;
    }
};

你可能感兴趣的:(C++,leetcode,算法,c++)