zoukankan      html  css  js  c++  java
  • C语言程序设计之字符串处理

    C语言程序设计-字符串处理

    第一题:回文数判断

    问题描述】
    回文是正读和倒读都一样的句子。读入一个最大长度不超过50个字符的句子,判断其是否是回文。
    【输入形式】
    输入一个最大长度不超过50个字符的句子
    【输出形式】
    Yes/No
    【输入样例】
    abcba
    【输出样例】
    Yes

    【样例说明】
    输入abcba,判断出它是回文。

    #include <stdio.h>
    #include <stdlib.h>
    #include<string.h>
    int main()
    {
        char str[50];
        int i,j,n;
        gets(str);
        //printf("%s",str);
        n = strlen(str);
        for(i=0,j=n-1;i<j;i++,j--){
            if(str[i] != str[j])
                break;
        }
        if(i<j){
            printf("No");
        }else{
            printf("Yes");
        }
        return 0;
    }
    

    解释:

    基本思路就是遍历字符数组,从前往后与从后往前的字符进行的对比;

    结束条件是字符不相等时,跳出循环;

    判断i与j的大小关系即可;

    第二题:求两个字符串的差集

    问题描述】要求计算A-B。A和B都是字符串 —即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串A-B。

    【输入形式】输入在2行中,先后给出字符串A和B。两字符串的长度都不超过104,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束。

    【输出形式】

    在一行中打印出A-B的结果字符串,如果 A-B为空串,则打印一空行。

    【样例输入】

    I love GPLT! It's a fun game!

    aeiou

    【样例输出】

    I lv GPLT! It's fn gm!

    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
        char str1[1001];
        char str2[1001];
        char ch[1001];
        int i,count=0;
    
        gets(str1);
        gets(str2);
        int n=strlen(str1);
        for(i=0;i<n;i++)
        {
            //如果str1中的不在str2中,则存储
            if(strchr(str2,str1[i])==NULL)
                ch[count++]=str1[i];
        }
        printf("%s",ch);
    
        return 0;
    }
    

    解释:

    首先定义了两个字符串;

    判断长的字符数组在短的字符数组中是否存在;

    我们使用的函数时strchr,如果没有找到,则返回NUll;

    所以我们可以写成strchr(str2,str1[i])==NULL;把没有找到字符(即不重复的字符)

    保存到新的数组中,数字下标自加;

    最后输出新的数组。

    第三题:字母顺序数字逆序

    【问题描述】输入任意的由字母和数字组成的字串,将其中字母直接输出,数字逆序输出S6.7。

    【输入形式】任意的由字母和数字组成的字串,#结束,中间没有空格。

    【输出形式】将其中字母直接输出,数字逆序输出,不含#。

    【样例输入】number345reverse#
    【样例输出】numberreverse543

    /*
     * 1.定位数字
     * 2.逆序数字--S1
     * 3.S1放在字符最后
     * 4.输出
     * */
    #include <stdio.h>
    #include "string.h"
    #define N 10001
    int main()
    {
        char str1[1001],c;
    //    gets(str1);
        //输入字符串
        int index ;
        for (index = 0; index <N-1&&(c=getchar()) !='#'; ++index)
        {
            str1[index] =c;
        }
        str1[index]='';
        //定义三个字符数组
        char count_str[1001];
        char count_int[1001];
        char count_re[1001];
    
        int  num=0;
        int n = strlen(str1);
        //输出字符
        for (int i = 0; i < n; ++i)
        {
            if (str1[i]>=';' &&str1[i]<='z')
            {
                count_str[num++]=str1[i];
            }
        }
    
        //判断数字48-57
        int k=0;
        for (int i = 0; i < n; ++i)
        {
            if (str1[i]>=48 && str1[i]<=57)
            {
                count_int[k++]=str1[i];
            }
        }
        //数字反转
        int m=strlen(count_int);
        int b=0;
        for (int i = m-1; i >=0 ; i--)
        {
            count_re[b++]=count_int[i];
        }
    
    //    puts(count_str);
    //    puts(count_int);
    //    puts(count_re);
        puts(strcat(count_str,count_re));
        return 0;
    }
    

    解释:

    首先需要明确字符串需要一个数组,数字一个数组,逆转的数字一个数组;

    首先提取字符串,根据字符的ASCII码设置范围来确定我们需要的字符;

    这里的起始点为什么是";",按理说应该是"a"-"z"的,但是在测试用例里面是有";";

    老话说的好:既然不能改变,那么只能默默接受;

    然后将符合条件的字符存到数组中;

    同理数字也是一样;

    数字反转只需要在数组中从后往前输出即可;

    使用strcat连接两个数组即可。

    第四题:整数转R进制数

    问题描述】键盘输入任一个大于等于0的整数,输出R进制表示的字符串
    【输入形式】

    两个空格隔开的整数, 一个是>=0的 整数,一个整数是R,(2<=R<=16)
    【输出形式】

    R进制字符串
    【样例输入1】

    29 2

    【样例输出1】

    11101

    【样例输入】

    29 16

    【样例输出】

    1D

    #include <stdio.h>
    #define N 20
    #include "string.h"
    int main() {
        int n,m;
        scanf("%d%d",&n,&m);
    
        int jz[N];
        //元素个数
        int i=0;
        while (n!=0){
            //将余数存到数组中,迭代n,n==0时输出;
            jz[i++]=n%m;
            n=n/m;
            }
        //后面取元素判断是否<10;
        for (int j = i-1; j>=0; j--) {
            int k=jz[j];
            if (k<10) printf("%d",k);
            else printf("%c",k+55);
        }
    
        return 0;
    }
    

    解释:

    首先需要知道进制转换的原理:

    除R取余,然后再逆取余数,如图所示;

    image-20201118170721686

    将余数保存到数组中,再从后往前输出即可得出进制数;

    但是我们需要判断元素的大小,如果大于/小于10;需要做相应的判断处理;

    这里我们小于10处理,小于10输出,否则将字符+55;

    因为16进制,+55正好是在大写字符的范围中,10+55-->65(A)。

    可能会问怎么知道数组中的元素个数,这个就是i变量的作用,相当于计数器。

    第五题:字符串基本操作

    编写一个程序,输入一个正整数n和字符串A,对字符串A作如下处理:

    • 去掉重复的字符
    • 去掉所有非字母非数字的字符
    • 将字母大小写互换
    • 按照字符的ASCII码从大到小排序

    最后在同一行里输出n个处理后的字符串A

    【输入形式】

    • 输入正整数n和字符串A,0<n<10,A长度小于80,输入以回车结束

    【输出形式】

    • 输出结果为目标字符串
    • 输出后面无换行符

    【样例输入】

    2 abcd123
    

    【样例输出】

    DCBA321DCBA321
    
    #include <stdio.h>
    #include "string.h"
    #define N 10000
    int main() {
        int n;
        scanf("%d",&n);
        char str[N];
        char str2[N];
        char str3[N];
        fgets(str, 100, stdin);
        int len = strlen(str);
        int count=0;
        //处理重复字符串
        for (int i = 0; i < len; ++i) {
            int index=0;
            for (int j = 0; j < i; ++j) {
                if (str[i]==str[j]){
                    index=1;
                }
            }
    
            if (index==0){
                str2[count++]=str[i];
            }
        }
    //    去掉所有去掉所有非字母非数字的字符
        int k=0;
        int len2 = strlen(str2);
        for (int i = 0; i <len2 ; ++i) {
            if ((str2[i]>='A' && str2[i]<='Z' )||(str2[i]>='a' && str2[i]<='z')||(str2[i]>='0'&&str2[i]<='9')){
                //大小写互换
                if ((str2[i]>='A' && str2[i]<='Z' )||(str2[i]>='a' && str2[i]<='z')){
                        str2[i] ^=32;
                }
                str3[k++]=str2[i];
            }
        }
    //    puts(str2);
    //    puts(str3);
        //通过冒泡排序进行由大到小
        int len3 = strlen(str3);
        for (int i=0;i<len3-1;i++)
            for (int j=0;j<len3-i-1;j++)
            {
                if (str3[j]<str3[j+1]) // 这里是从大到小排序,如果是从小到大排序,只需将“<”换成“>”
                {
                    int temp;
                    temp=str3[j];
                    str3[j]=str3[j+1];
                    str3[j+1]=temp;
                }
            }
        char str4[N];
        int num=0;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j <len3 ; ++j) {
                str4[num++]=str3[j];
            }
        }
        puts(str4);
        return 0;
    }
    
    

    解释:

    首先去掉重复的字符:

    这里我们采用的是二层循环,意思是将字符串中的第一个字符与本身所有的字符进行对比;

    定义一个记录变量index并初始为0-->表示没有相同的字符,如果有相同的,index=1;

    在第一层循环里判断index,若index=0;则将该字符存到新的数组中。

    for (int i = 0; i < len; ++i) {
            int index=0;
            for (int j = 0; j < i; ++j) {
                if (str[i]==str[j]){
                    index=1;
                }
            }
    
            if (index==0){
                str2[count++]=str[i];
            }
        }
    

    第二步:去掉所有非字母非数字的字符与将字母大小写互换整合

    这个判断字符ASCII的范围即可;在筛选出符合的的字符后在判断是否为大小写:

    转换为大小写的骚操作是网上的大佬所写,大体意思是:进行异或操作,具体链接放到博文结尾。

    for (int i = 0; i <len2 ; ++i) {
            if ((str2[i]>='A' && str2[i]<='Z' )||(str2[i]>='a' && str2[i]<='z')||(str2[i]>='0'&&str2[i]<='9')){
                //大小写互换
                if ((str2[i]>='A' && str2[i]<='Z' )||(str2[i]>='a' && str2[i]<='z')){
                        str2[i] ^=32;
                }
                str3[k++]=str2[i];
            }
        }
    

    第三步:按照字符的ASCII码从大到小排序

    这里采用的是数组中的冒泡排序,不多解释,如果不理解的话看前面博客:

    https://www.cnblogs.com/xbhog/p/11741079.html

    for (int i=0;i<len3-1;i++)
            for (int j=0;j<len3-i-1;j++)
            {
                if (str3[j]<str3[j+1]) // 这里是从大到小排序,如果是从小到大排序,只需将“<”换成“>”
                {
                    int temp;
                    temp=str3[j];
                    str3[j]=str3[j+1];
                    str3[j+1]=temp;
                }
            }
    

    最后:由题意可知需要输出n次并不换行;

    然后再循环内遍历字符存到新的数组中。

    for (int i = 0; i < n; ++i) {
            for (int j = 0; j <len3 ; ++j) {
                str4[num++]=str3[j];
            }
        }
    

    总结:

    上述题目的解不是唯一,例题中的解是我所理解并运行成功的,如果有不对的地方,欢迎指出。

    关于大小写的转换博客来链接:https://blog.csdn.net/zkx981105/article/details/78525672

  • 相关阅读:
    Java应用程序的运行机制,以及JDK,JRE,JVM
    正则表达式练习题
    正则表达式
    转:DOM操作
    jQuery 遍历
    转:把一个对象赋值给另一个对象会指向同一个内存地址
    sql 语句的先后执行顺序
    数据结构时间复杂度进阶篇
    数据结构时间复杂度基础篇
    UML图中类之间的关系:依赖,泛化,关联,聚合,组合,实现(转)
  • 原文地址:https://www.cnblogs.com/xbhog/p/14001460.html
Copyright © 2011-2022 走看看