部分简单字符串算法题解(自用)


题 1:最长连续字符

给定一个不含空白字符的字符串,要求找出其中最长连续出现的字符及其出现次数。如果存在多个字符满足条件,则输出第一个出现的字符及其次数。

第一行输入整数 N N N,表示测试数据的组数。接下来的 N N N 行,每行包含一个不含空白字符的字符串(长度不超过 200)。对于每组测试数据,输出一行,包含两个部分:最长连续出现的字符;该字符的连续出现次数,中间用空格隔开。

输入

2
aaaaabbbbbcccccccdddddddddd
abcdefghigk

输出

d 10
a 1

代码

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n; 
    string s;
    while (n--) {
        cin >> s; 
        int cnt = 0; 
        int max = 1; 
        char c = s[0]; 

        for (int i = 0; i < s.size(); i++) {
            if (s[i] == s[i + 1]) {
                cnt++; 
                if (cnt >= max) { 
                    max = cnt + 1;
                    c = s[i];
                }
            } else {
                cnt = 0; 
            }
        }
        cout << c << " " << max << endl; 
    }
    return 0;
}

题 2:最长单词

一个以 . 结尾的简单英文句子,单词之间用单个空格分隔,没有缩写形式和其它特殊形式,求句子中的最长单词。输入一行字符串,表示这个简单英文句子,长度不超过 500。该句子中最长的单词。如果多于一个,则输出第一个。

输入样例:

I am a student of Peking University.

输出样例:

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

int main() {
    string ret; 
    string s;  
    int max = 0; 
    while (cin >> s) { 
        int len = s.size();
        if (s[len - 1] == '.') {
            len--;
            s.erase(len, 1);
        }
        if (len > max) {
            max = len;
            ret = s;
        }
    }
    cout << ret; 
}

题 3:倒排单词

编写程序,读入一行英文(只包含字母和空格,单词间以单个空格分隔),将所有单词的顺序倒排并输出,依然以单个空格分隔。输入为一个字符串(字符串长度至多为 100)。输出为按要求排序后的字符串。

输入样例:

I am a student

输出样例:

student a am I
#include <iostream>
#include <string>
using namespace std;

int main() {
    string s;
    string ret;
    while(cin>>s){
        ret=s+" "+ret;
    }
    cout<<ret;

    return 0;
}

题 4:字符串移位包含

对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串。给定两个字符串 s 1 s_1 s1 s 2 s_2 s2,要求判定其中一个字符串是否是另一字符串通过若干次循环移位后的新字符串的子串。

共一行,包含两个字符串,中间由单个空格隔开。字符串只包含字母和数字,长度不超过 30。如果一个字符串是另一字符串通过若干次循环移位产生的新串的子串,则输出 true,否则输出 false

输入样例:

AABCD CDAA

输出样例:

true
#include <cmath>
#include <iostream>
using namespace std;
int main() {
    string a,b;
    cin>>a>>b;
    if(a.size()<b.size()) swap(a,b);
    string c = a+a;
    size_t t = c.find(b);
    if(t!=string::npos) puts("true");
    else puts("false");
    
  return 0;
}
#include <iostream>
using namespace std;
int main()
{
    string str, res;
    cin >> str >> res;

    if (str.size() < res.size())
        swap(str, res); // 母串str,子串res

    int len1 = str.size();
    int len2 = res.size();
    int st = 0;

    for (int i = 0; i < len1; i++) {
        str = str.substr(1) + str[0]; // 母串逐次移至末尾

        if (str.substr(0, len2) == res) 
            st = 1;
    }
    if (st == 1)
        cout << "true";
    else
        cout << "false";
    return 0;
}


题 5:字符串乘方

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

例如,如果 a = a b c a = abc a=abc b = d e f b = def b=def,则 a × b = a b c d e f a \times b = abcdef a×b=abcdef

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

输入包含不超过 10 组测试样例,每组测试样例占一行。每组样例包含一个由小写字母构成的字符串 s s s s s s 的长度不超过 100,且不包含空格。最后的测试样例后面将是一个点号作为一行。

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

输入样例:

abcd
aaaa
ababab
.

输出样例:

1
4
3
#include <iostream>
using namespace std;
int main()
{
    string s;
    while (getline(cin, s)) {
        if (s == ".")
            break;
        int n = s.size();
        int flag = 0;
        int len = 1;
        for (; len <= n; len++) {
            if (n % len == 0) {
                flag = 1;
                for (int k = len; k <= n; k++) {
                    if (s[k] != s[k % n]) {
                        flag = 0;
                        break;
                    }
                }
            }
        }
        if (flag)
            cout << n / len;
        else
            cout << 1;
    }
    return 0;
}

题 6:字符串最大跨距

问题描述

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

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

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

如果没有满足条件的 S 1 S_1 S1 S 2 S_2 S2 存在,则输出 − 1 -1 1

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

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

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

如果没有满足条件的 S 1 S_1 S1 S 2 S_2 S2 存在,则输出 − 1 -1 1

输入样例:

abcd123ab888efghij45ef67kl,ab,ef

输出样例:

18
#include <iostream>

using namespace std;

int main() {
  string s, s1, s2, a;
  getline(cin, a);

  int f1, f2;
  f1 = a.find(',');
  f2 = a.rfind(',');
  s = a.substr(0, f1);
  s1 = a.substr(f1 + 1, f2 - f1 - 1);
  s2 = a.substr(f2 + 1);

  int l, r;
  l = s.find(s1);
  r = s.rfind(s2);

  if (l == -1 || r == -1) {
    cout << "-1";
    return 0;
  }

  l = s.find(s1) + s1.size() - 1;
  if (l >= r)
    cout << "-1";
  else
    cout << r - l - 1;

  return 0;
}

题 7:最长公共后缀

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

由不超过 5 组输入组成。每组输入的第一行是一个整数 N N N N N N 为 0 时表示输入结束,否则后面会继续有 N N N 行输入,每行是一个字符串(字符串内不含空白符)。每个字符串的长度不超过 200。

输出格式
每组数据输出一行结果,为 N N N 个字符串的最长公共后缀(可能为空)。

输入样例:

3
baba
aba
cba
2
aa
cc
2
aa
a
0

输出样例:

ba
a
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

string ComString(const string& str1, const string& str2) {
  int len1 = str1.size();
  int len2 = str2.size();
  int i = len1 - 1;
  int j = len2 - 1;
  string comstr = "";
  while (i >= 0 && j >= 0 && str1[i] == str2[j]) {
    comstr += str1[i];
    i--;
    j--;
  }
  reverse(comstr.begin(), comstr.end());
  return comstr;
}
string comStrGrorup(const vector<string>& strs) {
  if (strs.empty()) return "";
  string ret = strs[0];
  for (size_t i = 1; i < strs.size(); i++) {
    ret = ComString(ret, strs[i]);
    if (ret.empty()) break;
  }
  return ret;
}

int main() {
  int N;
  while (cin >> N, N) {
    vector<string> strings(N);
    char ch = getchar();
    for (int i = 0; i < N; i++) {
      getline(cin, strings[i]);
    }
    string ret = comStrGrorup(strings);
    cout << ret;
  }
  //test for ComString
  /*   
  	string a = "abcdde";
    string b = "bcddde";
    cout << ComString(a, b); 
  */

  return 0;
}

后续补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Echo-Nie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值