【C++修行之道】string类练习题

avatar
作者
筋斗云
阅读量:0

目录

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

125. 验证回文串 

917. 仅仅反转字母

415. 字符串相加(重点)

541. 反转字符串 II


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

字符串中的第一个唯一字符 - 力扣(LeetCode)

给定一个字符串 s ,找到它的第一个不重复的字符,并返回它的索引 。

如果不存在,则返回 -1 。

示例 1:

输入: s = "leetcode" 输出: 0 

示例 2:

输入: s = "loveleetcode" 输出: 2 

示例 3:

输入: s = "aabb" 输出: -1 

提示:

  • 1 <= s.length <= 105
  • s 只包含小写字母

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;     } };

 

  • ch - 'a' 计算字符 ch 相对于字符 'a' 的位置索引。例如,字符 'a' 的位置为 0,字符 'b' 的位置为 1,依此类推。
  • count[ch - 'a']++ 表示将 count 数组中相应位置的值加 1,从而记录字符 ch 出现的次数。
  • count[s[i] - 'a'] == 1 检查字符 s[i] 是否在字符串 s 中只出现了一次。如果是,则返回该字符的索引 i

125. 验证回文串 

验证回文串  - 力扣(LeetCode)

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。

示例 1:

输入: s = "A man, a plan, a canal: Panama" 输出:true 解释:"amanaplanacanalpanama" 是回文串。 

示例 2:

输入:s = "race a car" 输出:false 解释:"raceacar" 不是回文串。 

示例 3:

输入:s = " " 输出:true 解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。 由于空字符串正着反着读都一样,所以是回文串。 

提示:

  • 1 <= s.length <= 2 * 105
  • s 仅由可打印的 ASCII 字符组成
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; 	} }; 

 

  • while (begin < end) 循环确保指针交替向中间移动,直到它们相遇或交错。
  • while (begin < end && !isLetterOrNumber(s[begin])) ++begin; 跳过非字母数字字符,移动 begin 指针向右。
  • while (begin < end && !isLetterOrNumber(s[end])) --end; 跳过非字母数字字符,移动 end 指针向左。
  • 如果 s[begin] != s[end],即对应字符不相等,返回 false,表示字符串不是回文串。
  • 如果对应字符相等,继续移动指针 begin 向右,end 向左。

917. 仅仅反转字母

仅仅反转字母 - 力扣(LeetCode)

给你一个字符串 s ,根据下述规则反转字符串:

  • 所有非英文字母保留在原有位置。
  • 所有英文字母(小写或大写)位置反转。

返回反转后的 s 。

示例 1:

输入:s = "ab-cd" 输出:"dc-ba" 

示例 2:

输入:s = "a-bC-dEf-ghIj" 输出:"j-Ih-gfE-dCba" 

示例 3:

输入:s = "Test1ng-Leet=code-Q!" 输出:"Qedo1ct-eeLg=ntse-T!" 

提示:

  • 1 <= s.length <= 100
  • s 仅由 ASCII 值在范围 [33, 122] 的字符组成
  • s 不含 '\"' 或 '\\'

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; 	} };
  • reverseOnlyLetters 函数接收一个字符串 S,并返回一个仅反转字母部分的字符串。
  • 首先检查字符串是否为空,如果是,则直接返回原字符串。
  • 使用 while (begin < end) 循环确保指针交替向中间移动,直到它们相遇或交错。
  • while (begin < end && !isLetter(S[begin])) ++begin; 跳过非字母字符,移动 begin 指针向右。
  • while (begin < end && !isLetter(S[end])) --end; 跳过非字母字符,移动 end 指针向左。
  • swap(S[begin], S[end]); 交换 beginend 指针指向的字母。
  • 继续移动指针 begin 向右,end 向左。
  • beginend 指针相遇或交错时,返回反转后的字符串 S

415. 字符串相加(重点)

字符串相加 - 力扣(LeetCode)

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。

你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。

示例 1:

输入:num1 = "11", num2 = "123" 输出:"134" 

示例 2:

输入:num1 = "456", num2 = "77" 输出:"533" 

示例 3:

输入:num1 = "0", num2 = "0" 输出:"0" 

提示:

  • 1 <= num1.length, num2.length <= 104
  • num1 和num2 都只包含数字 0-9
  • num1 和num2 都不包含任何前导零
class Solution { public:     string addStrings(string num1, string num2) {         int end1 = num1.size() - 1;         int end2 = num2.size() - 1;                  string str;         int next = 0;// 进位         while(end1 >= 0 || end2 >= 0)         {             int x1 = end1 >= 0 ? num1[end1--] - '0' : 0;             int x2 = end2 >= 0 ? num2[end2--] - '0' : 0;             int x = x1 + x2 + next;              // 处理进位             next = x / 10;             x = x % 10;                          // 头插             // str.insert(0, 1, '0'+x);             str.insert(str.begin(), '0'+x);         }         // 还有一个进位没处理         if(next == 1)         {             str.insert(str.begin(), '1');         }           return str;     } };

 

  • while (end1 >= 0 || end2 >= 0) 循环确保我们遍历两个字符串,直到两个字符串都处理完毕。
  • x1x2 分别是当前字符对应的数字,如果对应的字符已经处理完毕,则赋值为 0
  • x 是当前位相加的结果,包括进位 next
  • next = x / 10 计算新的进位值。
  • x = x % 10 计算当前位的实际数字。
  • str.insert(str.begin(), '0' + x) 将当前位的结果插入到结果字符串的头部。
  • end1--end2-- 将指针分别向前移动一位。
  • 如果循环结束后还有进位,则在结果字符串的头部插入 '1'
class Solution { public:     string addStrings(string num1, string num2) {         int end1 = num1.size() - 1;         int end2 = num2.size() - 1;                  string str;         int next = 0;// 进位         while(end1 >= 0 || end2 >= 0)         {             int x1 = end1 >= 0 ? num1[end1--] - '0' : 0;             int x2 = end2 >= 0 ? num2[end2--] - '0' : 0;             int x = x1 + x2 + next;              // 处理进位             next = x / 10;             x = x % 10;                          // 尾插             str += ('0' + x);         }         // 还有一个进位没处理         if(next == 1)         {             str += '1';         }                    reverse(str.begin(), str.end());          return str;     }

541. 反转字符串 II

541. 反转字符串 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 <= 10000
s 仅由小写英文组成
1 <= k <= 10000

class Solution { public:     string reverseStr(string s, int k) {         int n = s.length();         for(int i = 0; i < n; i += 2 * k)             reverse(s.begin() + i, s.begin() + min(i + k, n));         return s;     } };

今天就先到这了!!!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!

你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!