day8 字符串

c++ 字符库函数
1.初始化

(1)string s1 = string(s, start) // 从下标start。拷贝剩余所有字符到s2

(2)string s2 = string(s, start, len) //从下标start开始拷贝len长度的字符

(3)使用字符数组初始化
char c[] = “hello world”;
string str3 = string(c, len) //从index=0,拷贝le那个元素
string str4 = string("字符串“, len) // 这里的字符串依旧被看成字符数组

  1. 插入
    s.insert(pos,n,ch) //在字符串s的pos位置上面插入n个字符ch
    s.insert(pos,str) // 在字符串s的pos位置插入字符串str
    s.insert(pos,str,a,n) //在字符串s的pos位置插入字符串str中位置a到后面的n个字符
    s.insert(pos,cstr,n) 在字符串s的pos位置插入字符数组cstr从开始到后面的n个字符

  2. 替换
    s.replace(p0,n0,n,ch) 删除p0开始的n0个字符,然后在p0处插入n个字符ch
    s.replace(p0,n0,str) 删除从p0开始的n0个字符,然后在p0处插入字符串str
    s.replace(p0,n0,str,pos,n) 删除p0开始的n0个字符,然后在p0处插入字符串str中从pos开始的n个字符
    s.replace(p0,n0,cstr,n) 删除p0开始的n0个字符,然后在p0处插入字符数组cstr的前n个字符

  3. 翻转
    reverse(str.begin()+n,str.end() +m) 反转在[n,m)范围内的顺序 前闭后开

  4. 删除字符串
    s.erase(pos, len) //如果不指明 len 的话,那么直接删除从 pos 到字符串结束处的所有字符

  5. 提取子字符串
    s.substr(pos, len) //pos 为要提取的子字符串的起始下标,len 为要提取的子字符串的长度。

    系统对 substr() 参数的处理和 erase() 类似:
    如果 pos 越界,会抛出异常;
    如果 len 越界,会提取从 pos 到字符串结尾处的所有字符。

  6. 字符串查找
    s.find(s2, pos) [pos, size()-1] 不指明开始查找的下标,则从第0个字符开始查找
    (1)如果没有查找到子字符串,那么会返回一个值,它是 string 类内部定义的一个静 态常成员,用来表示 size_t 类型所能存储的最大值
    (2)s2可以是字符串,也可以是字符数组

    s.rfind(s2, pos) [0.pos] 查找到第二个参数处
    find_first_of(s2) 查找子字符串和字符串共同具有的字符在字符串中首次出现的位置

  7. 扩充字符串
    s.resize(len);

344.反转字符串
方法:双指针翻转
注意元素交换方式:

 swap(s[i],s[j]);
//位运算交换
 s[i] ^= s[j];
 s[j] ^= s[i];
 s[i] ^= s[j];

541. 反转字符串 II
前一题主要就是考察不用库函数的字符串翻转,这道题重点再模拟过程,直接使用reverse函数就可以

class Solution {
public:
    string reverseStr(string s, int k) {
         int start = 0;
         while(start < s.size()){
             if(s.size() - start < k) reverse(s.begin() + start, s.end());
             else reverse(s.begin() + start, s.begin() + start + k);
             start += 2*k;
         }
         return s;
    }
};

151. 反转字符串中的单词

整体翻转加局部翻转

使用额外空间

  1. 将整个字符串翻转
  2. 将每一个字符再转回来,并且将字符串粘贴到另一个字符串来解决空格的问题
  3. 为了避免字符串头部有没有多余空格造成的区别,提前在原字符串头加一个空格
class Solution {
public:
    string reverseWords(string s) {
        string result;
        s.insert(0, " ");
        reverse(s.begin(), s.end());  //翻转整个字符串
        int start=0;
        for(int i= 0; i<s.size(); i++){  //找到第一个不为空格的字符
            if(s[i]!=' '){
                start = i;
                break;
            }
        }
        int end = start;
        while(end < s.size()){
            if(s[end]!=' ') end++;
            else{
            //进行切割存储的逻辑是遇到空格触发的,但是原字符串头部不一定有
            //多余空格,那么最后一个词的翻转就不会执行,所以为避免这种分类
            //在原字符串头部多加了一个空格  
                string temp = s.substr(start, end - start);
                reverse(temp.begin(), temp.end());
                result += temp;
                result += " ";
                while(s[end] == ' ') end++;
                start = end;
            }
        }
        return result.erase(result.size()-1);
    }
};

原地旋转

  1. 先进行空格的删除
  2. 翻转整个数组
  3. 翻转每一个字符串
class Solution {
public:
    string reverseWords(string s) {
        s = delet(s);
        reverse(s.begin(), s.end());
        int start = 0;
        int end = start;
        while(end <= s.size()){
            if(end == s.size()|| s[end] == ' '){
                reverse(s.begin() + start, s.begin() + end);
                start = end + 1;
            }
            end++;
        }
        return s;
    }
    string delet(string s){ //双指针覆盖
        int slow = 0;
        int fast = 0;
        while(fast < s.size()){
            if(s[fast] !=' ') s[slow++] = s[fast++];
            else{
                while(fast <s.size( )&& s[fast] ==' ') fast++;
                //之后一个单词之后不需要额外加空格
                if(slow!=0 && fast<s.size()) s[slow++] = ' ';
            }
        }
        s.erase(slow);
        return s;
    }

};

剑指 Offer 58 - II. 左旋转字符串

局部反转加整体翻转

class Solution {
public:
    string reverseLeftWords(string s, int n) {
        reverse(s.begin(), s.begin() + n);
        reverse(s.begin() + n, s.end());
        reverse(s.begin(), s.end());
        return s;
    }
};

BM85 验证IP地址

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

//IPV4 特点: 0 - 255;. 分割;不能以0开头;长度为4段
//IPv6 特点:8段;不能省略::,每段4位,16进制
class Solution {
  public:
    /**
     * 验证IP地址
     * @param IP string字符串 一个IP地址字符串
     * @return string字符串
     */
    string solve(string IP) {
        if (IP.find('.') < IP.size()) return Ipv4(IP);
        return Ipv6(IP);
    }

    string Ipv4(string IP) {
        if (IP.size() < 7 || IP[0] == '.') return "Neither";

        vector<string>s;
        int start = 0;
        for (int i = 0; i <= IP.size(); i++) {
            if (i < IP.size() && IP[i] < '0' && IP[i] > '9' &&
                    IP[i] != '.')return "Neither";
            if (i == IP.size() || IP[i] == '.') {
                string x = IP.substr(start, i - start);
                cout << x << endl;
                if (x.size() == 0 || x.size() > 3 || (x.size() > 1 &&
                                                      x[0] == '0')) return "Neither";
                s.push_back(x);
                if (s.size() > 4 || (i < IP.size() - 1 &&
                                     IP[i] == IP[i + 1])) return
                                             "Neither"; // 放置两个连续.使start始终指向第一个
                start = i + 1;
            }
        }
        for (string x : s) {
            int sum = 0;
            for (int i = 0; i < x.size(); i++) {
                sum += (x[i] - '0') * (pow(10, x.size() - i - 1));
            }
            if (sum > 255) return "Neither" ;
        }
        return "IPv4";
    }
    string Ipv6(string IP) {
        if (IP.size() < 15 || IP[0] == ':') return "Neither";

        vector<string>s;
        int start = 0;
        for (int i = 0; i <= IP.size(); i++) {
            if (i == IP.size() || IP[i] == ':') {
                string x = IP.substr(start, i - start);
                cout << x << endl;
                if (x.size() == 0 || x.size() > 4 ||(x.size() > 1 && x[0] == '0' && x[1]=='0')) return "Neither";
                s.push_back(x);
                if (s.size() > 8 || (i < IP.size() - 1 && IP[i] == IP[i + 1])) return "Neither";
                start = i + 1;
            }
        }
         for (string x : s) {
            for(int i=0; i<x.size(); i++){
                if((x[i]<'a' || x[i] >'f') && (x[i]<'A' || x[i] >'F') && x[i]!=':'&&( x[i]<'0' ||x[i]>'9')){
                    cout<<x[i];
                     return "Neither";
                }
                   
            }
        }


        return "IPv6";
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值