第五章 C++字符串

1.忽略大小比较字符串

一般我们用 strcmp 可比较两个字符串的大小,比较方法为对两个字符串从前往后逐个字符相比较(按 ASCII 码值大小比较),直到出现不同的字符或遇到 \0 为止。

如果全部字符都相同,则认为相同;如果出现不相同的字符,则以第一个不相同的字符的比较结果为准。

但在有些时候,我们比较字符串的大小时,希望忽略字母的大小,例如 Hello 和 hello 在忽略字母大小写时是相等的。

请写一个程序,实现对两个字符串进行忽略字母大小写的大小比较。

输入格式

输入为两行,每行一个字符串,共两个字符串。注意字符串中可能包含空格。

数据保证每个字符串的长度都不超过 80。

输出格式

如果第一个字符串比第二个字符串小,输出一个字符 <。

如果第一个字符串比第二个字符串大,输出一个字符 >。

如果两个字符串相等,输出一个字符 =。

输入样例:

Hello
hello

输出样例:

=

题解:

#include <iostream>
#include <cstring>
using namespace std;

int main() {
    string a, b;
    getline(cin, a);
    getline(cin, b);
    for (int i = 0; i < a.size(); i++) {
        a[i] = tolower(a[i]);
        b[i] = tolower(b[i]);
    }
    if (a < b) {
        cout << "<" << endl;
    } else if (a > b){
        cout << ">" << endl;
    } else {
        cout << "=" << endl;
    }
    return 0;
}

2.字符串中最长的连续出现的字符

求一个字符串中最长的连续出现的字符,输出该字符及其出现次数,字符串中无空白字符(空格、回车和 tab),如果这样的字符不止一个,则输出第一个。

输入格式

第一行输入整数 N,表示测试数据的组数。

每组数据占一行,包含一个不含空白字符的字符串,字符串长度不超过 200。

输出格式
共一行,输出最长的连续出现的字符及其出现次数,中间用空格隔开。

输入样例:

2
aaaaabbbbbcccccccdddddddddd
abcdefghigk

输出样例:

d 10
a 1

题解:

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;

    while (n--) {
        string s;
        int cnt = 1;
        int max = -1;
        char maxc = ' ';
        cin >> s;
        for (int i = 0; i < s.size() - 1; i++) {
            if (s[i] == s[i + 1]) {
                cnt++;
            } else {
                cnt = 1;
            }
            if (cnt > max) {
                max = cnt;
                maxc = s[i];
            }
        }
        cout << maxc << " " << max << endl;
    }
    return 0;
}

3.字符串乘方

给定两个字符串 a 和 b,我们定义 a×b 为他们的连接。

例如,如果 a=abc 而 b=def, 则 a×b=abcdef。

如果我们将连接考虑成乘法,一个非负整数的乘方将用一种通常的方式定义:a0=“(空字符串),a(n+1)=a×(an)。

输入格式

输入包含多组测试样例,每组测试样例占一行。

每组样例包含一个字符串 s,s 的长度不超过 100。

最后的测试样例后面将是一个点号作为一行。

输出格式

对于每一个 s,你需要输出最大的 n,使得存在一个字符串 a,让 s=an。

输入样例:

abcd
aaaa
ababab
.

输出样例:

1
4
3

题解:

#include <iostream>
using namespace std;

int main() {
    string s;
    while (cin >> s, s != ".") {
        int len = s.size();
        for (int i = len; i >= 0; i--) {
            if (len % i == 0) {
                int m = len / i;
                string t = s.substr(0, m);
                string r;
                for (int j = 0; j < i; j++) {
                    r += t;
                }
                if (r == s) {
                    cout << i << endl;
                    break;
                }
            }
        }
    }
    return 0;
}

4.字符串最大跨距

有三个字符串 S,S1,S2,其中,S 长度不超过 300,S1 和 S2 的长度不超过 10。

现在,我们想要检测 S1 和 S2 是否同时在 S 中出现,且 S1 位于 S2 的左边,并在 S 中互不交叉(即,S1 的右边界点在 S2 的左边界点的左侧)。

计算满足上述条件的最大跨距(即,最大间隔距离:最右边的 S2 的起始点与最左边的 S1 的终止点之间的字符数目)。

如果没有满足条件的 S1,S2 存在,则输出 −1。

例如,S= abcd123ab888efghij45ef67kl, S1= ab, S2= ef,其中,S1 在 S 中出现了 2 次,S2 也在 S 中出现了 2 次,最大跨距为:18。

输入格式

输入共一行,包含三个字符串 S,S1,S2,字符串之间用逗号隔开。

数据保证三个字符串中不含空格和逗号。

输出格式

输出一个整数,表示最大跨距。

如果没有满足条件的 S1 和 S2 存在,则输出 −1。

输入样例:

abcd123ab888efghij45ef67kl,ab,ef

输出样例:

18

题解:

#include <iostream>
using namespace std;

int main() {
    string s, s1, s2;
    char c;

    while (cin >> c, c != ',') {
        s += c;
    }
    while (cin >> c, c != ',') {
        s1 += c;
    }
    while (cin >> c) {
        s2 += c;
    }

    if (s.size() < s1.size() || s.size() < s2.size()) {
        cout << -1 << endl;
    } else {
        int l = 0;
        while (l <= s.size() - s1.size()) {
            int k = 0;
            while (k < s1.size()) {
                if (s[l + k] != s1[k]) {
                    break;
                }
                k++;
            }
            if (k == s1.size()) {
                break;
            }
            l++;
        }

        int r = s.size() - s2.size();
        while (r >= 0) {
            int k = 0;
            while (k < s2.size()) {
                if (s[r + k] != s2[k]) {
                    break;
                }
                k++;
            }
            if (k == s2.size()) {
                break;
            }
            r--;
        }

        l += s1.size();

        if (l <= r) {
            cout << r - l << endl;
        } else {
            cout << -1 << endl;
        }
    }


    return 0;
}

5.最长公共字符串后缀

给出若干个字符串,输出这些字符串的最长公共后缀。

输入格式

由若干组输入组成。

每组输入的第一行是一个整数 N。

N 为 0 时表示输入结束,否则后面会继续有 N 行输入,每行是一个字符串(字符串内不含空白符)。

每个字符串的长度不超过 200。

输出格式

共一行,为 N 个字符串的最长公共后缀(可能为空)。

数据范围

1≤N≤200

输入样例:

3
baba
aba
cba
2
aa
cc
2
aa
a
0

输出样例:

ba

a

题解:

#include <iostream>
using namespace std;

string s[200];
int main() {
    int n;
    while (cin >> n, n) {
        int len = 205;
        for (int i = 0; i < n; i++) {
            cin >> s[i];
            if (s[i].size() < len) {
                len = s[i].size();
            }
        }

        while (len) {
            bool success = true;
            for (int i = 1; i < n; i++) {
                bool is_same = true;
                for (int j = 1; j <= len; j++) {
                    if (s[0][s[0].size() - j] != s[i][s[i].size() - j]) {
                        is_same = false;
                        break;
                    }
                }
                if (!is_same) {
                    success = false;
                    break;
                }
            }
            if (success) {
                break;
            } else {
                len--;
            }
        }

        cout << s[0].substr(s[0].size() - len) << endl;;
    }

    return 0;
}