字符串练习题

——以下例题均来自 《算法竞赛入门经典》

  1. 在Tex中,做双引号的" ",右双引号是" '' "(两个回车左边的).输入一篇包含双引号的文章,你的任务是把它转换成TeX的格式。 样例输入:"To be or not to be,"quoth the Bard,"that is the question". 样例输出:To be or not to be’‘quoth the Bard,``that
    is the question’’

分析: 边读边处理,不需要把字符串完整的保存,选取getchar()。

#include
int main(){
int c,q;                  //注意c在这里是 int 类型
    while((c=getchar)!=EOF){
    	if(c=='"')
    	{
    	printf("%s",q?"``":"''");
    	q=!q;
    	}
    	else
    	printf("%c,c);
    }
    return 0;
}
  1. 把手放在键盘上时,稍不注意就会往右错一位。这样,输入Q会变成输入W。输入一个错位后敲出的字符串(所有字母大写),输出打字员本来想打的字母。保证输入合法,一定是错位之后的字符串。例如输入中不会出现A。
    样例输入:
    O S, GOMR YPFSU/
    样例输出:
    I AM FINE TODAY.

分析: 一种方法是输入字母然后用switch或者if语句判断,但是这样很麻烦,一个较常用的方法是使用常量数组

#include
#include
//常量数组
char s[] = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";
int main()
{
    int i,c;
    while((c=getchar())!=EOF)
    {
        for(i=1;s[i]&&s[i]!=c;i++)
             ;//找到错位后的字符在常量表中的位置
        if(s[i])
        putchar(s[i-1]); //如果找到输出它的前一个字符
        else
        putchar(c);
    }
    return 0;
} 
  1. 回文词和镜像词
    输入一串字符,判断它是否回文词或镜像词。回文词大家都不陌生,比如abba和madam。以下给出镜像词的对应字符。
A E H I J L M O S T U V W X Y Z 8
A 3 H I L J M O 2 T U V W X Y 5 8

输入每行包含一个字符串(不含空白字符),判断是否为回文串和镜像串。

分析: 不包含空白可用scanf输入。使用常量数组

#include
#include
#include
#include

const char* rev="A    3  HIL JM O   2TUVWXY51SE Z  8 ";
const char*msg[]={"not a palindrome","a regular palindrome","a mirrored string","a mirror palindrome"};

//判断镜像函数
char judgemirror(char ch)
{
    if (isalpha(ch)) //如果是字母
        // (ch-'A'是该字母的序号),也就是该字母在常量数组中的序号
        //  返回该字母所对应的镜像
        return rev[ch - 'A']; 
    else
    return rev[ch-'0'+25]; //返回该数字对应的镜像
}

int main()
{ 
    char s[30];
    while(scanf("%s",s)==1)
    {
        int len=strlen(s);
        int p=1,m=1;
        for(int i=0;i<(len+1)>>1;i++) //判断一半
        {
            if(s[i]!=s[len-1-i])
            p=0;//不是回文串
            if(judgemirror(s[i])!=s[len-1-i])
            m=0;//不是镜像
        }
        printf("%s---is %s.\n\n",s,msg[m*2+p]);  //4种组合
    }
    system("pause");
    return 0;
} 
  1. 环状序列 (Uva1584)
    输入一个长度为n,(n<=100)的环状DNA串(只包含A C G T)的一种表示法,输出该环状串的最小表示法。(字典序)例如CTCC的最小表示法是CCCT ,要保持原先环的相对位置。

分析: 像 “ 求n个元素的最小值 ” 一样,用变量ans表示目前为止,字典序最小串在输入串的起始位置,然后不断更新ans。如图所示的DNA环,从0开始,逐次比较。
字符串练习题_第1张图片

#include
#include
//环状串s的表示法p是否比表示法q的字典序小
int judgesmall(char s[],int p,int q)
{
    int n=strlen(s);
    for(int i=0;i<n;i++)
    {
        if(s[(p+i)%n]!=s[(q+i)%n])
        return s[(p+i)%n]<s[(q+i)%n]; 
    }
    return 0; //p表示法 与q表示法相等

}

int main()
{ 
    char s[101];
    int T;
    //输入的字符串个数
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",s);
        int ans=0,n=strlen(s);
        for(int i=1;i<n;i++){
            if(judgesmall(s,i,ans))
                ans=i; //不断更新最小的字符串起始位置
        }
        for(int i=0;i<n;i++)
        putchar(s[(i+ans)%n]);
        putchar('\n');
    }
    return 0;
} 
  1. 得分(UVa1585)
    给出一个由O和X组成的串(长度为1~80),统计得分。每个O的得分为目 前连续出现的O的个数,X的得分为0。 例如,OOXXOXXOOO的得分为1+2+0+0+1+0+0+1+2+3。

分析: 放置一个标记,用来标记是不是第一次不连续出现的O,如果当前字符是X,就说明下一个出现的O,将是第一个出现的不连续O。

#include
#include
int main()
{ 
    char s[81];
    int tot,ans=0;
    scanf("%s",s);
    int firsto=1;//标记,第一次不连续出现的O
    int n=strlen(s);  //不要将这个语句放入for语句,这样会很耗时
    for(int i=0;i<n;i++)
    {
        if(s[i]=='O')
        {
            if(firsto)
            {
                tot=1;
                ans+=tot;
                firsto=0;
            }
            else
            {
                tot++;
                ans += tot;
            }
        }
        else
        {
            firsto=1;
            ans+=0;
        }  
    }
    printf("%d\n",ans);
    return 0;
} 

————————持续更新……

你可能感兴趣的:(刷题练习)