西安交通大学—软件学院—专业课915—AcWing—语法基础课(第五讲:字符串)

本篇博文是笔者归纳汇总的AcWing基础语法课题集,目的方便各位准研究生复盘巩固~

特点:前四章建议自己学习,较为简单!后四章题目一题多解,详细注释。算法代码简洁,适合背诵记忆~

PS: 其他任何有关交大考研问题都可私我!!!

第五章——字符串

AcWing 760. 字符串长度

//给定一行长度不超过 100 的非空字符串,请你求出它的具体长度。
//输入格式
//输入一行,表示一个字符串。注意字符串中可能包含空格。

//输出格式
//输出一个整数,表示它的长度。

//方法1
#include <iostream>
#include <cstring>
using namespace std;
int main(){
    string a;
    getline(cin,a);
    cout<<a.size()<<endl;
    return 0;
}
//方法2
#include <iostream>
#include <cstring>
using namespace std;
int main(){
    char a[100];
    cin.getline(a,100);//需要注意cin.getline()会把换行符取出删除,不影响下一次读入!
    cout<<strlen(a)<<endl;
    return 0;
}

AcWing 761. 字符串中的数字个数

// 输入一行字符,长度不超过 100,请你统计一下其中的数字字符的个数。

// 输入格式
// 输入一行字符。注意其中可能包含空格。

// 输出格式
// 输出一个整数,表示数字字符的个数。
//方法1
#include<iostream>
#include<cstring>
using namespace std;
int main(){
    string s;
    int sum=0;
    getline(cin,s);
    for(int i=0;i<s.size();i++){
        if(s[i]>='0'&&s[i]<='9'){
            sum++;
        }
    }
    cout<<sum<<endl;
    return 0;
}
//方法2
#include<iostream>
#include<cstring>
using namespace std;
int main(){
    char s[100];
    int sum=0;
    cin.getline(s,100);
    for(int i=0;i<strlen(s);i++){
        if(s[i]>='0'&&s[i]<='9'){
            sum++;
        }
    }
    cout<<sum<<endl;
    return 0;
}

AcWing 763. 循环相克令

// 令词为“猎人、狗熊、枪”,两人同时说出令词,
// 猎人赢枪、枪赢狗熊、狗熊赢猎人,动作相同则视为平局。
// 现在给定你一系列的动作组合,请你判断游戏结果。
// 输入格式
// 第一行包含整数 T,表示共有 T 组测试数据。
// 接下来 T 行,每行包含两个字符串,表示一局游戏中两人做出的动作,字符串为 Hunter, Bear, Gun 中的一个,这三个单词分别代表猎人,狗熊和枪。
// 输出格式
// 如果第一个玩家赢了,则输出 Player1。
// 如果第二个玩家赢了,则输出 Player2。
// 如果平局,则输出 Tie。
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
    int n;
    string player1,player2;
    cin>>n;
   while(n--){
       cin>>player1>>player2;
       if(player1==player2)
        cout<<"Tie"<<endl;
       else if(player1=="Hunter"&&player2=="Gun"||player1=="Bear"&&player2=="Hunter"||player1=="Gun"&&player2=="Bear")
        cout<<"Player1"<<endl;
       else cout<<"Player2"<<endl;
   }
    return 0;
}

AcWing 765. 字符串加空格

// 给定一个字符串,在字符串的每个字符之间都加一个空格。
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
    string s;
    getline(cin,s);
    for(int i=0;i<s.size();i++){
        cout<<s[i]<<" ";
    }
}

AcWing 769. 替换字符

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
    string s;
    char ch;
    getline(cin,s);
    cin>>ch;
    for(int i=0;i<s.size();i++){
        if(s[i]!=ch)
        cout<<s[i];
        else cout<<"#";
    }
    return 0;
}

AcWing 773. 字符串插入

// 有两个不包含空白字符的字符串 str 和 substr,str 的字符个数不超过 10,substr 的字符个数为 3。(字符个数不包括字符串结尾处的 \0。)
// 将 substr 插入到 str 中 ASCII 码最大的那个字符后面,若有多个最大则只考虑第一个

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
    string str,substr;
    while(cin>>str>>substr){
    int i=0,j=0;
    int max=i;//寻找ASCII最大的下标
    for( i=0;i<str.size()-1;i++){
        if(str[i]<str[i+1])
        max=i+1;
    }
    for(i=0;i<max+1;i++){
        cout<<str[i];
    }
    for(i=0;i<3;i++){
        cout<<substr[i];
    }
    for(i=max+1;i<str.size();i++){
        cout<<str[i];
    }
    cout<<endl;
}
}

AcWing 772. 只出现一次的字符

// 给你一个只包含小写字母的字符串。
// 请你判断是否存在只在字符串中出现过一次的字符。
// 如果存在,则输出满足条件的字符中位置最靠前的那个。
// 如果没有,输出 no。
//方法1
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
    string s;
    int temp=1;//查看是否有符合条件的字符,如果没有就输出“no”
    int num[100000]={};//设置标志位,标记该字符是否符合条件
    getline(cin,s);
    for(int i=0;i<s.size()-1;i++){
        for(int j=i+1;j<s.size();j++){
            if(s[i]==s[j]){
            num[i]=num[j]={1};
            break;
			}
        }
    }
    for(int i=0;i<s.size();i++){
    	if(num[i]!=1){
    		cout<<s[i];
    		temp=0;
    		break;
		}
    }
    if(temp==1)
    cout<<"no";
}
//方法2
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
    string s;
    getline(cin,s);
    int flag[300]={0};
    char p=-1;
    for(int i=0;i<s.size();i++){
        flag[s[i]]++;  //计数
    }
    for(int i=0;i<s.size();i++){
        if(flag[s[i]]==1){
            p=s[i];
            break;
        }
    }
    if(p==-1)
    cout<<"no";
    else cout<<p;
}

AcWing 762. 字符串匹配

//给定两个长度相同的字符串 a 和字符串 b。
//如果在某个位置 i 上,满足字符串 a 上的字符 a[i] 和字符串 b 上的字符 b[i] 相同,那么这个位置上的字符就是匹配的。
//如果两个字符串的匹配位置的数量与字符串总长度的比值大于或等于 k,则称两个字符串是匹配的。
//现在请你判断给定的两个字符串是否匹配。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
    double k,m=0;
    string a,b;
    cin>>k>>a>>b;
    int len=a.size();
    for(int i=0;i<len;i++){
        if(a[i]==b[i])
        m++;
    }
    if(m/len>=k)
    cout<<"yes";
    else cout<<"no";
}

AcWing 768. 忽略大小写比较字符串大小

//一般我们用 strcmp 可比较两个字符串的大小,比较方法为对两个字符串从前往后逐个字符相比较(按 ASCII 码值大小比较),直到出现不同的字符或遇到 \0 为止。
//如果全部字符都相同,则认为相同;如果出现不相同的字符,则以第一个不相同的字符的比较结果为准;如果两字符串长度不同,但所有相同位置的字符均相同,则认为较长字符串更大。
//在有些时候,我们比较字符串的大小时,希望忽略字母的大小,例如 Hello 和 hello 在忽略字母大小写时是相等的。
//请写一个程序,实现对两个字符串进行忽略字母大小写的大小比较。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main(){
    string a,b;
    getline(cin,a);
    getline(cin,b);
    int len1=a.size();
    int len2=b.size();
    for(int i=0;i<len1;i++)
    a[i]=tolower(a[i]);//tolower()函数:大写字母->小写字母
    for(int i=0;i<len2;i++)
    b[i]=tolower(b[i]);
    if(a==b) cout<<"=";
    else if(a>b) cout<<">";
    else cout<<"<";
    return 0;
}

AcWing 766. 去掉多余的空格

//输入一个字符串,字符串中可能包含多个连续的空格,请将多余的空格去掉,只留下一个空格。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main(){
    string a;
    getline(cin,a);
    int flag=0;//设置标志位
    for(int i=0;i<a.size();i++){
    	if(a[i]!=' '){
    		cout<<a[i];
    		flag=0;
		}
    	else{
    		if(flag==0){
    			cout<<" ";
    			flag=1;
			}
        }
	}
}

AcWing 767. 信息加密

// 字符串中的小写字母,a 加密为 b,b 加密为 c,…,y 加密为 z,z 加密为 a。
// 字符串中的大写字母,A 加密为 B,B 加密为 C,…,Y 加密为 Z,Z 加密为 A。
// 字符串中的其他字符,不作处理。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
    string s;
    getline(cin,s);
    for(int i=0;i<s.size();i++){
        if(s[i]>='a'&&s[i]<'z'){
            s[i]=s[i]+1;
        }
        else if(s[i]=='z')
        s[i]='a';
        if(s[i]>='A'&&s[i]<'Z'){
            s[i]=s[i]+1;
        }
        else if(s[i]=='Z')
        s[i]='A';
    }
    cout<<s;
}

AcWing 764. 输出字符串

// 给定字符串 a 的第一个字符的 ASCII 值加第二个字符的 ASCII 值,得到 b 的第一个字符;
// 给定字符串 a 的第二个字符的 ASCII 值加第三个字符的 ASCII 值,得到 b 的第二个字符;
// …
// 给定字符串 a 的倒数第二个字符的 ASCII 值加最后一个字符的 ASCII 值,得到 b 的倒数第二个字符;
// 给定字符串 a 的最后一个字符的 ASCII 值加第一个字符的 ASCII 值,得到 b 的最后一个字符。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
    string a;
    getline(cin,a);
    for(int i=0;i<a.size()-1;i++)
    {
        cout<<char(a[i]+a[i+1]); //char 类型转换,否则只输出ASCII码
    }
    cout<<char(a[a.size()-1]+a[0]);
    return 0;
}

AcWing 770. 单词替换

// 该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区分大小写。
// 现需要将其中的某个单词替换成另一个单词,并输出替换之后的字符串。
// 输入格式
// 第 1 行是包含多个单词的字符串 s;
// 第 2 行是待替换的单词 a(长度不超过 100);
// 第 3 行是 a 将被替换的单词 b(长度不超过 100)。

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

//求一个字符串中最长的连续出现的字符,输出该字符及其出现次数,字符串中无空白字符(空格、回车和 tab),如果这样的字符不止一个,则输出第一个。
#include<iostream>
using namespace std;
int main()
{
    int n;
    cin>>n;
    string s;
    while(n--)
    {
        char c;
        int count=0, max = 1;
        cin>>s;
        c = s[0];
        for(int i=0 ;i<s.size()-1;i++)
        {
            if(s[i]==s[i+1])
            {
                count+=1;
                if(count >= max)
                {
                    max = count+1;
                    c = s[i];
                }
            }
            else{
                count = 0;
            }
        }
        cout<<c<<" "<<max<<endl;
    }

AcWing 774. 最长单词

//一个以 . 结尾的简单英文句子,单词之间用单个空格分隔,没有缩写形式和其它特殊形式,求句子中的最长单词。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
    string s;
    getline(cin,s);
    int sum[500];
    int j=0,num=0;
    for(int i=0;i<s.size();i++)//统计每个单词的长度
    {
        if(s[i]!=' '&&s[i]!='.'){
            num++;
        }
        else{
            sum[j++]=num;
            num=0;
        }
    }
    int max=sum[0];
    for(int i=0;i<j;i++)//找出最长的单词长度
    {
    	if(sum[i]>max)
    	max=sum[i];
	}
	int len=max;
	for(int i=0;i<s.size();i++)
	{
		if(s[i]!=' '&&s[i]!='.'){
			len--;
		    if(len==0){
			    for(int k=i-max+1;k<=i;k++)//遍历每次长度减一,若为0则输出
			    {
			    	cout<<s[k];
				}
				break;
		}
		}
		else//若不为0就恢复最大长度
		{
			len=max;
		}
	}
}

AcWing 775. 倒排单词

//编写程序,读入一行英文(只包含字母和空格,单词间以单个空格分隔),将所有单词的顺序倒排并输出,依然以单个空格分隔。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
    string s;
    getline(cin,s);
    int book[100],k=1;
    book[0]={0};
    for(int i=0;i<s.size();i++)//book[]数组中记录每个单词的起始坐标
    {
        if(s[i]==' ')
        book[k++]=i+1;
    }
    while(k>0){
        for(int i=book[k-1];s[i]!=' '&&i<s.size();i++){
            cout<<s[i];
        }
        cout<<" ";
        k--;
    }
}

AcWing 776. 字符串移位包含问题

//对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串。
//给定两个字符串 s1 和 s2,要求判定其中一个字符串是否是另一字符串通过若干次循环移位后的新字符串的子串。
//例如 CDAA 是由 AABCD 两次移位后产生的新串 BCDAA 的子串,而 ABCD 与 ACBD 则不能通过多次移位来得到其中一个字符串是新串的子串。
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
    string a,b;
    char ch;
    cin>>a>>b;
    if(a.size()<b.size())//判断长度大小
    swap(a,b);
    int len=a.size(),flag1=0;//flag1为标志位
    while(len--){
    ch=a[0];
    for(int i=0;i<a.size()-1;i++){//循环产生所有位移形式,长度为n就有n种
        a[i]=a[i+1];
    }
    a[a.size()-1]=ch;
    int flag=a.find(b);//find()函数,判断子串,返回第一个位置下标,无则返回-1
    if(flag>=0) 
    flag1=1;
 }
 if(flag1==1)
 cout<<"true";
 else cout<<"false";
}

AcWing 777. 字符串乘方
在这里插入图片描述

#include <iostream> 
#include <string>
using namespace std;
int main(){
    string s;
    while (cin >> s,s[0]!='.'){
        int f = 1;
        for (int i = 1; i <= ( s.size() / 2 ); i ++){
            int k = 0, cnt = 0;
            string a = s.substr(0, i);
            while ( s[k] && s.find(a, k) != -1 ){
                cnt ++;
                k = s.find(a, k) + i;
            }
            if ( cnt * i == s.size() ){
                cout << cnt << endl;
                f = 0;
                break;
            }
        }
        if(f) 
        cout << "1" << endl;
    }
    return 0;
}

AcWing 778. 字符串最大跨距

//有三个字符串 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,字符串之间用逗号隔开。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
    string s0,s,s1,s2; 
    getline(cin,s0);
    int x=s0.find(',');
    int y=s0.rfind(',');
    s=s0.substr(0,x);             //substr()函数,截取字符串片段
    s1=s0.substr(x+1,y-x-1);
    s2=s0.substr(y+1,s0.size()-y-1);
    int l, r;
    l = s.find(s1);                   // 在字符串s上从左往右找s1,找到第一个子串
    r = s.rfind(s2);                  // 在字符串s上从右往左找s2,找到最后一个子串
    if (l == -1 || r == -1)           // s1 或 s2 不在 s 上
    { 
        cout << "-1";
        return 0;
    }
    l = s.find(s1)  + s1.size() - 1;   // l为s1最右面的下标

    if ( l >= r )                      // s1 s2 交叉
        cout << "-1";
    else cout << r - l - 1;
    return 0;
}

AcWing 779. 最长公共字符串后缀

//输入格式
//由不超过 5 组输入组成。
//每组输入的第一行是一个整数 N。
//N 为 0 时表示输入结束,否则后面会继续有 N 行输入,每行是一个字符串(字符串内不含空白符)。
//每个字符串的长度不超过 200。
//输出格式
//每组数据输出一行结果,为 N 个字符串的最长公共后缀(可能为空)。
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 210;
string s[N];
int main(){
    int m;      // m个字符串
    while (cin >> m && m){
        int len = 200;
        for (int i = 0; i < m; i ++){
            cin >> s[i];
            reverse( s[i].begin(), s[i].end() );         // 把每个字符串首尾翻转 变后缀为前缀
            if ( s[i].size() < len) 
			len = s[i].size();               // 取所有字符串中最短长度作为len
        }
        string a;                           // 从前往后存放相同的字符 最后一位不一定属于公共前缀
        int l = -1;
        for(int i = 0; i < len; i ++){       // 从字符串第一位依次比较
            a += s[0][i];                   // 把第一个字符串的第i个字符存到a[i]中用于与后面的比较
            for (int j = 1; j < m; j ++)
                if (a[i] != s[j][i]){
                    l = i;                  // 把出现不同的位数存到l中
                    break;
                }
            if (l != -1) break;             // 已经知道前缀的位数 后面的没必要判断
        }
        if (l == -1)                        // 说明没出现过a[i] != s[j][i] a中的字符都是公共前缀
            for (int i = len - 1; i >= 0; i --)  // 因为翻转过 倒序输出
            cout << a[i];
        else
            for (int i = l - 1; i >= 0; i --)    // a的第l位字符不是公共前缀 l之前的字符都是
                cout << a[i];
        cout << endl;
    }
    return 0;
}

笔者认为不用在意本题的输入输出格式要求,简化题目:求输入若干字符串的最长公共字符串后缀!

#include <iostream>
#include <algorithm>
using namespace std;
int main(){
    int n,m;      // m个字符串
    cin>>n;
    m=n+1;
    string s[10];
    while (m--){
        int len = 200;
        for (int i = 0; i < m; i ++){
            cin >> s[i];
            reverse( s[i].begin(), s[i].end() );         // 把每个字符串首尾翻转 变后缀为前缀
            if ( s[i].size() < len) 
			len = s[i].size();               // 取所有字符串中最短长度作为len
        }
        string a;                           // 从前往后存放相同的字符 最后一位不一定属于公共前缀
        int l = -1;
        for(int i = 0; i < len; i ++){       // 从字符串第一位依次比较
            a += s[0][i];                   // 把第一个字符串的第i个字符存到a[i]中用于与后面的比较
            for (int j = 1; j < m; j ++)
                if (a[i] != s[j][i]){
                    l = i;                  // 把出现不同的位数存到l中
                    break;
                }
            if (l != -1) break;             // 已经知道前缀的位数 后面的没必要判断
        }
        if (l == -1)                        // 说明没出现过a[i] != s[j][i] a中的字符都是公共前缀
            for (int i = len - 1; i >= 0; i --)  // 因为翻转过 倒序输出
            cout << a[i];
        else
            for (int i = l - 1; i >= 0; i --)    // a的第l位字符不是公共前缀 l之前的字符都是
                cout << a[i];
    break;
    }
}

笔者认为要理解核心代码,再次简化题目:求输入若干字符串的最长公共字符串前缀!

#include <iostream>
using namespace std;
int main(){
    int m,n;
    string s[10];
    cin>>n;
    m=n+1;
    while(m--){
        int len=200;
        for(int i=0;i<m;i++){
            cin>>s[i];
            if(s[i].size()<len)
            len=s[i].size();
        }
        int flag=-1;
        string a;
        for(int i=0;i<len;i++){
            a+=s[0][i];
            for(int j=1;j<m;j++)
                if(a[i]!=s[j][i]){
                    flag=i;
                    break;
                }
                if(flag!=-1)
                break;
            }
        if(flag=-1)
            for(int i=0;i<len;i++)
            cout<<a[i];
        else 
            for(int i=0;i<flag;i++)
                cout<<a[i];
        break;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

再沉淀一年!

本人高校大学生,谢谢你的激励

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

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

打赏作者

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

抵扣说明:

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

余额充值