【C++】string的经典算法题

文章目录

仅仅反转字母

cpp 复制代码
class Solution {
public:
	 bool isLetter(char ch)
	{
     if(ch >= 'a' && ch <= 'z')
         return true;
     if(ch >= 'A' && ch <= 'Z')
         return true;
     return false;
	}
	 string reverseOnlyLetters(string S) {
	     if(S.empty())
	         return S;
	 size_t begin = 0, end = S.size()-1;
	 while(begin < end)
	 {
	     while(begin < end && !isLetter(S[begin]))                
	     	++begin;    
	     while(begin < end && !isLetter(S[end]))
	         --end;
	     swap(S[begin], S[end]);
	     ++begin;
	     --end;
	 }
	 return S;
	 }
};

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

cpp 复制代码
class Solution {
public:
 int firstUniqChar(string s) {

// 统计每个字符出现的次数

 	int count[256] = {0};
    int size = s.size();
    for(int i = 0; i < size; ++i)
         count[s[i]] += 1;
     

 	// 按照字符次序从前往后找只出现一次的字符
 	for(int i = 0; i < size; ++i)
     	if(1 == count[s[i]])
         	return i;

	return -1;

	}
};
cpp 复制代码
class Solution {
public:
	int firstUniqChar(string s) {
		int count[26] = { 0 };
		for (auto ch : s)
		{
			count[ch - 'a']++;
		}
		//遍历第一个字符的count
		for (size_t i = 0; i < s.size(); i++)
		{
			if (count[s[i] - 'a'] == 1)
				return i;
		}
		return -1;
	}
};

字符串里面最后一个单词的长度

rfind是倒着找

operator<<从流中提取字符串

operator>>将字符串插入流

左闭右开的区间

数据个数=左减右

例如:[0,10),个数:10
左闭右闭的区间:

数据个数:左减右加一

例如:[0,9],个数:10

getline只识别换行,不识别空格,还可以自定义字符结束

cpp 复制代码
#include<iostream>
#include<string>
using namespace std;
int main()
{
	string str;
	getline(cin,str);
	size_t pos = str.rfind(' ');
	//有可能没有空格
	if (pos != string::npos)
		cout << str.size() - (pos + 1) << endl;
	else
		cout << str.size() << endl;
	return 0;
}

验证一个字符串是否是回文

cpp 复制代码
class Solution {
public:
 bool isLetterOrNumber(char ch)
{
     return (ch >= '0' && ch <= '9')
     || (ch >= 'a' && ch <= 'z')
         || (ch >= 'A' && ch <= 'Z');
}

 bool isPalindrome(string s) {
     // 先小写字母转换成大写,再进行判断
     for(auto& ch : s)
    {
         if(ch >= 'a' && ch <= 'z')
             ch -= 32;
    }   
 int begin = 0, end = s.size()-1;
 while(begin < end)
{
     while(begin < end && !isLetterOrNumber(s[begin]))                ++begin;
     
     while(begin < end && !isLetterOrNumber(s[end]))
         --end;
     
     if(s[begin] != s[end])
    {
         return false;
    }
     else
    {
         
         ++begin;
         --end;
    }
}
 
 return true;
 }
};

字符串相加

cpp 复制代码
class Solution {
public:
    string addStrings(string num1, string num2) {
        string s3;
        int carry=0;
        int end1=num1.size()-1,end2=num2.size()-1;
        while(end1>=0||end2>=0)
        {
            int val1=end1>=0?num1[end1--]-'0':0;
            int val2=end2>=0?num2[end2--]-'0':0;
            int ret=val1+val2+carry;
            carry=ret/10;
            ret=ret%10;
            s3+=(ret+'0');
        }
        if(carry)
            s3+='1';
        reverse(s3.begin(),s3.end());
        return s3;
    }
};

翻转字符串II:区间部分翻转

cpp 复制代码
class Solution {
public:
    string reverseStr(string s, int k) {
        int n = s.length();
        //当剩余字符在 k 到 2k 之间时,会跳过
        for (int i = 0; i < n; i += 2 * k) {
            reverse(s.begin() + i, s.begin() + min(i + k, n));
        }
        return s;
    }
};

分析:如果 i + k <= n,那么 last = i + k,反转从 i 到 i+k-1 的字符,即前 k 个。

如果 i + k > n,那么 last = n,反转从 i 到 n-1 的字符,即剩余的全部字符。这正好处理了剩余字符少于 k 的情况。

当剩余字符在 k 到 2k 之间时,i + k 可能小于 n,所以反转前 k 个,后面的保持不变。注意,因为 i 每次增加 2k,所以下一个块从 i+2k 开始,而当前块的后 k 个字符(如果有)不会被反转,符合要求。

翻转字符串III:翻转字符串中的单词

cpp 复制代码
class Solution {
public:
    string reverseWords(string s) 
    {
        string ret;
        int length = s.length();
        int i = 0;
        while (i < length) 
        {
        //记录单词开始位置start
            int start = i;
            while (i < length && s[i] != ' ') 
            {
                i++;
            }
            //单词区间[start,i)
            //反向索引
            for (int p = start; p < i; p++) 
            {
                ret.push_back(s[start + i - 1 - p]);
            }
            //插入了单词后插入空格长度
            while (i < length && s[i] == ' ') 
            {
                ret.push_back(' ');
                i++;
            }
        }
        return ret;
    }
};

字符串相乘

cpp 复制代码
class Solution {
public:
    if(num1=="0"||num2=="0")
            return "0";
        //ans初始化为"0"
    string ans="0";
    int m=num1.size(),n=num2.size();
     //先乘数字2的最低位
    for(int i=n-1;i>=0;i--)
    {
         string curr;
         //carry是进位
         int carry=0;
         //除了第一次,其余要给curr也加上n-1-i个'0'
         for(int j=n-1;j>i;j--)
         {
             curr+='0';
         }
         //现在处理当前位(i)
         //将num2[i]转换为数字处理
         int y=num2[i]-'0';
         //数字1从后往前的每一位和数字2的其中一位相乘
         for(int j=m-1;j>=0;j--)
         {
             int x=num1[j]-'0';
             int ret=x*y+carry;
             carry=ret/10;
             ret=ret%10;
             curr+=(ret+'0');
         }
         //继续处理进位
         while(carry)
         {
             curr+=(carry%10+'0');
             carry/=10;
         }
         reverse(curr.begin(),curr.end());
         ans=addStrings(ans,curr);
     }
     return ans;
       
    }
    //字符串相加的代码
    string addStrings(string num1, string num2)
    {
        string s3;
        int carry = 0;
        int end1 = num1.size() - 1, end2 = num2.size() - 1;
        while (end1 >= 0 || end2 >= 0)
        {
            int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
            int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
            int ret = val1 + val2 + carry;
            carry = ret / 10;
            ret = ret % 10;
            s3 += (ret + '0');
        }
        if (carry)
            s3 += '1';
        reverse(s3.begin(), s3.end());
        return s3;
    }
};

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

cpp 复制代码
#include <iostream>
using namespace std;
//找出第一个只出现一次的字符的代码
class Solution {
public:
    int firstUniqChar(string s) 
    {
        int count[26]={0};
        for(auto ch:s)
        {
            count[ch-'a']++;
        }
        for(size_t i=0;i<s.size();i++)
        {
            if(count[s[i]-'a']==1)
                return i;
        }
        return -1;
    }
};
int main()
{
    Solution s;
    string str;
    cin>>str;
    int res=s.firstUniqChar(str);
    if(res!=-1)
        cout<<str[res];
    else
        cout<<res;

    return 0;
}
相关推荐
兑生1 小时前
【灵神题单·贪心】2279. 装满石头的背包的最大数量 | 排序贪心 | Java
java·开发语言
闻缺陷则喜何志丹1 小时前
【动态规划】P8591 『JROI-8』颅脑损伤 2.0|普及+
c++·算法·动态规划·洛谷
阿贵---2 小时前
C++中的工厂模式高级应用
开发语言·c++·算法
倾心琴心2 小时前
【agent辅助pcb routing coding学习】实践7 length matching 算法学习
学习·算法·agent·pcb·routing
y = xⁿ2 小时前
【LeetCodehot100】T114:二叉树展开为链表 T105:从前序与中序遍历构造二叉树
java·算法·链表
灰色小旋风2 小时前
力扣20有效的括号(C++)
c++·算法·leetcode·职场和发展
逆境不可逃2 小时前
LeetCode 热题 100 之 160. 相交链表 206. 反转链表 234. 回文链表 141. 环形链表 142. 环形链表 II
算法·leetcode·链表
weiabc2 小时前
今日C/C++学习笔记20260223
c语言·c++·学习
CoovallyAIHub2 小时前
AAAI 2026 | 华中科大联合清华等提出Anomagic:跨模态提示零样本异常生成+万级AnomVerse数据集(附代码)
深度学习·算法·计算机视觉