【C语言】【信息学奥赛一本通】【期末复习专题】期末大复习之字符串

字符串是计算机编程中的基本概念之一,涉及到字符串的创建操作查找以及替换等操作,以下是有关字符串的题目以及解析,均出自信息学奥赛一本通

题目难度适中,小白也不用担心,一点一点看,琢磨一下都能懂的

目录

小tips 

以下题目会运用到的知识点

 1.strcmp函数

2.strstr函数 

3.strtok函数 

4.字符串分类函数

1.密码翻译

题目描述

输入

输出

样例输入 复制

样例输出 复制

 源代码

2.石头剪子布 

题目描述

输入

输出

样例输入

样例输出

 源代码

3.连续出现的字符

题目描述

输入

输出

样例输入 复制

样例输出 复制

 源代码

4.最高分数的学生姓名

题目描述

输入

输出

样例输入 复制

样例输出 复制

 源代码

 5.字符串p型编码

题目描述

输入

输出

样例输入 复制

样例输出 复制

 源代码

 6.最长最短单词

题目描述

输入

输出

样例输入 复制

样例输出 复制

提示

源代码

 7.验证子串

题目描述

输入

输出

样例输入 复制

样例输出 复制

 源代码

 8.整理药名

题目描述

输入

输出

样例输入 复制

样例输出 复制

 源代码


小tips 

以下题目会运用到的知识点

1.strcmp函数

2.strstr函数

3.strtok函数

4.tolower,toupper,isupper,islower函数

 如果你已经全部掌握,可以通过目录,直接跳转到题目

1.strcmp函数

strcmp函数是C语言中的一个字符串比较函数,主要用于比较两个以'\0'结尾的字符串。

具体来说,strcmp()函数会比较两个字符串的每一个字符,直到出现不相同的字符,或者到达其中一个字符串的末尾(遇见'\0')。在比较过程中,这个函数会依照ASCII编码值的大小来判断字符的大小。

如果第一个字符串小于第二个字符串,那么strcmp()函数将返回一个负数;如果第一个字符串大于第二个字符串,则返回一个正数;如果两个字符串相等,则返回0。

2.strstr函数 

strstr函数是C语言中的一个字符串搜索函数,主要用于在一个字符串中查找是否含有另一个子串。

具体来说,strstr()函数会返回子串在原字符串中首次出现的位置,如果未找到则返回null。例如,如果需要查找的字符串为"world",而被检索的字符串为"Hello, world!",那么该函数将返回第一次出现"world"的位置,即第7个字符的位置。值得注意的是,返回的是一个指向首次出现位置指针,而非完整的子串

此外,如果需要查找的字符串在原字符串中不存在,则strstr()函数同样会返回NULL。因此在使用此函数进行字符串查找时,通常需要进行NULL检查以避免产生错误。

3.strtok函数 

strtok函数是C语言中的一个字符串分割函数,主要用于将一个字符串按照指定的分隔符分解成多个子串。

具体来说,当首次调用strtok()函数时,需要传入要分割的字符串。如果要继续调用,应将此参数设置为NULL,以便从上次分割的位置继续进行分割。而delim参数则是一个包含多个分隔符的字符串,这些字符被用作分隔符,将原字符串分割成多个子串。

值得注意的是,每次成功调用strtok()函数都会返回一个指向被分割出片段的指针。如果在参数s的字符串中没有找到参数delim中包含的分割字符,那么函数就会将该字符改为'\0'字符,并返回指向下一个子串的指针。如果所有的子串都已经被查找完毕,那么函数就会返回NULL。
 

前三个都需要引用头文件<string.h> 

下面需要引用头文件<ctype.h>

4.字符串分类函数

以下图片出自C语言——字符串函数(七千字详解)_c语言字符串函数-CSDN博客

1.密码翻译

题目描述

在情报传递过程中,为了防止情报被截获,往往需要对情报用一定的方式加密,简单的加密算法虽然不足以完全避免情报被破译,但仍然能防止情报被轻易的识别。我们给出一种最简的的加密方法,对给定的一个字符串,把其中从a-y,A-Y的字母用其后继字母替代,把z和Z用a和A替代,其他非字母字符不变,则可得到一个简单的加密字符串。

输入

输入一行,包含一个字符串,长度小于80个字符。

输出

输出每行字符串的加密字符串。

样例输入 
Hello! How are you!
样例输出 
Ifmmp! Ipx bsf zpv!
 源代码
#include<stdio.h>
#include<string.h>
int main()
{
    char arr[80];
    gets(arr);
    int len=strlen(arr);
    int i;
    for(i=0;i<len;i++)
    {
//对与‘z’之前的数字一般处理,简单加1,也就是往后移动一位
        if(arr[i]>='a'&&arr[i]<='y'||arr[i]>='A'&&arr[i]<='Y')
        {
            arr[i]+=1;
        }
//对于'z'单独处理,减25,变成'a'
        else if(arr[i]=='Z'||arr[i]=='z')
        {
            arr[i]-=25;
        }
        else
        arr[i]=arr[i];
    }
    puts(arr);
}

2.石头剪子布 

题目描述

石头剪子布,是一种猜拳游戏。起源于中国,然后传到日本、朝鲜等地,随着亚欧贸易的不断发展它传到了欧洲,到了近现代逐渐风靡世界。简单明了的规则,使得石头剪子布没有任何规则漏洞可钻,单次玩法比拼运气,多回合玩法比拼心理博弈,使得石头剪子布这个古老的游戏同时用于“意外”与“技术”两种特性,深受世界人民喜爱。
游戏规则:石头打剪刀,布包石头,剪刀剪布。
现在,需要你写一个程序来判断石头剪子布游戏的结果。

输入

第一行是一个整数N,表示一共进行了N次游戏。1≤N≤100。
接下来N行的每一行包括两个字符串,表示游戏参与者Player1,Player2的选择(石头、剪子或者是布): S1S2
字符串之间以空格隔开S1,S2只可能取值在{"Rock", "Scissors", "Paper"}(大小写敏感)中。

输出

输出包括N行,每一行对应一个胜利者(Player1或者Player2),或者游戏出现平局,则输出Tie。

样例输入
3
Rock Scissors
Paper Paper
Rock Paper
样例输出
Player1
Tie
Player2
 源代码
#include <stdio.h>
#include <string.h>

int main()
{
    int N;
    scanf("%d", &N);
    char S1[10], S2[10];

    for (int i = 0; i < N; i++)
    {
        scanf("%s %s", S1, S2);

        if (strcmp(S1, S2) == 0)//若两个人出的一样就是平局
        {
            printf("Tie\n");
        }
        else if ((strcmp(S1, "Rock") == 0 && strcmp(S2, "Scissors") == 0) ||(strcmp(S1, "Scissors") == 0 && strcmp(S2, "Paper") == 0) ||(strcmp(S1, "Paper") == 0 && strcmp(S2, "Rock") == 0))//剩下的情况列举就行了
        {
            printf("Player1\n");
        }
        else
        {
            printf("Player2\n");
        }
    }

    return 0;
}

3.连续出现的字符

题目描述

给定一个字符串,在字符串中找到第一个连续出现至少k次的字符。

输入

第一行包含一个正整数k,表示至少需要连续出现的次数。1 ≤ k ≤ 1000。
第二行包含需要查找的字符串。字符串长度在1到2500之间,且不包含任何空白符。

输出

若存在连续出现至少k次的字符,输出该字符;否则输出No。

样例输入 
3
abcccaaab
样例输出 
c
 源代码
#include<stdio.h>
#include<string.h>
int main()
{
	int k;
	scanf("%d",&k);
    char arr[2500];
    scanf("%s",arr);
    int len=strlen(arr);
    int i;
    int count=1;
    char token;
    int flag=0;
    for(i=1;i<len;i++)
    {
        if(arr[i]==arr[i-1])//若相等则继续加
        {
            ++count;
            if(count==k)//直到等于规定的k值之后,退出
            {
            	token=arr[i];
            	flag=1;
            	break;
			}
        }
        else//若不相等则更新次数
        {
            count=1;
        }
    }
    if(flag==0)
    {
        printf("No");
        return 0;
    }
    else
    printf("%c",token);
}

4.最高分数的学生姓名

题目描述

输入学生的人数,然后再输入每位学生的分数和姓名,求获得最高分数的学生的姓名。

输入

第一行输入一个正整数N(N <= 100),表示学生人数。接着输入N行,每行格式如下:
分数 姓名
分数是一个非负整数,且小于等于100;
姓名为一个连续的字符串,中间没有空格,长度不超过20。
数据保证最高分只有一位同学。

输出

获得最高分数同学的姓名。

样例输入 
5
87 lilei
99 hanmeimei
97 lily
96 lucy
77 jim
样例输出 
hanmeimei
 源代码
#include<stdio.h>
#include<string.h>
int main()
{
    int N;
    scanf("%d",&N);
    char max_name[20];
    int max=0;
    while(N--)
    {
        int a;
        char people[20];
        scanf("%d %s",&a,people);
        if(a>max)//若大于max,就记录并保持这个字符串
        {
            max=a;
            strcpy(max_name,people);
        }
    }
    printf("%s",max_name);
}

 

 5.字符串p型编码

题目描述

给定一个完全由数字字符(‘0’,‘1’,‘2’,…,‘9’)构成的字符串str,请写出str的p型编码串。例如:字符串122344111可被描述为"1个1、2个2、1个3、2个4、3个1",因此我们说122344111的p型编码串为1122132431;类似的道理,编码串101可以用来描述1111111111;00000000000可描述为"11个0",因此它的p型编码串即为110;100200300可描述为"1个1、2个 0、1个2、2个0、1个3、2个0",因此它的p型编码串为112012201320。

输入

输入仅一行,包含字符串str。每一行字符串最多包含1000个数字字符。

输出

输出该字符串对应的p型编码串。

样例输入 
122344111
样例输出 
1122132431
 源代码
#include<stdio.h>
#include<string.h>
int main()
{
    char str[1000];
    gets(str);
    int len=strlen(str);
    int i;
    int count=1;
    for(i=1;i<len;i++)
    {
        if(str[i]!=str[i-1])//若前后字母不相等,次数更新
        {
            printf("%d%d",count,str[i-1]-'0');//记得一定要减去'0',不然会输出神奇数字
            count=1;
        }
        else
        {
            count++;
        }
    }
//输出最后一个数字出现次数
    printf("%d%d",count,str[len-1]-'0');
}

 6.最长最短单词

题目描述

输入1行句子(不多于200个单词,每个单词长度不超过100),只包含字母、空格和逗号。单词由至少一个连续的字母构成,空格和逗号都是单词间的间隔。
试输出第1个最长的单词和第1个最短单词。

输入

一行句子。

输出

第1行,第一个最长的单词。
第2行,第一个最短的单词。

样例输入 
I am studying Programming language C in Peking University
样例输出 
Programming
I
提示

如果所有单词长度相同,那么第一个单词既是最长单词也是最短单词。

源代码
#include<stdio.h>
#include<string.h>
int main()
{
    char arr[20000];
    fgets(arr,20000,stdin);
    char *maxlen,*minlen;
    int max=0,min=100;
//这里注意strtok函数的运用
    for(char *token=strtok(arr,", ");token!=NULL;token=strtok(NULL,", "))
    {
        int len=strlen(token);
        if(len>max)//将最长的单词保存
        {
            maxlen=token;
            max=len;
        }
        if(len<min)//将最短单词保存
        {
            minlen=token;
            min=len;
        }
    }
    printf("%s\n%s",maxlen,minlen);
}

 7.验证子串

题目描述

输入两个字符串,验证其中一个串是否为另一个串的子串。

输入

输入两个字符串, 每个字符串占一行,长度不超过200且不含空格。

输出

若第一个串s1是第二个串s2的子串,则输出(s1) is substring of (s2)
否则,若第二个串s2是第一个串s1的子串,输出(s2) is substring of (s1)
否则,输出 No substring。

样例输入 
abc
dddncabca
样例输出 
abc is substring of dddncabca
 源代码
#include<stdio.h>
#include<string.h>
int main()
{
    char str1[200],str2[200];
    gets(str1);
    gets(str2);
//下面就是strstr函数的运用,注意strstr两个参数意味着什么
    if(strstr(str1,str2))
    {
        printf("%s is substring of %s",str2,str1);
        return 0;
    }
    else if(strstr(str2,str1))
    {
        printf("%s is substring of %s",str1,str2);
        return 0;
    }
//若都返回空指针,则谁也不是谁的子串
    else if(strstr(str1,str2)==NULL&&strstr(str1,str2)==NULL)
    {
        printf("No substring");
    }
}

 8.整理药名

题目描述

医生在书写药品名的时候经常不注意大小写,格式比较混乱。现要求你写一个程序将医生书写混乱的药品名整理成统一规范的格式,即药品名的第一个字符如果是字母要大写,其他字母小写。如将ASPIRIN、aspirin整理成Aspirin。

输入

第一行一个数字n,表示有n个药品名要整理,n不超过100。
接下来n行,每行一个单词,长度不超过20,表示医生手书的药品名。药品名由字母、数字和-组成。

输出

n行,每行一个单词,对应输入的药品名的规范写法。

样例输入 
4
AspiRin
cisapride
2-PENICILLIN
Cefradine-6
样例输出 
Aspirin
Cisapride
2-penicillin
Cefradine-6
 源代码
#include<stdio.h>
#include<ctype.h>
#include<string.h>
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        char str[21];
        scanf("%s",str);
        int i;
//将首位变成大写字母
        str[0]=toupper(str[0]);
//其他的都变成小写字母
        for(int j=1;j<strlen(str);j++)
        {
            str[j]=tolower(str[j]);
        }
        printf("%s\n",str);
    }
}

结尾

刚开始做的时候会遇见很多困难,但请坚持,一切都会变好的

还是那句话:记得坚持做题!!!

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值