【C++】string的使用

1、string的使用

#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include
using namespace std;

void Test1()
{
    string s1;
    string s2("hello");

    cin >> s1;
    cout << s1 << endl;

    //strcat【字符串拼接】
    string ret1 = s1 + s1;
    cout << ret1 << endl;

    string ret2 = s1 + "我来了";
    cout << ret2 << endl;
}

void Test2()
{
    string s1("Hello String");
    string s2 = "Hello String";
    string s3("Hello String");

//遍历string
//方法1:【数组】
    //读
    for (int i = 0; i < s1.size(); i++)
    {
        cout << s1[i];
    }
    cout << endl;
    
    //写
    for (int i = 0; i < s1.size(); i++)
    {
        s1[i]++;
    }
    cout << s1 << endl;

    cout << "------------" << endl;

//方法2:【迭代器】
    //读
    string::iterator it = s2.begin();
    while (it != s2.end())
    {
        cout << *it;
        ++it;
    }
    cout << endl;

    //写
    it = s2.begin();
    while (it != s2.end())
    {
        *it = 'A';
        ++it;
    }
    cout << s2 << endl;

    cout << "------------" << endl;

//方法3:【范围for】
    //读
    for (auto ch : s3)
    {
        cout << ch;
    }
    cout << endl;

    //写
    for (auto& ch : s3)
    {
        ++ch;
    }
    cout << s3 << endl;
}

void Test3()
{
    string s1("Hello String");

//反向迭代器
    //string::reverse_iterator rit = s1.rbegin();
    auto rit = s1.rbegin();
    while (rit != s1.rend())
    {
        cout << *rit;
        ++rit;
    }
    cout << endl;
}

void func(const string& s)
{
    //const迭代器
    //string::const_iterator it = s.begin();
    auto it = s.begin();
    while (it != s.end())
    {
        cout << *it;
        ++it;
    }
    cout << endl;

    //const反向迭代器
    //string::const_reverse_iterator rit = s.rbegin();
    auto rit = s.rbegin();
    while (rit != s.rend())
    {
        cout << *rit;
        ++rit;
    }
    cout << endl;
}

void Test4()
{
    string s1("Hello String");
    func(s1);
}

void Test5()
{
    string s1("Hello String");
    string s2(s1);

    string s3(s1, 6, 6); //从下标为6的地方起始,往后输出3个字符
    cout << s3 << endl;

    string s4(s2, 6, 3);
    cout << s4 << endl;

    string s5("Hello String XXXXXXXXXXXXXXXXXXXXXXXXX");
    //strlen不能用于自定义类型
    cout << string(s5, 6, s5.size() - 1) << endl; //从起始位置往后打印完
    cout << string(s5, 6) << endl; //不给输出多少,默认从起始位置全部输出完

    string s6(10, 'A'); //n个字符
    cout << s6 << endl;

    cout << string("Hello String", 5) << endl; //从字符串中取前n个

    string s8(s1.begin(), s1.end()); //用迭代器拷贝
    cout << s8 << endl; 

    string s9(++s1.begin(), --s1.end()); //迭代器可以控制范围
    cout << s9 << endl;

    //其他赋值
    s9 = s8;
    s9 = "XXX";
    s9 = 'Y';
}

void Test6()
{
    string s1("Hello String");
    cout << s1.size() << endl; //12【不算\0】
    cout << s1.length() << endl; //12
    cout << s1.capacity() << endl; //15

    s1.clear(); //只清数据,不清空间
    s1 = "LMY";
    cout << s1.capacity() << endl; //15

    /*string filename;
    cin >> filename;
    FILE* fout = fopen(filename.c_str(), "r");*/
}

void Test7()
{
    //string的扩容
    string s;
    s.reserve(100); //【保留空间,提前开空间】

    size_t old = s.capacity();
    cout << "初始容量:" << s.capacity() << endl;

    for (size_t i = 0; i < 100; i++)
    {
        s.push_back('x');
        if (s.capacity() != old)
        {
            cout << "扩容成功:" << s.capacity() << endl;
            old = s.capacity();
        }
    }
    s.reserve(10); //VS不能缩空间
    cout << "缩后空间容量:" << s.capacity() << endl;
}

void Test8()
{
    string s("Hello World");
    cout << "resize前:" << s.size() << endl; //11
    cout << "resize前:" << s.capacity() << endl << endl; //15

    //size < resize < capacity
    //s.resize(13); //【不给值,s里默认存\0】
    s.resize(13, 'x');
    cout << s << endl;
    cout << "resize后:" << s.size() << endl; //13
    cout << "resize后:" << s.capacity() << endl << endl; //15

    //capacity < resize【相当于插入数据】
    s.resize(20, 'x');
    cout << s << endl;
    cout << "resize后:" << s.size() << endl; //20
    cout << "resize后:" << s.capacity() << endl << endl; //31

    //resize < size【相当于删除数据】
    s.resize(5);
    cout << s << endl;
    cout << "resize后:" << s.size() << endl; //5
    cout << "resize后:" << s.capacity() << endl << endl; //31
}

void Test9()
{
    //insert/erase/repalce能不用就尽量不用,因为他们都涉及挪动数据,效率不高
    string s("Hello World");
    s.insert(0, 1, 'L');
    s.insert(s.begin(), 'L');
    cout << s << endl;

    s.erase(8,2); //【从下标为8的位置开始,往后删俩】
    cout << s << endl;
    s.erase(5); //【不给删除个数,默认从起始位置开始往后全删】
    cout << s << endl << endl;

    //空格替换为20%
    string s2("The quick brown fox jumps over a lazy dog.");
    string s3;
    for (auto ch : s2)
    {
        if (ch != ' ')
        {
            s3 += ch;
        }
        else
        {
            s3 += "20%";
        }
    }
    //swap(s2, s3);
    //s2 = s3;
    //s2.assign(s3);
    printf("s2:%p\n", s2.c_str());
    printf("s3:%p\n", s3.c_str());

    s2.swap(s3); //交换的是指针
    cout << s2 << endl;

    printf("s2:%p\n", s2.c_str());
    printf("s3:%p\n", s3.c_str());
}

void Test10()
{
    string s1("test.cpp.tar.zip");
    size_t i = s1.find('.');
    string s2 = s1.substr(i);
    cout << s2 << endl;

    size_t j = s1.rfind('.');
    string s3 = s1.substr(j);
    cout << s3 << endl << endl;

    //分离协议、域名、资源名
    string s("https://cplusplus.com/reference/string/string/");
    string sub1, sub2, sub3;
    
    size_t i1 = s.find(':');
    if (i1 != string::npos)
        sub1 = s.substr(0, i1);
    else
        cout << "没有找到i1" << endl;

    size_t i2 = s.find('/', i1 + 3);
    if (i2 != string::npos)
        sub2 = s.substr(i1 + 3, i2 - (i1 + 3)); //【左闭右开区间,一减就是个数】
    else
        cout << "没有找到i2" << endl;

    sub3 = s.substr(i2 + 1);

    cout << sub1 << endl;
    cout << sub2 << endl;
    cout << sub3 << endl;
}

void Test11()
{
    string str;
    //getline(cin, str); //【读取一行】
    getline(cin, str, '!'); //【读取到'!'结束】
    cout << str;
}

int main()
{
    Test11();

    return 0;
}

【C++】string的使用_第1张图片

【C++】string的使用_第2张图片

【C++】string的使用_第3张图片


2、string的OJ题

(1)字符串中的第一个唯一字符

class Solution
{
public:
    int firstUniqChar(string s)
    {
        int count[26] = { 0 };

        //统计次数
        /*for (int i = 0; i < s.size(); i++)
        {
            count[s[i] - 'a']++;
        }*/
        for (auto ch : s)
        {
            count[ch - 'a']++;
        }

        for (int i = 0; i < s.size(); i++)
        {
            if (count[s[i] - 'a'] == 1)
            {
                return i;
            }
        }
        return -1;
    }
};

(2)仅仅反转字母

class Solution
{
public:
    bool IsLater(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;

        int begin = 0;
        int end = s.size() - 1;
        while (begin < end)
        {
            while (begin < end && !IsLater(s[begin]))
            {
                begin++;
            }
            while (begin < end && !IsLater(s[end]))
            {
                end--;
            }
            swap(s[begin], s[end]);
            begin++;
            end--;
        }
        return s;
    }
};

(3)字符串最后一个单词的长度

  • scanf / cin 遇到空格和换行符自动停止读取,空格和换行符后边的内容会被放在缓冲区中不被此次读取。但是 getline 可以。
  • getline(cin, s);【可以读取一整行,遇到空格不停,遇到换行符才停止读取内容】
  • getline(cin, str, '!'); 【读取到’!'结束】
#include 
#include 
using namespace std;

int main()
{
    string s;
    getline(cin, s);

    size_t i = s.rfind(' ');
    if (i != string::npos)
    {
        cout << s.size() - (i + 1) << endl;
    }
    else
    {
        cout << s.size() << endl;
    }
    return 0;
}

(4)字符串相加

class Solution
{
public:
    string addStrings(string num1, string num2)
    {
        string str;
        int next = 0; //进位

        int end1 = num1.size() - 1;
        int end2 = num2.size() - 1;

        while (end1 >= 0 || end2 >= 0)
        {
            int x1 = end1 >= 0 ? num1[end1] - '0' : 0; //转成整数
            int x2 = end2 >= 0 ? num2[end2] - '0' : 0; //转成整数

            int ret = x1 + x2 + next;

            //进位
            next = ret / 10;
            ret = ret % 10;

            //头插
            //str.insert(0,1,ret+'0'); //转成字符

            //尾插
            str += ret + '0';

            end1--;
            end2--;
        }
        if (next == 1)
        {
            //str.insert(0,1,next+'0');
            str += next + '0';
        }
        reverse(str.begin(), str.end()); //逆置字符串
        return str;
    }
};

【C++】string的使用_第4张图片

(5)验证回文串

class Solution
{
public:
    //判断是不是字母
    bool IsLatter(char ch)
    {
        return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9');
    }

    bool isPalindrome(string s)
    {
        //大写字母全部转小写
        for (auto& ch : s) //要加引用才能修改
        {
            if (ch >= 'A' && ch <= 'Z')
            {
                ch += 32;
            }
        }

        int begin = 0;
        int end = s.size() - 1;
        while (begin < end)
        {
            while (begin < end && !IsLatter(s[begin]))
            {
                begin++;
            }
            while (begin < end && !IsLatter(s[end]))
            {
                end--;
            }
            if (s[begin] == s[end])
            {
                begin++;
                end--;
            }
            else
            {
                return false;
            }
        }
        return true;
    }
};

(6)字符串转整型数字

class Solution
{
public:
    int StrToInt(string str)
    {
        int len = str.size();
        int flag = 1; //区分正负数
        int sum = 0;

        if (str[0] == '-')
        {
            flag = -1;
        }

        //从个位开始
        for (int i = len - 1; i >= 0; i--)
        {
            if (str[i] == '+' || str[i] == '-')
            {
                continue;
            }

            if (str[i] >= '0' && str[i] <= '9')
            {
                //判断位数
                int n = 1;
                for (int j = len - 1; j > i; j--)
                {
                    n = n * 10;
                }
                sum += (str[i] - '0') * n;
            }

            else
            {
                return 0;
            }
        }
        return flag * sum;
    }
};

(7)反转字符串Ⅰ

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

(8)反转字符串Ⅱ

class Solution
{
public:
    //翻转start到end区间的字符串
    void Reverse(string& s, int start, int end)
    {
        while (start < end)
        {
            swap(s[start], s[end]);
            start++;
            end--;
        }
    }

    string reverseStr(string s, int k)
    {
        int len = s.size();
        for (int i = 0; i < len; i += 2 * k)
        {
            if (i + k < len)
                Reverse(s, i, i + k - 1);
            else
                Reverse(s, i, len - 1);
        }
        return s;
    }
};

(9)反转字符串中的单词

class Solution
{
public:
    void reverse(string& s, int begin, int end)
    {
        while (begin < end)
        {
            swap(s[begin], s[end]);
            begin++;
            end--;
        }
    }

    string reverseWords(string s)
    {
        int begin = 0;
        int end = 0;
        
        while (end < s.size())
        {
        	//找空格
            end = s.find(' ', begin);
            if (end == string::npos)
            {
                end = s.size();
                break;
            }
            
            //反转
            reverse(s, begin, end - 1);
            begin = end + 1;
        }
        
        //反转最后一个单词
        reverse(s, begin, end - 1);
        return s;
    }
};

(10)字符串相乘

  • 两个数相乘之后的结果的位数肯定不会超过两个数位数之和,定义一个长度为两数位数之和的字符串,然后从尾部开始迭代,通过取余和整除的操作依次计算各位结果,最后通过 substr 从不为零的位置返回字符串。
class Solution
{
public:
    string multiply(string num1, string num2)
    {
        //两个数相乘之后的结果的位数肯定不会超过两个数位数之和
        //定义一个长度为两数位数之和的字符串,然后从尾部开始迭代,通过取余和整除的操作依次计算各位结果
        //最后通过substr从不为零的位置返回字符串

        int len1 = num1.size();
        int len2 = num2.size();
        string arr(len1 + len2, '0');

        //从后按位迭代
        for (int i = len1 - 1; i >= 0; i--)
        {
            for (int j = len2 - 1; j >= 0; j--)
            {
                int tmp = (num1[i] - '0') * (num2[j] - '0') + (arr[i + j + 1] - '0');
                arr[i + j + 1] = tmp % 10 + '0';
                arr[i + j] = tmp / 10 + (arr[i + j] - '0') + '0';
            }
        }

        //取字符串
        for (int i = 0; i < len1 + len2; i++)
        {
            if (arr[i] != '0')
            {
                return arr.substr(i);
            }
        }
        
        return "0";
    }
};

你可能感兴趣的:(C++,c++,开发语言)