「代码随想录算法训练营」第八天 | 字符串 part2
151. 反转字符串中的单词
题目链接:https://leetcode.cn/problems/reverse-words-in-a-string/
题目难度:中等
文章讲解:https://programmercarl.com/0151.翻转字符串里的单词.html
视频讲解: https://www.bilibili.com/video/BV1uT41177fX
题目状态:修改后过
个人思路:
讨了个巧,使用istringstream
分割字符串,在将分割出来的单词依次存放到一个vector<string>
里面,最后翻转vector<string>
并通过ostringstream
将结果输出。
实现代码:
class Solution {
public:
string reverseWords(string s) {
istringstream iss(s);
vector<string> words;
string word;
while(iss >> word) {
words.push_back(word);
}
reverse(words.begin(), words.end());
ostringstream oss;
for(int i = 0; i < words.size(); ++i) {
if(i != 0) oss << " ";
oss << words[i];
}
return oss.str();
}
};
55. 右旋字符串(卡码网)
题目链接:https://kamacoder.com/problempage.php?pid=1065
文章讲解:https://programmercarl.com/kama55.右旋字符串.html
题目状态:过
个人思路:
创建一个新string
类型的res
用来存放结果,首先先将字符串后n
个元素加入res
,再将剩下的元素加入到res
。
实现代码:
#include <iostream>
#include <string>
using namespace std;
using std::string;
int main() {
int n;
string s;
cin >> n >> s;
string res;
int sLen = s.size();
for(int i = sLen - n; i < sLen; ++i) {
res += s[i];
}
for(int i = 0; i < sLen - n; ++i) {
res += s[i];
}
cout << res << endl;
return 0;
}
28. 找出字符串中第一个匹配项的下标
题目链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/
题目难度:中等
文章讲解:https://programmercarl.com/0028.实现strStr.html
题目状态:通过
个人思路:
依次遍历,检测从每个元素开始能否进行匹配,知道找到一个匹配项返回其下标,或者没找到匹配项,返回-1
。
代码实现:
class Solution {
public:
int strStr(string haystack, string needle) {
int haySize = haystack.size();
int needleSize = needle.size();
if(needleSize == 0) return 0;
if(haySize < needleSize) return -1;
int hayPoint = 0;
int needlePoint = 0;
while(hayPoint < haySize && needlePoint < needleSize) {
if(haystack[hayPoint] == needle[needlePoint]) {
hayPoint++;
needlePoint++;
if(needlePoint == needleSize) return hayPoint - needlePoint;
}
else {
if(needlePoint > 0) {
hayPoint -= needlePoint;
needlePoint = 0;
}
hayPoint++;
}
}
return -1;
}
};
学习使用 KMP 算法的思路:
要理解next
数组代表着什么,具体思想在这:代码随想录
代码实现:
class Solution {
public:
void getNext(int* next, const string& s) {
int j = 0;
next[0] = 0;
for(int i = 1; i < s.size(); i++) {
while (j > 0 && s[i] != s[j]) {
j = next[j - 1];
}
if (s[i] == s[j]) {
j++;
}
next[i] = j;
}
}
int strStr(string haystack, string needle) {
if (needle.size() == 0) {
return 0;
}
vector<int> next(needle.size());
getNext(&next[0], needle);
int j = 0;
for (int i = 0; i < haystack.size(); i++) {
while(j > 0 && haystack[i] != needle[j]) {
j = next[j - 1];
}
if (haystack[i] == needle[j]) {
j++;
}
if (j == needle.size() ) {
return (i - needle.size() + 1);
}
}
return -1;
}
};
459. 重复的子字符串
题目链接:https://leetcode.cn/problems/repeated-substring-pattern/
题目难度:简单
文章讲解:https://programmercarl.com/0459.重复的子字符串.html
题目状态:想到用暴力但头皮发麻,不想写,看解析
思路:移动匹配
只需要将字符串前后拼接,找中间是否又出现了该字符串,若出现了,则表示该字符串是由其子字符串重复组成的;若没出现,则表示该字符串不是由重复子字符串组成。
代码实现:
class Solution {
public:
bool repeatedSubstringPattern(string s) {
string t = s + s;
t.erase(t.begin());
t.erase(t.end() - 1);
if(t.find(s) != string::npos) return true;
return false;
}
};
学习到了string::npos
。
在 C++ 中,string::npos
是std::string
类中的一个静态成员常量,它表示“未找到”的状态。当进行字符串搜索操作,比如find
、rfind
、find_first_of
等,如果没有找到指定的子串或字符,这些函数就会返回string::npos
。string::npos
的值是std::string
类型的最大可能大小,通常是2^31-1
,即 2147483647。