Leetcode4_【字符串】

 比如 

string str="";//ATTENTION: 不可''

string str("");//ATTENTION: 不可''

2、索引

 可以像 C 语言中一样,将 string 对象当做一个数组,然后使用数组下标的方式来访问字符串中的元素;也可以使用 string.at(index) 的方式来访问元素(索引号从 0 开始):

cout << str[1] << endl;      // 使用数组下标的方式访问 string 字符串的元素
cout << str.at(1) << endl;     // 使用 at 索引访问 string 字符串的元素
3、函数( 参考

(1)长度:在 C++ 中,可以使用 string.size() 函数或 string.length() 函数来获得 string 对象的长度

(2)复制:在 C 语言中,使用 strcpy、strncpy 函数来实现字符串的复制。在 C++ 中则方便很多,可以直接将一个 string 对象赋值给另一个 string 对象:str2 = str1;

(3)拼接:在 C 语言中,使用 strcat、strncat 函数来进行字符串拼接操作。在 C++ 中也有多种方法来实现字符串拼接和附加操作:

方法1:string str3 = str1 + str2;

方法2:str1.append(str2);

方法3:str.push_back('a');//只能是一个字符

(4)比较:在 C 语言中,使用 strcmp、strncmp 函数来进行字符串的比较。在 C++ 中,由于将 string 对象声明为了简单变量,故而对字符串的比较操作十分简单了,直接使用关系运算符(==、!=、<、<=、>、>=)即可。或者 string.compare() 方法。

(5)子字符串 使用 str = string.substr(起始位置,子字符串长度) 函数来获取子串

(6)查找string.find() 

//从字符串的 pos 位置开始(若不指定 pos 的值,则默认从索引 0 处开始),查找子字符串 str。如果找到,则返回该子字符串首次出现时其首字符的索引;否则,返回 string::npos:
size_type find (const string& str, size_type pos = 0) const;

//从字符串的 pos 位置开始(若不指定 pos 的值,则默认从索引 0 处开始),查找子字符串 s。如果找到,则返回该子字符串首次出现时其首字符的索引;否则,返回 string::npos:  
size_type find (const char *s, size_type pos = 0) const;

//从字符串的 pos 位置开始(若不指定 pos 的值,则默认从索引 0 处开始),查找 s 的前 n 个字符组成的子字符串。如果找到,则返回该子字符串首次出现时其首字符的索引;否则,返回 string::npos:
size_type find (const char *s, size_type pos, size_type n);

//从字符串的 pos 位置开始(若不指定 pos 的值,则默认从索引 0 处开始),查找字符 ch 。如果找到,则返回该字符首次出现的位置;否则,返回 string::npos:
size_type find (char ch, size_type pos = 0) const;

(7)插入string.insert()

// 在位置 pos 处插入字符串 str
string&insert(size_t pos,const string&str);   

// 在位置 pos 处插入字符串 str 的从位置 subpos 处开始的 sublen 个字符
string&insert(size_t pos,const string&str,size_t subpos,size_t sublen); 

// 在位置 pos 处插入字符串 s
string&insert(size_t pos,const char * s);    

// 在位置 pos 处插入字符串 s 的前 n 个字符
string&insert(size_t pos,const char * s,size_t n); 

// 在位置 pos 处插入 n 个字符 c
string&insert(size_t pos,size_t n,char c);   

// 在 p 处插入 n 个字符 c,并返回插入后迭代器的位置
iterator insert (const_iterator p, size_t n, char c); 

 // 在 p 处插入字符 c,并返回插入后迭代器的位置
iterator insert (const_iterator p, char c);      

(8)删除string.erase

 // 删除从 pos 处开始的 n 个字符
string& erase (size_t pos = 0, size_t len = npos);  

// 删除 p 处的一个字符,并返回删除后迭代器的位置
iterator erase (const_iterator p);    

        
// 删除从 first 到 last 之间的字符,并返回删除后迭代器的位置
iterator erase (const_iterator first, const_iterator last); 

(9)交换:str1.swap(str2);

(10)判断是否为空:str.empty();

(11)反转:reverse (res.begin(), res.end());

 344.反转字符串 

建议: 本题是字符串基础题目,就是考察 reverse 函数的实现,同时也明确一下 平时刷题什么时候用 库函数,什么时候 不用库函数。

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

文章讲解/视频讲解:代码随想录

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

 541. 反转字符串II

建议:本题又进阶了,自己先去独立做一做,然后在看题解,对代码技巧会有很深的体会。 

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

文章讲解/视频讲解:代码随想录

class Solution {
public:
    string reverseStr(string s, int k) {
        for(int i = 0; i < s.size(); i = i + 2 * k){
            if(i+k<s.size()){//如果剩余字符小于 2k 但大于或等于 k 个
                reverse(s.begin()+i, s.begin()+i+k);//则反转前 k 个字符,其余字符保持原样
            }else{//如果剩余字符少于 k 个
                reverse(s.begin()+i, s.end());//则将剩余字符全部反转
            }
        }
        return s;
    }
};

 卡码网:54.替换数字 

建议:对于线性数据结构,填充或者删除,后序处理会高效的多。好好体会一下。

题目链接:题目页面

文章讲解:代码随想录

链接字符串不必执着用strcat(s1,s2),直接用+就行了呀!
#include <string>
#include <iostream>

using namespace std;

int main(){
    string str;
    cin >> str ;
    string strOut;
    for(char c : str){
        if(c >= 'a' &&  c <='z'){
            strOut += c;
        }
        if(c >='0' && c <= '9'){
            strOut += "number";
        }
    }
    cout << strOut << endl;
    return 0;
}
#include<iostream>
using namespace std;
int main() {
    string s;
    while (cin >> s) {//ATTENTION
    int count =  0;
    for(char c : s){
        if(c>='0'&&c<='9'){
            count ++;
        }
    }
    int soldsize = s.size();
    s.resize(s.size() + count * 5);
    int snewsize = s.size();
    for(int fast = soldsize-1, slow = snewsize-1; fast < slow;fast--,slow--){
        if(s[fast]>='0'&&s[fast]<='9'){
            s[slow]='r';
            s[slow-1]='e';
            s[slow-2]='b';
            s[slow-3]='m';
            s[slow-4]='u';
            s[slow-5]='n';
            slow = slow - 5;
        }else{
            s[slow]=s[fast];
        }
    }
    std::cout << s << std::endl;
    } 
}

上面这种做法不用申请新的字符串数组。很多数组填充类的问题,其做法都是先预先给数组扩容带填充后的大小,然后在从后向前进行操作

 151.反转字符串里的单词 【有难度待补充】

建议:这道题目基本把 刚刚做过的字符串操作 都覆盖了,不过就算知道解题思路,本题代码并不容易写,要多练一练。 

题目链接:151. 反转字符串中的单词 - 力扣(LeetCode)

文章讲解/视频讲解:代码随想录

有一种运用stringstream的方法

class Solution {
public:
    string reverseWords(string s) {
        stringstream ss(s);
        string cur;
        string ans;
        bool isFirst = true;
        while(ss >> cur){
            if(isFirst == true){
                ans += cur;
                isFirst = false;
            }else{
                ans = cur +' '+ ans;
            }           
        }
        return ans;
    }
};

满射问题/判断是否具有相同规律【hush表】

205. 同构字符串

class Solution {
public:
    bool isIsomorphic(string s, string t) {
        if(s.size() != t.size()){
            return false;
        }
        unordered_map<char,char> maps2t;
        unordered_map<char,char> mapt2s;
        int n = s.size();
        for(int i = 0; i < n; i ++){
            if(maps2t.find(s[i]) == maps2t.end()){
                maps2t[s[i]] = t[i];
            }
            if(mapt2s.find(t[i]) == mapt2s.end()){
                mapt2s[t[i]] = s[i];
            }
            if(maps2t.find(s[i]) != maps2t.end() && maps2t[s[i]] != t[i] ||
            mapt2s.find(t[i]) != mapt2s.end() && mapt2s[t[i]] != s[i]){
                return false;
            }
        }
        return true;
    }
};

290. 单词规律

class Solution {
public:
    bool wordPattern(string pattern, string s) {
        unordered_map<char,string> maps2t;
        unordered_map<string,char> mapt2s;
        vector<string> vec = st2vec(s);
        if(pattern.size() != vec.size()) return false;
        int n = vec.size();
        for(int i = 0; i < n; i ++){
            if(maps2t.find(pattern[i]) == maps2t.end()){
                maps2t[pattern[i]] = vec[i];
            }
            if(mapt2s.find(vec[i]) == mapt2s.end()){
                mapt2s[vec[i]] = pattern[i];
            }
            if(maps2t.find(pattern[i]) != maps2t.end() && maps2t[pattern[i]] != vec[i] ||
            mapt2s.find(vec[i]) != mapt2s.end() && mapt2s[vec[i]] != pattern[i]){
                return false;
            }
        }
        return true;
    }
private:
    vector<string> st2vec(string str){
        vector<string> res;
        string word = "";
        for(char i : str){ 
            if(i == ' '){
                res.push_back(word);
                word= "";
            }else{
                word += i;
            }
            
        }
        res.push_back(word);
        return res;
    }
};

55.右旋转字符串-卡码网

建议:题解中的解法如果没接触过的话,应该会想不到;第二遍看还是没想到。

题目链接:题目页面 (kamacoder.com)

文章讲解:代码随想录

#include<iostream>
#include<algorithm>
using namespace std;
int main(){
    int n ;
    string s ;
    string s1;
    string s2;
    cin >> n ;
    cin >> s ;
    // s1 = s[0 : s.size()-n];
    // s2 = s[s.size()-n : -1];
    // cout << s2 + s1 <<endl;
    reverse(s.begin(), s.end()); // 整体反转
    reverse(s.begin(), s.begin() + n); // 先反转前一段,长度n
    reverse(s.begin() + n, s.end()); // 再反转后一段
    cout << s <<endl;
}

28. KMP - 实现 strStr() 【待补充】

因为KMP算法很难,大家别奢求 一次就把kmp全理解了,大家刚学KMP一定会有各种各样的疑问,先留着,别期望立刻啃明白,第一遍了解大概思路,二刷的时候,再看KMP会 好懂很多。

或者说大家可以放弃一刷可以不看KMP,今天来回顾一下之前的算法题目就可以。

因为大家 算法能力还没到,细扣 很难的算法,会把自己绕进去,就算别人给解释,只会激发出更多的问题和疑惑。所以大家先了解大体过程,知道这么回事, 等自己有 算法基础和思维了,在看多看几遍视频,慢慢就理解了。

题目链接:

文章讲解/视频讲解:代码随想录

 459. KMP 重复的子字符串  【待补充】

本题算是KMP算法的一个应用,不过 对KMP了解不够熟练的话,理解本题就难很多。 

我的建议是 KMP和本题,一刷的时候 ,可以适当放过,了解怎么回事就行,二刷的时候再来硬啃

题目链接:

文章讲解/视频讲解:代码随想录

用的KMP

28. 找出字符串中第一个匹配项的下标

暴力解法的话

class Solution {
public:
    int strStr(string haystack, string needle) {
        int i, j;
        for(i = 0; i < haystack.size(); i++){
            for(j = 0; j < needle.size(); j++){
                if(haystack[i + j] != needle[j]) break;
            }
            if (j == needle.size()) return i;
        }
        return -1;
    }
};

字符串总结 

题目链接/文章讲解:代码随想录

 双指针回顾 

文章讲解:代码随想录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值