回文词详细解析(算法竞赛入门)

本文详细解析了一个C程序,该程序用于判断输入字符串是否为回文或镜像串。通过自定义函数和常量数组,程序能够有效识别大写字母和数字的镜像字符,最终输出四种可能的状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 问题描述

           输入一个字符串,判断它是否为回文以及镜像串。输入字符串保证不含数字0.所谓回文串,就是反转之后原串相同,如abba和madam。所谓镜像串,就是左右镜像之后和原串相同,如2S和3AIAE。注意,并不是每个字符在镜像之后都能得到一个合法字符,本题中,每个字符的镜像如下所示,(空白项表示该字符镜像后不能得到一个合法的字符)。

 

 

#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),
	参数ch是一个字符,返回值是ch的镜像字符,因为该常量数组中前26项是各个大写字母的镜像,而后10个是1~9的数字
	所以需要判断ch是字母还是数字,使用isalpha来判断字符是否为字母,在ctype.h中定义。
	由于ASCII码表中大写字母、小写字母、数字都是连续的,如果ch是大写字母,则ch-'A'就是它在字母表中的序号(A序号是0,B为1,以此类推)
	如果ch是数字,则ch-'0'就是这个数值本身 +25是因为前26项都是字母 
*/
char r(char ch){
	if(isalpha(ch)) return rev[ch-'A'];
	return rev[ch-'0'+25];
} 

int main(){
	char s[30];
	//scanf返回数据为读入数据的个数,==1表示在成功读入一个数据是执行循环 
	//scanf的返回值由后面的参数决定 scanf("%d%d", &a, &b); 如果a和b都被成功读入,那么scanf的返回值就是2 
	//如果只有a被成功读入,返回值为1 如果a和b都未被成功读入,返回值为0 如果遇到错误或遇到end of file,返回值为EOF。
	// 且返回值为int型.
	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;
}

 输出msg[m*2+p]的原因

回文,镜像串,有4种组合。

msg[0]是: 非回文、非镜像。
msg[1]是: 回文、非镜像。
msg[2]是: 非回文、镜像。
msg[3]是: 回文、镜像。
为何最后输出的时候,m(镜像)要 * 2呢?
因为我们对比一下:msg[0],msg[1],这2个都是 非镜像,差别就在于回文,下标相关是1.再对比msg[2],msg[3],这2个都是镜像,差别就在于回文,相差是1.所以为何输出结果p * 1。
再对比msg[0], msg[2],都是非回文,差别就是 镜像与否,下标差了2. 最后对比msg[1],msg[3],都是回文,差别就是 镜像与否,下标相差2.所以为何输出结果m * 2.

贴出以下代码方便理解,可以用以下代码输出但显然会造成浪费

 if(p==0&&m==0)
        printf("%s----is %s\n\n",a,msg[0]);
    if(p==1&&m==0)
        printf("%s----is %s\n\n",a,msg[1]);
    if(p==0&&m==1)
        printf("%s----is %s\n\n",a,msg[2]);
    if(p==1&&m==1)
        printf("%s----is %s\n\n",a,msg[3]);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值