【关于string的练习题】


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

一、题目描述

在这里插入图片描述
题目链接


二、题目代码

提示:每出现一次,就在相对映射数组中计数+1

#include<iostream>
#include<string>
#include<vector>

using namespace std;
int main(){
    string s;
    cin >> s;
    int Array[26] = {0};
    int flag = 0;
    for(int i = 0; i < s.size(); i++)
    {
        Array[s[i]-'a']++;
    }
    for(int j=0;j<s.size();j++)
    {
        if( Array[s[j]-'a'] == 1)
        {
            printf("%c",s[j]);
            flag = 1;
            break;
        }
    }
    if(flag == 0)
    printf("%d",-1);
    
}
/*

*思路:

* 1. 对字符串的每一个字符进行hash映射

* 2. 按顺序检测每一个字符是否只出现一次

*/

#include<iostream>

#include<string>

#include<list>

using namespace std;



int Hash(int key)

{

  return key - 'a';

}

int FirstTimeChar(string &str)

{

  int hashtable[26] = {0};

  //对字符串的每一个字符进行hash映射

  for(int i=0; i<str.size(); ++i)

  {

    int index = Hash(str[i]);

    hashtable[index]++;

  }

  //按顺序检测每一个字符是否只出现一次

  for(int i=0; i<str.size(); ++i)

  {

    int index = Hash(str[i]);

    if(hashtable[index] == 1)

      return str[i];

  }

  return -1;

}



int main()

{

  string str;

  while(getline(cin, str))

  {

    char res = FirstTimeChar(str);

    if(res == -1)

      cout<<-1<<endl;

    else

      cout<<res<<endl;

  }

  return 0;

}

【387. 字符串中的第一个唯一字符】

一、题目描述

在这里插入图片描述

题目链接

二、题目代码

class Solution {
public:
    int firstUniqChar(string s) {
    int Array[26] = {0};
    for(int i = 0; i < s.size(); i++)
    {
        Array[s[i]-'a']++;
    }
    for(int j=0;j<s.size();j++)
    {
        if( Array[s[j]-'a'] == 1)
        {
            return j;
        }
    }
    return -1;

    }
};
/*

*思路:

* 1. 分别对字符串进行正序查询和反序查询

* 2. 如果所查询的字符下标相等,说明此字符只出现了一次

*/

class Solution {

public:

  int firstUniqChar(string s) 

  {

    for(int i=0; i<s.size(); ++i)

    {

      int index = s.find(s[i]);

      int reverse_index = s.rfind(s[i]);  

      if(index == reverse_index)

        return i;

    }

    return -1;

  }

};

【557. 反转字符串中的单词 III】

一、题目描述

在这里插入图片描述
题目链接


二、题目代码

class Solution {
public:
    string reverseWords(string s) {
      int left = 0;
      int right = 0;
      while(right < s.size())
      {
         while(right < s.size() && s[right] != ' ')
         {
             right++;
         }
         right-=1;
         int tright = right;
         while(left < right)
         {
             swap(s[left],s[right]);
             left++;
             right--;
         }
         left = tright+2;
         right = left;
      }
      return s;
    }
};
/*

*思路:

* 1. 通过查找空格,分割单词

* 2. 针对分割的单词进行翻转

*/

class Solution {

public:

  void Reverse(string &s, int start, int end)

  {

    char tmp;

    while(start < end)

    {

      tmp = s[start];

      s[start] = s[end];

      s[end] = tmp;



      start++;

      end--;

    }

  }



  string reverseWords(string s) 

  {

    size_t start = 0;

    size_t end = 0;

    while(start < s.size())

    {

      end = s.find(' ', start);

      if(end == string::npos)

      {

        end = s.size();

        break;

      }

      Reverse(s, start, end-1);

      start = end+1;

    }

    Reverse(s, start, end-1);

    return s;

  }

};

【541. 反转字符串 II】

一、题目描述

在这里插入图片描述
题目链接


二、题目代码

class Solution {
public:
    void reverse(string& s, int start, int end) {
        for (int i = start, j = end; i < j; i++, j--) {
            swap(s[i], s[j]);
        }
    }
    string reverseStr(string s, int k) {
        for (int i = 0; i < s.size(); i += (2 * k)) {
            // 1. 每隔 2k 个字符的前 k 个字符进行反转
            // 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
            if (i + k <= s.size()) {
                reverse(s, i, i + k - 1);
                continue;
            }
            // 3. 剩余字符少于 k 个,则将剩余字符全部反转。
            reverse(s, i, s.size() - 1);
        }
        return s;
    }
};
class Solution {

public:

  //翻转start到end区间的字符串

  void Reverse(string &s, int start, int end)

  {

    char tmp;

    end--;

    while(start < end)

    {

      tmp = s[start];

      s[start] = s[end];

      s[end] = tmp;



      start++;

      end--;

    }

  }



  string reverseStr(string s, int k) 

  {

    int len = s.size();

    for(int i=0; i<len; i+=2*k)

    {

      if(i+k < len)

        Reverse(s, i, i+k);

      else

        Reverse(s, i, len);

    }

    return s;

  }

};

【125. 验证回文串】

一、题目描述

在这里插入图片描述
题目链接


二、题目代码

/*

*思路:

* 1. 忽略大小写,只考虑字母

* 2. 通过首尾比较的方式,判断其是否为回文

*/

class Solution {

public:

  bool isDigtalOrWord(char ch)

  {

    if( (ch>='0' && ch<='9')

    || (ch>='A' && ch<='Z')

    || (ch>='a' && ch<='z'))

      return true;

    return false;

  }

  bool isPalindrome(string s) 

  {

    if(s.empty())

      return true;

     

    for(int i=0; i<s.size(); ++i)

    {

      s[i] = tolower(s[i]); //忽略大小写      

    }



    int left = 0;    

    int right = s.size()-1;

    while(left < right)

    {

      //找到左边第一个未比较的字母

      while(left<right && !isDigtalOrWord(s[left]))

        left++;

      //找到右边第一个未比较的字母

      while(left<right && !isDigtalOrWord(s[right]))

        right--;

      //左右两边字母若不相等,则不是回文

      if(s[left] != s[right])

        return false;

      left++;

      right--;

    }

    return true;

  }

};

【HJ1 字符串最后一个单词的长度】

一、题目描述

在这里插入图片描述
题目链接


二、题目代码

#include <iostream>
#include <string>
using namespace std;

int main(){
    string s;
    getline(cin , s);
    size_t pos = s.rfind(' ');
    if(pos == string::npos)
    {
        cout<<s.size();
    }
    else
    {
        cout<<s.size()-pos-1;
    }
    
}
/*

*思路:

* 1. 反向查询最后一个空格所在位置,从而确定最后一个单词

* 2. 最后一个单词长度等于整个字符串长度减去最后一个空格之前的长度

*/

#include<iostream>

#include<string>

using namespace std;



int Calc_Word_Length(string &str)

{

  if(str.empty())

    return 0;

  int index = str.rfind(' ');

  if(index == string::npos)

    return str.size();

  return str.size()-index-1;

}



int main()

{

  string str;

  getline(cin, str);

  int len = Calc_Word_Length(str);

  cout<<len;

  return 0;

}

【344. 反转字符串】

一、题目描述

在这里插入图片描述
题目链接


二、题目代码

class Solution {
public:
    void reverseString(vector<char>& s) {
        int left = 0;
        int right = s.size()-1;
        while(left < right)
        {
            swap(s[left],s[right]);
            left++;
            right--;
        }

    }
};
/*

*思路:

* 1. 收尾交换,进行翻转

*/

class Solution {

public:

  void reverseString(vector<char>& s) 

  {

    if(s.empty())

      return;

    int start = 0;

    int end = s.size()-1;

    while(start < end)

    {

      swap(s[start], s[end]);

      start++;

      end--;

    }

  }

};

【415. 字符串相加】

一、题目描述

在这里插入图片描述
题目链接


二、题目代码

class Solution {
public:
    string addStrings(string num1, string num2) {
        int end1 = num1.size() - 1, end2 = num2.size() - 1;
        int next = 0;//进位

        string retStr;
        while(end1 >= 0 || end2 >= 0)
        {
            int x1 = 0;
            if(end1 >= 0)
            {
                x1 = num1[end1] - '0';
                --end1;
            }

            int x2 = 0;
            if(end2 >= 0)
            {
                x2 = num2[end2] - '0';
                --end2;
            }

            int retval = x1 + x2 + next;
            if(retval > 9)
            {
                next = 1;
                retval -= 10;
            }
            else
            {
                next = 0;
            } 
            //头插
            //retStr.insert(retStr.begin(),retval+'0');
            retStr += retval + '0';
        }
        if(next == 1)
        {
            //retStr.insert(retStr.begin(),'1');
            retStr += '1';
        }
        reverse(retStr.begin(), retStr.end());
        return retStr;
    }
};
/*

*思路:

* 1. 先逆置数据

* 2. 数据对应为进行相加

* 3. 最后若有进位,还需尾插数据,最后逆置恢复数据

*/

class Solution 

{

public:

  //完成每一项的相加,进位可能会被修改,sign以引用传递

  int AddItem(int a, int b, int &sign)

  {

    int sum = a + b + sign;

    if(sum >= 10)

    {

      sum -= 10;

      sign = 1;

    }

    else

      sign = 0;

    return sum;

  }

  string addStrings(string num1, string num2) 

  {

    //先逆置数据,方便相加时有进位直接在数据的尾部插入即可,这样不会引起数据的移动

    reverse(num1.begin(), num1.end());

    reverse(num2.begin(), num2.end());

    int i, j, sign;

    i = j = sign = 0;

    int sum = 0;

    string res;

    while(i<num1.size() && j<num2.size())

    {

      sum = AddItem(num1[i]-'0', num2[j]-'0', sign);

      res.push_back(sum+'0');

      i++;

      j++;

    }



    while(i < num1.size())

    {

      sum = AddItem(num1[i]-'0', 0, sign);

      res.push_back(sum+'0');

      i++;

    }

    while(j < num2.size())

    {

      sum = AddItem(0, num2[j]-'0', sign);

      res.push_back(sum+'0');

      j++;

    }



    if(sign > 0)

      res.push_back(sign+'0');

    reverse(res.begin(), res.end());

    return res;

  }

};

【把字符串转换成整数】

一、题目描述

在这里插入图片描述
题目链接


二、题目代码

class Solution {
public:
    int StrToInt(string str) {
        if(str.empty())
            return 0;
        int flag = 1;
        if(str[0] == '-')
        {
            flag = -1;
            str[0] = '0';
        }
        else if(str[0] == '+')
        {
            flag = 1;
            str[0] = '0';
        }
        int sum = 0;
        for(int i = 0; i < str.size(); ++i)
        {
            if(str[i] < '0' || str[i] > '9')
            {
                sum = 0;
                break;
            }
            sum = sum * 10 + str[i] - '0';
        }
        return flag * sum;
        
    }
};
/*

*思路:

* 1. 要考虑正负数

* 2. 要考虑数据是否溢出

*/

class Solution {

public:

   

  int StrToInt(string str) 

  { 

    int len=str.size();

    int flag=1;  

    if(len==0)    

      return 0;    

    const char *cstr = str.c_str();

    if(cstr == NULL)

      return 0;

    int i=0;      

    if(cstr[i]=='+')

    {      

      i++;     

      flag=1;//如果str[i]为'+',str[i]顺序后移,并令标志flag为1,表示为正数   

    }     

    else if(cstr[i]=='-')

    {    

      i++;    

      flag=-1;//如果str[i]为'-',str[i]顺序后移,并令标志flag为-1,表示为负数   

    }    

    long long num=0;    

    while(cstr[i]!='\0')

    {       

      if(cstr[i]>='0' && cstr[i]<='9')

      {

        //每遍历一个在0-9间的字符,就将其输入到num中       

        num=num*10+(cstr[i]-'0');//下一次输入到num中时要加上上一次*10的结果,即上一次的数左移一位(十进制下) 

         

        //如果数据溢出,则返回0

        if((flag>0 && num>0x7fffffff) || (flag<0 && num>0x80000000))

          return 0;

        i++;      

      }      

      else

      {       

        return 0;   

      }     

    }     

    if(flag < 0)

      num = num * -1;

    return (int)num;  

  }

};

【43. 字符串相乘】

一、题目描述

在这里插入图片描述
题目链接


二、题目代码

class Solution {
public:
    string multiply(string num1, string num2) {
        int l1 = num1.size();
        int l2 = num2.size();
        string res(l1+l2, '0');
        for(int i = l1-1; i>=0; i--){
            for(int j = l2-1; j>=0; j--){
                int tmp = (res[i+j+1] - '0') + (num1[i] - '0')*(num2[j] - '0');
                res[i+j+1] = tmp%10 +'0';
                res[i+j] += tmp/10;
            }
        }
        for(int i = 0; i < l1+l2; i++){
            if(res[i]!='0') return res.substr(i);
        }
        return "0";

    }
};
/*

*思路:

* 1. 下翻转数据

* 2. 按位相乘

* 3. 将乘得的结果进行错位相加,模拟乘法的笔算过程

*/

class Solution 

{

public:



  void MulItem(string &tmp, string &num1, char a)

  {

    int i = 0, sign=0;

    int mul = 0;

    while(i < num1.size())

    {

      mul = (num1[i]-'0') * (a-'0') + sign;

      if(mul >= 10)

      {

        sign = mul / 10;

        mul %= 10;

      }

      else

        sign = 0;

      tmp.push_back(mul+'0');

      i++;

    }    

    if(sign > 0)

      tmp.push_back(sign+'0'); 

  }   

  //对应为相加,sign进位采用引用传递

  int AddItem(int a, int b, int &sign)

  {

    int add = a+b+sign;

    if(add >= 10)

    {

      sign = 1;

      add -= 10;

    }

    else

      sign = 0;

    return add;

  }

  //错位相加

  void MoveAdd(string &result, string &tmp, int k)

  {

    int i, j;

    i = k;

    j = 0;

    int sign = 0;

    while(i<result.size() &&j<tmp.size())

    {

      result[i] = AddItem(result[i]-'0', tmp[j]-'0', sign) + '0';

      i++;

      j++;

    }

    while(i<result.size() && sign)

    {

      result[i] = AddItem(result[i]-'0', 0, sign)+'0';

      i++;

    }

    while(j < tmp.size())

    {

      int v = AddItem(0, tmp[j]-'0', sign);

      result.push_back(v+'0');

      j++;

    }

    if(sign)

      result.push_back(sign+'0');

  }



  string multiply(string num1, string num2) 

  {

   //先翻转数据,方便进位处理

     reverse(num1.begin(), num1.end());

     reverse(num2.begin(), num2.end());



     string tmp, result;

     for(int i=0; i<num2.size(); ++i)

     {

      //使用num2的每一个数据乘以num1

       MulItem(tmp, num1, num2[i]);

       //将乘得的结果进行错位相加

       MoveAdd(result, tmp, i);

       tmp.clear();

     }    



     while(result.size()!=1 && result.back()=='0')

      result.pop_back();



//翻转数据,恢复数据

     reverse(result.begin(), result.end());

     return result;

  }

};

以上是本篇文章的全部内容,如果文章有错误或者有看不懂的地方,多和喵博主交流。互相学习互相进步。如果这篇文章对你有帮助,可以给喵博主一个关注,你们的支持是我最大的动力。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值