《算法竞赛入门经典2ndEdition 》例题3-3 回文词(Palindromes, Uva401)

本文分享了在解决《算法竞赛入门经典2nd Edition》中例题3-3(UVA401 回文词)的过程,描述了遇到的挑战和解决方案。通过对比不同代码实现,包括未通过和通过AC的版本,探讨了优化技巧,并引用了刘汝佳书中简洁的解题代码。
摘要由CSDN通过智能技术生成

好吧,这道题真心写了很长时间(不得不承认我很弱),现在还有一个程序没改出来,贴出来希望各位大神能给我挑挑错,下面这个是没有AC的代码:

#include <cstdio>
#include <cstring>
#include "string.h"
char s[30];
using namespace std;
bool check_palindrome();
bool check_mirrored(int, int);
int main()
{
  //freopen("New Text Document.txt","r",stdin);
  //freopen("Output.txt","w",stdout);
  while(scanf("%s", s) != EOF)
  {
    int n = strlen(s);
    printf("%s ", s);
    if(check_palindrome())// a palindrome
    {
      int flag = 1;
      for(int i = 0; i <= n/2; i++)//=
        if(!check_mirrored(i,n-i-1)) 
        {
          flag = 0;
          printf("-- is a regular palindrome.\n");
          break;
        }
      if(flag == 1) printf("-- is a mirrored palindrome.\n");
    }
    else//not a palindrome
    {
      int flag = 1;
      for(int i = 0; i <= n/2; i++)//=
        if(!check_mirrored(i,n-i-1)) 
        {
          flag = 0;
          printf("-- is not a palindrome.\n");
          break;
        }
      if(flag == 1) printf("-- is a mirrored string.\n");
    }
    printf("\n");
  }
  //getchar();getchar();
  return 0;
} 

bool check_palindrome()
{
  int n = strlen(s);
  for(int i = 0; i < n/2; i++)
    if(s[i] != s[n-i-1]) return false;
  return true;
}

bool check_mirrored(int x,int y)
{
  char a = s[x], b = s[y];
  if(a == b)
    switch(a)
    {
      case 'A':case 'H':case 'I':case 'M':case 'O':case 'T':case 'U':
      case 'V':case 'W':case 'X':case 'Y':case '1':case '8': return true;
      //default:return false;
    }
  else
  {
    if(a > b) 
    {
      char ch;
      ch = a; a = b; b = ch;
    } 
    switch(a)
    {
      case '2':
           if(b == 'S') return true;
           else return false;
      case '3':
           if(b == 'E') return true;
           else return false;
      case '5':
           if(b == 'Z') return true;
           else return false;
      case 'J':
           if(b == 'L') return true;
           else return false;
      //default: return false;
    }
    return false;
  }
}

下面这个是看了书之后使用常量数组简化了一下check_mirrored函数,就AC了,但目前还没找到上个程序的错误。

#include <cstdio>
#include <cstring>

char s[30];

const char* rev = "A   3  HIL JM O   2TUVWXY51SE Z  8 ";
bool check_palindrome();
bool check_mirrored();

int main()
{
  //freopen("New Text Document.txt","r",stdin);
  //freopen("Output.txt","w",stdout);
  while(scanf("%s", s) != EOF)
  {
    printf("%s ", s);
    if(check_palindrome())// a palindrome
      if(!check_mirrored()) 
        printf("-- is a regular palindrome.\n");
      else printf("-- is a mirrored palindrome.\n");
    else//not a palindrome
      if(!check_mirrored()) 
          printf("-- is not a palindrome.\n");
        else printf("-- is a mirrored string.\n");
    printf("\n");
  }
  //getchar();getchar();
  return 0;
} 

bool check_palindrome()
{
  int n = strlen(s);
  for(int i = 0; i <= n/2; i++)
    if(s[i] != s[n-i-1]) return false;
  return true;
}

bool check_mirrored()
{
  int n = strlen(s);
  for(int i = 0; i <= n/2; i++)
    if(s[i]<='Z' && s[i]>='A' && *(rev+s[i]-'A')==s[n-i-1]) continue;
    else if(s[i]<='9' && s[i]>='1' && *(rev+s[i]-'1'+26)==s[n-i-1]) continue;
    else return false;
  return true;
}

虽然AC了,但还是觉得没有Rujia Liu给出的代码简洁,下面这个是从书配套的代码仓库下载的代码。
https://github.com/aoapc-book/aoapc-bac2nd/blob/master/ch3/UVa401.cpp

// UVa401 Palindromes
// Rujia Liu
#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;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值