算法竞赛入门 (一)语言篇 数组和字符串 2

三、竞赛题目选讲

例题3-2 WERTYU

把手放在键盘上时,稍不注意就会往右错一位。这样,输入Q会变成输入W,输入J会变成输 入K等。输入一个错位后敲出的字符串(所有字母均大写),输出打字员本来想打出的句子。输入保证合法,即一定是错位之后的字符串。例如输入中不会出现大写字母A。

样例输入:
O S, GOMR YPFSU/
样例输出:
I AM FINE TODAY

我的思路:这样的打字员赶紧滚犊子完事

同例题3-1,可以利用 getchar()  一边输入,一边输出。但问题卡在了 如何变换回正确的? switch 或 if 都太麻烦

书的思路:使用常量数组

#include<stdio.h>
 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;
 }

 # 常量数组并不需要指明大小,编译器可以完成计算

 例题3-3 回文词

输入一个字符串,判断它是否为回文串以及镜像串。输入字符串保证不含数字0。所谓 回文串,就是反转以后和原串相同,如abba和madam。所有镜像串,就是左右镜像之后和原

串相同,如2S和3AIAE。注意,并不是每个字符在镜像之后都能得到一个合法字符。在本题 中,每个字符的镜像如图3-3所示(空白项表示该字符镜像后不能得到一个合法字符) 

 

输入的每行包含一个字符串(保证只有上述字符。不含空白字符),判断它是否为回文 串和镜像串(共4种组合)。每组数据之后输出一个空行。
样例输入:
NOTAPALINDROME
ISAPALINILAPASI
2A3MEAS
ATOYOTA
样例输出:
NOTAPALINDROME -- is not a palindrome.
ISAPALINILAPASI -- is a regular palindrome.
2A3MEAS -- is a mirrored string.
ATOYOTA -- is a mirrored palindrome.

分析:题目提到了 不包含空白字符 —— 可以安全的用 scanf 进行输入

可以采用上方例题提到的 常量数组解决

#include<stdio.h>
#include<string.h>
#include<ctype.h>
const char* rev = "A   3  HIL JM O   2TUVWXY51SE Z  8 ";
const char* msg[] = {"not a palindrome", "a regular palindrome", "a mirrored string","a mirrored palindrome"};

char r(char ch) {
      if(isalpha(ch))
        return rev[ch - 'A'];
      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)/2; i++) {
                        if(s[i] != s[len-1-i])
                        p = 0; //不是回文串
                        if(r(s[i]) != s[len-1-i])
                            m = 0; //不是镜像串
                        }
            printf("%s -- is %s.\n\n", s, msg[m*2+p]);

    }
   return 0;
}

自定义函数char r(char ch),参数ch是一个字符,返回值是ch的镜像字符。这是因为该常量数组中前26项是各个大写字母的镜像,而后10个是数字1~9的镜像(数 字0不会出现),所以需要判断ch是字母还是数字

isalpha来判断字符是否为字母,类似的还有idigit、isprint等,在ctype.h中定义。

由于ASCII码表中大写字母、小写字母和数字都是连续的,如果ch是大写字母,则ch-'A'就是 它在字母表中的序号(A的序号是0,B的序号是1,依此类推);类似地,如果ch是数字, 则ch-'0'就是这个数字的数值本身(例如'5'-'0'=5)

常量数组msg,事实上,这是一个字符串数组,即二维字符数组

 # 头文件ctype.h中定义的isalpha、isdigit、isprint等工具可以用来判断字符 的属性,而toupper、tolower等工具可以用来转换大小写。如果ch是大写字母,则ch-'A'就是 它在字母表中的序号(A的序号是0,B的序号是1,依此类推);类似地,如果ch是数字, 则ch-'0'就是这个数字的数值本身

char* a = "abc" 和 char a[] = "abc" 之间的区别

 例题3-4 猜数字游戏的提示

a

猜你喜欢

转载自www.cnblogs.com/expedition/p/11485330.html
今日推荐