刷紫书第三章例题(例题3-1,3-2,3-3)

来源:互联网 发布:中国网络暴力数据 编辑:程序博客网 时间:2024/05/22 01:55

本文章主要参考刘汝佳著作《算法竞赛入门经典》(第2版)

例题3-1 TEX Quotes UVA - 272

TEX is a typesetting language developed by Donald Knuth. It takes source text together with a few
typesetting instructions and produces, one hopes, a beautiful document. Beautiful documents use “
and ” to delimit quotations, rather than the mundane ” which is what is provided by most keyboards.
Keyboards typically do not have an oriented double-quote, but they do have a left-single-quote and
a right-single-quote '. Check your keyboard now to locate the left-single-quote key
(sometimes
called the “backquote key”) and the right-single-quote key ’ (sometimes called the “apostrophe” or
just “quote”). Be careful not to confuse the left-single-quote with the “backslash” key \. TEX lets
the user type two left-single-quotes `` to create a left-double-quote “ and two right-single-quotes ''
to create a right-double-quote ”. Most typists, however, are accustomed to delimiting their quotations
with the un-oriented double-quote ".
If the source contained
"To be or not to be," quoth the bard, "that is the question."
then the typeset document produced by TEX would not contain the desired form:
“To be or not to be,” quoth the bard, “that is the question.”
In order to produce the desired form, the source file must contain the sequence:
``To be or not to be,'' quoth the bard, ``that is the question.''
You are to write a program which converts text containing double-quote (") characters into text
that is identical except that double-quotes have been replaced by the two-character sequences required
by TEX for delimiting quotations with oriented double-quotes. The double-quote (") characters should
be replaced appropriately by either `` if the " opens a quotation and by '' if the " closes a quotation.
Notice that the question of nested quotations does not arise: The first " must be replaced by ``, the
next by '', the next by ``, the next by '', the next by ``, the next by '', and so on.
Input
Input will consist of several lines of text containing an even number of double-quote (") characters.
Input is ended with an end-of-file character.
Output
The text must be output exactly as it was input except that:
• the first " in each pair is replaced by two
characters: and
• the second " in each pair is replaced by two ' characters: ''.
Sample Input
"To be or not to be," quoth the Bard, "that
is the question".
The programming contestant replied: "I must disagree.
To `C' or not to `C', that is The Question!"
Sample Output
To be or not to be,” quoth the Bard, that
is the question''.
The programming contestant replied:
I must disagree.
To C' or not toC’, that is The Question!”

【我的思路】

由于存在空格的输入,所以不能用scanf,我选择用gets。
我的Runtime error代码:

#include<iostream>#include<cstring>#include<cstdio>using namespace std;char s[1005][1005];char str[1000];int main(){    int n=0;    int cnt=0;    while(gets(str)!=NULL)    {        strcpy(s[n],str);        s[n++][strlen(str)]='\0';    }    for(int i=0;i<n;i++)    {        for(int j=0;j<strlen(s[i]);j++)        {            if(s[i][j]=='"')            {                cnt++;                if(cnt%2==0)cout<<"''";                else cout<<"``";            }            else cout<<s[i][j];        }        cout<<endl;    }    return 0;}

改成便输入边输出竟然过了!!!!!!!!!!!!

不推荐的AC代码

(虽然AC,但建议不要用gets,该函数存在缓冲区漏洞,在C11标准中已经删除):

#include<iostream>#include<cstring>#include<cstdio>using namespace std;char str[1000];int main(){    int cnt=0;    while(gets(str)!=NULL)    {       for(int j=0;j<strlen(str);j++)        {            if(str[j]=='"')            {                cnt++;                if(cnt%2==0)cout<<"''";                else cout<<"``";            }            else cout<<str[j];        }        cout<<endl;    }    return 0;}

推荐使用下面的代码!!!

(一)书本代码:

#include<cstdio>int main(){    int c;//注意这里的c是int类型的    bool q=true;    while((c=getchar())!=EOF)    {        if(c=='"'){printf("%s",q?"``":"''");q=!q;}        else printf("%c",c);    }    return 0;}

(二)自己代码:

#include<iostream>#include<cstdio>using namespace std;int main(){    int c,cnt=0;    while((c=getchar())!=EOF)    {        if(c=='"')        {            cnt++;            if(cnt%2!=0)                cout<<"``";            else                cout<<"''";        }        else            printf("%c",c);    }    return 0;}

【补充fgets函数】

函数原型:char *fgets(char *buf, int bufsize, FILE *stream)参数:
buf: 字符型指针,指向存储读入数据的缓冲区的地址。
bufsize: 从流中读入bufsize-1个字符
stream : 指向读取的流。
返回值:
当n<=0 时返回NULL,即空指针。
当n=1 时,返回空串”“.
如果读入成功,则返回缓冲区的地址。
如果读入错误或遇到文件结尾(EOF),则返回NULL.

由于C11删除了gets函数,现在使用fgets函数来代替gets函数,要注意的是fgets可以把一行最后的换行符也读进去(如果读到换行符还没读够bufsize-1个字符)。本文章共有三道题目,每道题目都特别给出了fgets版本的代码,在后续题目中对fgets读进换行符会有所体会。

(三)(fgets版AC代码):

#include<cstdio>#include<cstring>int main(){    char str[1005];    int cnt=0;    while(fgets(str,sizeof(str),stdin)!=NULL)    {        bool mark=1;        for(int i=0;i<strlen(str);i++)        {            if(str[i]=='"')            {                cnt++;                if(cnt&1)printf("%s","``");                else printf("%s","''");            }            else putchar(str[i]);        }    }    return 0;}

补充getchar和EOF
C语言中getchar()的返回值类型为什么是int?
正常情况,getchar返回单个字符。但如果getchar()碰到文件结束标志或发生读错误,他必须返回一个EOF。为了区别于正常的字符,只好将EOF定义为负数(-1),因此getchar就设置成了int型。

例题3-2 WERTYU UVA - 10082

这里写图片描述
A common typing error is to place the
hands on the keyboard one row to the
right of the correct position. So ‘Q’ is
typed as ‘W’ and ‘J’ is typed as ‘K’ and
so on. You are to decode a message typed in this manner.
Input
Input consists of several lines of text. Each line may contain digits, spaces, upper case letters (except
Q, A, Z), or punctuation shown above [except back-quote (‘)]. Keys labelled with words [Tab, BackSp,
Control, etc.] are not represented in the input.
Output
You are to replace each letter or punction symbol by the one immediately to its left on the ‘QWERTY’
keyboard shown above. Spaces in the input should be echoed in the output.
Sample Input
O S, GOMR YPFSU/
Sample Output
I AM FINE TODAY.

(一)不推荐的AC代码

(使用了不推荐的gets函数,推荐用下面的第四个代码):

#include<cstdio>#include<map>#include<iostream>#include<cstring>#include<string>using namespace std;int main(){    char s[]="`1234567890-=QWERTYUIOP[]\ASDFGHJKL;'ZXCVBNM,./";    map<char,int>mp;    for(int i=0;i<strlen(s);i++)    {        mp[s[i]]=i;    }    char str[1000];    while(gets(str)!=NULL)    {        for(int i=0;i<strlen(str);i++)        {            if(str[i]==' ')cout<<" ";            else cout<<s[mp[str[i]]-1];        }        cout<<endl;    }    return 0;}

(二)有缺陷的AC的代码

(因不同系统的换行符不一致,这里使用’\n’可以AC,但是不保险):

#include<cstdio>#include<iostream>#include<cstring>using namespace std;int main(){    char s[]="`1234567890-=QWERTYUIOP[]\ASDFGHJKL;'ZXCVBNM,./";    int len=strlen(s);    int c;    while((c=getchar())!=EOF)    {        if(c==' ')cout<<" ";        else if(c=='\n')cout<<endl;        else        {            for(int i=0;i<len;i++)                if(s[i]==c)                    cout<<s[i-1];        }    }    return 0;}

(三)书本代码

(避开不同系统的换行符不一致的问题,非常准确简洁):

#include<cstdio>int main(){    char s[]="`1234567890-=QWERTYUIOP[]\ASDFGHJKL;'ZXCVBNM,./";    int c,i=0;    while((c=getchar())!=EOF)    {        for(i=0;s[i] && s[i]!=c;i++);        if(s[i])putchar(s[i-1]);        else putchar(c);    }    return 0;}

(四)(fgets版):

#include<cstdio>#include<cstring>#include<map>using namespace std;char s[]="`1234567890-=QWERTYUIOP[]\ASDFGHJKL;'ZXCVBNM,./";int main(){    char str[1000];    map<char,int>mp;    for(int i=0;i<strlen(s);i++)        mp[s[i]]=i;    while(fgets(str,1000,stdin)!=NULL)    {        str[strlen(str)-1]='\0';        for(int i=0;i<strlen(str);i++)        {            if(str[i]==' ')putchar(' ');            else putchar(s[mp[str[i]]-1]);        }        putchar('\n');    }    return 0;}

例题3-3 Palindromes UVA - 401

A regular palindrome is a string of numbers or letters that is the same forward as backward. For
example, the string “ABCDEDCBA” is a palindrome because it is the same when the string is read from
left to right as when the string is read from right to left.
A mirrored string is a string for which when each of the elements of the string is changed to its
reverse (if it has a reverse) and the string is read backwards the result is the same as the original string.
For example, the string “3AIAE” is a mirrored string because ‘A’ and ‘I’ are their own reverses, and ‘3’
and ‘E’ are each others’ reverses.
A mirrored palindrome is a string that meets the criteria of a regular palindrome and the criteria
of a mirrored string. The string “ATOYOTA” is a mirrored palindrome because if the string is read
backwards, the string is the same as the original and because if each of the characters is replaced by
its reverse and the result is read backwards, the result is the same as the original string. Of course, ‘A’,
‘T’, ‘O’, and ‘Y’ are all their own reverses.
A list of all valid characters and their reverses is as follows.
这里写图片描述
Note that ‘0’ (zero) and ‘O’ (the letter) are considered the same character and therefore ONLY the
letter ‘O’ is a valid character.
Input
Input consists of strings (one per line) each of which will consist of one to twenty valid characters.
There will be no invalid characters in any of the strings. Your program should read to the end of file.
Output
For each input string, you should print the string starting in column 1 immediately followed by exactly
one of the following strings.
这里写图片描述
Note that the output line is to include the ‘-’s and spacing exactly as shown in the table above and
demonstrated in the Sample Output below.
In addition, after each output line, you must print an empty line.
Sample Input
NOTAPALINDROME
ISAPALINILAPASI
2A3MEAS
ATOYOTA
Sample Output
NOTAPALINDROME – is not a palindrome.
ISAPALINILAPASI – is a regular palindrome.
2A3MEAS – is a mirrored string.
ATOYOTA – is a mirrored palindrome.

【我的思路】

具体思路过程就是下面的代码了,被坑的是起初用cin,cout老是显示presentation error,还有一个坑点是起初理解错了,以为如果一个字符没有reverse就默认为该字符本身,其实不然,其实该字符的reverse是一个不合法字符。

AC代码(一)(建议不要使用cout,cin,不然老是出现presentation error):

#include<cstdio>#include<cstring>using namespace std;const int maxn=25;char s1[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";char s2[]="A***3**HIL*JM*O***2TUVWXY51SE*Z**8*";bool pal(char s[]){    int len=strlen(s);    for(int i=0;i<=(len-1)/2;i++)        if(s[i]!=s[len-1-i]) return false;    return true;}bool mir(char str[]){    int len=strlen(str);    char s[maxn];    strcpy(s,str);    s[len]='\0';    for(int i=0;i<len;i++)    {        for(int j=0;j<strlen(s1);j++)            if(s[i]==s1[j]){s[i]=s2[j];break;}    }    for(int i=0;i<len;i++)        if(s[i]!=str[len-i-1])return false;    return true;}int main(){    char ss[25];    while(scanf("%s",ss)!=EOF)    {        bool flag1=pal(ss);        bool flag2=mir(ss);        if((!flag1) && (!flag2))printf("%s -- is not a palindrome.\n\n",ss);        else if(flag1 && (!flag2))printf("%s -- is a regular palindrome.\n\n",ss);        else if((!flag1) && flag2)printf("%s -- is a mirrored string.\n\n",ss);        else if(flag1 && flag2)printf("%s -- is a mirrored palindrome.\n\n",ss);    }    return 0;}

AC代码(二)(fgets版):

#include<cstdio>#include<cstring>using namespace std;const int maxn=25;char s1[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";char s2[]="A***3**HIL*JM*O***2TUVWXY51SE*Z**8*";bool pal(char s[]){    int len=strlen(s);    for(int i=0;i<=(len-1)/2;i++)        if(s[i]!=s[len-1-i]) return false;    return true;}bool mir(char str[]){    int len=strlen(str);    char s[maxn];    strcpy(s,str);    s[len]='\0';    for(int i=0;i<len;i++)    {        for(int j=0;j<strlen(s1);j++)            if(s[i]==s1[j]){s[i]=s2[j];break;}    }    for(int i=0;i<len;i++)        if(s[i]!=str[len-i-1])return false;    return true;}int main(){    char ss[25];    while(fgets(ss,sizeof(ss),stdin)!=NULL)    {        ss[strlen(ss)-1]='\0';        bool flag1=pal(ss);        bool flag2=mir(ss);        if((!flag1) && (!flag2))printf("%s -- is not a palindrome.\n\n",ss);        else if(flag1 && (!flag2))printf("%s -- is a regular palindrome.\n\n",ss);        else if((!flag1) && flag2)printf("%s -- is a mirrored string.\n\n",ss);        else if(flag1 && flag2)printf("%s -- is a mirrored palindrome.\n\n",ss);    }    return 0;}
原创粉丝点击