美文网首页《算法图解》学习笔记算法笔记
《算法笔记》3.6小节——入门模拟->字符串处理

《算法笔记》3.6小节——入门模拟->字符串处理

作者: 木子李_0961 | 来源:发表于2020-04-07 11:13 被阅读0次

    @[TOC]

    100000580 《算法笔记》3.6小节——入门模拟->字符串处理

    来自 http://codeup.cn/contest.php?page=6

    讲解

    讲解

    例题

    Codeup 5901见习题

    PAT B 1009 说反话 (20 分)

    来自
    https://pintia.cn/problem-sets/994805260223102976/problems/994805314941992960

    题析:主要是输入时候用二维字符数组接收一行字符串,需要注意
    PAT单点测试不需要用gets()
    还有法二见:
    https://blog.csdn.net/xsj_blog/article/details/51992540

    
    //1009说反话
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int main()
    {
        char str[85][85];
        int count=0;
        while(scanf("%s",str[count]) != EOF)
        {
            count++;
        }
        for(int i=count-1;i>=0;i--)
        {
            printf("%s",str[i]);
            if(i>0) printf(" ");//注意空格条件,最后一个但此后面没有空格,否则出错
        }
        printf("\n");
        return 0;   
    } 
    
    /*
    注意:在黑框中手动输入时,系统并不知道什么时候到达了所谓的“文件末尾“,
    因此需要用< Ctrl + Z >组合键,
    然后按< Enter >键的方式来告诉系统已经到了 EOF,这样系统才会结束 while
    */
    

    练习题:

    1785 Problem A 字符串连接

    来自 http://codeup.cn/contest.php?cid=100000580

    //1785ProblemA字符串连接
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int main()
    {
        char str1[105];
        char str2[105];
        char str[315];
        while(scanf("%s%s",str1, str2)!=EOF)
        {
            int len1=strlen(str1);
            int len2=strlen(str2);
            int count=0;
            //略简洁 
            for(int i=0;i<len1+len2;i++)
            {
                if(i<len1)
                    str[i]=str1[i];
                else
                    str[i]=str2[i-len1];
            }
            //略繁琐
            /* 
            for(int i=0;i<len1;i++)
            {
                str[count++] = str1[i];
            }
            for(int j=0;j<len2;j++)
            {
                str[count++] = str2[j];
            }
     
            for(int k=0;k<count;k++)
            {
                printf("%c",str[k]);
            }
            */ 
            str[len1+len2]='\0';//字符串结尾需加结束符号,否则报错50% 
            printf("%s\n",str);
            
        //  printf("\n");
        }
        return 0;
    }
    
    

    1805 Problem B 首字母大写

    来自 http://codeup.cn/contest.php?cid=100000580

    题析:
    通用解法,多点测试用一维字符数组,然后转存二位字符数组,用row/column行列指针来控制下标,相应改变字符串即可。
    附大佬解法:
    https://blog.csdn.net/qq_40073459/article/details/86559451

    //1805ProblemB首字母大写
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int main()
    {
        char str[105];
        while(gets(str) != NULL)
        {
            int lens = strlen(str);
            char string[105][105]={};//若不初始化为空则会影响到下一组测试 
            int row=0,column=0;
            for(int i=0;i<lens;i++)//str转移到二维字符数组string中 
            {
                if(str[i] != ' '&&str[i]!='\t'&&str[i]!='\r'&&str[i]!='\n')
                {
                    string[row][column++] = str[i];
                }
                else
                {
                    string[row++][column]='\0';
                    column=0;
                }
            }
            for(int i=0;i<=row;i++)
            {
                if(string[i][0]>='a' && string[i][0]<='z')
                {
                    string[i][0] -= 32;//相差32
            //      string[i][0] = string[i][0]-'a'+'A'; //该语句导致错误50%,虽然不知道为啥 
                }
            }
            
            for(int i=0;i<=row;i++)
            {
                if(i<row)
                    printf("%s ",string[i]);
                else
                    printf("%s",string[i]);
            }
            printf("\n");
        //  getchar();
        }
        return 0;
    }
    

    1808 Problem C 字符串的查找删除

    来自 http://codeup.cn/contest.php?cid=100000580
    题析:题目有些绕,注意:
    Gets()的用法
    母串子串比较过程的模拟(特别是指针的动态变化),详见注释

    //1808ProblemC字符串的查找删除 
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    bool compare(char a,char b)//将大小写相同的情况都包括进去的字符比较
    {//简单粗暴的吧子串和母串的字符进行比较,而不必改变各自的值
        if(a>='A'&&a<='Z')
        {
            a=a-'A'+'a';    
        }
        if(b>='A'&&b<='Z')
        {
            b=b-'A'+'a';    
        }
        if(a==b)
            return 1;
        else
            return 0;
    } 
    
    char substr[1005];//子串字符数组,注意申请足够大
    char str[1005];
    int main()
    {
        int i,j;
        gets(substr);
        int sublen = strlen(substr);
        /*//转换为compare()函数更高效
        for(i=0;i<sublen;i++)//待删除字符串一律变成小写,tolower 
        {
            if(substr[i]>='A'&&substr[i]<='Z')
                substr[i] = substr[i] - 'A' + 'a';
        }
        */
        while(gets(str) != NULL)//输入母字符串 
        {
    
            int len = strlen(str);
            //字符串比较
            i=0;j=0;
            while(i<sublen&&j<len)
            {
                if(compare(substr[i],str[j]))//若当前指针字符相等,则指针后移
                {
                    i++;
                    j++;
                    //子串遍历完,说明母串中有一个匹配的,则除了移动指针,子串指针应重置
                    if(i==sublen)
                        i=0;    
                }
                else//字符串不匹配,则打印母字符串不匹配部分,并且指针重新计数
                {
                    j = j-i+1;//不匹配的话,母串指针跳过匹配段向后
                    if(str[j-1] != ' ')//打印前一项 
                        printf("%c",str[j-1]);  
                    i=0;//子串指针重置
                }   
            }   
            if(j==len) //一行结束换行
                printf("\n");
        } 
    
        return 0;
    }
    
    
    

    1962 Problem D 单词替换

    来自 http://codeup.cn/contest.php?cid=100000580

    //1962ProblemD单词替换
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int main()
    {
        char s[1010];
        char str[105][105];
        char a[105],b[105];
        while(gets(s) != NULL)
        {   
            int lens,lena,lenb;
            int i=0,j,row=0,column=0;
            lens=strlen(s);
            
            for(i=0;i<=lens;i++)//将输入母串转换为二维数组存储 
            {
                if(s[i]!=' '||i==lens)
                {
                    str[row][column++]=s[i];
                }
                if(s[i]==' ')
                {
                    str[row++][column]='\0';
                    column=0;
                }   
            }
        //  scanf("%s",a);
        //  scanf("%s",b);
            gets(a);
            gets(b);        
            for(i=0;i<=row;i++)
            {
                if(strcmp(str[i],a) == 0)//母串中匹配到子串a,用b替换 
                {
                    printf("%s",b);
                //  strcpy(str[i],b);
                }
                else
                    printf("%s",str[i]);
                if(i<row)
                    printf(" ");
                else
                    printf("\n");
            }
            
        }
        getchar();  
        return 0;
    }
    

    1963 Problem E 字符串去特定字符

    来自 http://codeup.cn/contest.php?cid=100000580

    题析:见解析
    //1963ProblemE字符串去特定字符
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int main()
    {
        char s[100005],c;
    //  while(scanf("%s %c",s,&c))//单点,不合题意 
        while(gets(s) != NULL)//多点测试 
        {
            c=getchar();//输入 字符 两种方法均可 
            //scanf("%c",&c); 
            int len = strlen(s);
            for(int i=0;i<len;i++)
            {
                if(s[i]!=c)//不匹配到删除字符则打印输出 
                    printf("%c",s[i]);
            }
            printf("\n");
            getchar();//不加getchar()出错%50,?? 大概影响下一次gets(),毕竟是换行符 
        }
        return 0;
    }
    
    
    

    1967 Problem F 数组逆置

    来自 http://codeup.cn/contest.php?cid=100000580
    题析:真 水题
    注意输入的字符串可能会有空格 get() gets() 与 scanf()区别

    //1967ProblemF数组逆置 
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int main()
    {
        char str[205];
        while(gets(str) != NULL)//注意输入的字符串可能会有空格
        {
            int len = strlen(str);
            for(int i=len-1;i>=0;i--)
            {
                printf("%c",str[i]);
            }
            printf("\n");
        }
        return 0;
    }
    
    

    2025 Problem G 比较字符串

    来自 http://codeup.cn/contest.php?cid=100000580

    题析:简单题,注意cstring头文件和strlen与char str[]的配合应用

    //2025ProblemG比较字符串
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int main()
    {
        char str1[55],str2[55];
        int len1,len2;
        int m;
        scanf("%d",&m);
        while(m--)//多点测试 
        {
            scanf("%s%s",str1,str2);
            len1 = strlen(str1);
            len2 = strlen(str2);
            if(len1 == len2)
            {
                printf("%s is equal long to %s\n",str1,str2);
            }
            else if(len1>len2)
            {
                printf("%s is longer than %s\n",str1,str2);
            }
            else
                printf("%s is shorter than %s\n",str1,str2);
        }
        
        return 0;
    }
    
    
    

    2064 Problem H 编排字符串

    来自 http://codeup.cn/contest.php?cid=100000580

    题析:
    数组下标的处理比较繁琐,具体见注释
    将字符串计数与输出指针分割开来,并将字符数4作为分界条件

    //2064ProblemH编排字符串
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int main()
    {
        int m;
        scanf("%d",&m);
        char str[4][25];
        int i,j,count=0;
        while(m--)//多点测试 
        {
            scanf("%s",str[count%4]);//输入字符串并存入数组,多出4个则覆盖 
            i=count;//i用来控制输出下标 
            if(count<4)//字符串少于4个时,上限用count表示 
            {
                for(j=1;j<=count+1;j++)
                {
                    printf("%d=%s",j,str[i--]);
                
                    if(j==count+1)  
                        printf("\n");
                    else
                        printf(" ");
                }
            }
            else//字符串多于4个时,上限不用count表示 
            {
                for(j=1;j<5;j++)
                {
                    printf("%d=%s",j,str[(i--)%4]);//注意取余 
                    if(j==4)
                        printf("\n");
                    else
                        printf(" ");
                }
            }
            
            count++;//输入字符串计数 
        }
        return 0;
    }
    
    

    5901 Problem I 【字符串】回文串

    来自 http://codeup.cn/contest.php?cid=100000580
    题析:很简单,两头往中间跑,但是scanf()输入时输出超限什么鬼??已解决觉,没加!=EOF,具体机制还是不清楚???
    scanf 和 gets 读取字符串
    来自 http://www.cnblogs.com/qinjunni/archive/2012/03/03/2378323.html

    
    //5901ProblemI【字符串】回文串
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    bool Judge(char str[])
    {
        int len = strlen(str);
        for(int i=0;i<len/2;i++)
        {
            if(str[i]==str[len-i-1])
            {
                continue;
            }
            else
                return 0;
        }
        return 1;
    }
    int main()
    {
        char str[260];
        //while(scanf("%s",str))//输出超限???? 
        //while(gets(str))
        while(scanf("%s",str)!=EOF)//已解决觉,没加!=EOF,具体机制还是不清楚??? 
        {
            if(Judge(str))
            {
                printf("YES\n");
            }
            else
                printf("NO\n");
        //  printf("\n");
        }
        return 0;   
    } 
    

    相关文章

      网友评论

        本文标题:《算法笔记》3.6小节——入门模拟->字符串处理

        本文链接:https://www.haomeiwen.com/subject/muygphtx.html