UVa 401 - Palindromes -AC

本文探讨了一种改进的算法,用于识别镜像字符串与回文串,并详细解释了如何优化代码减少不必要的行数。通过比较原始代码与优化后的版本,展示了在处理特定字符集时更高效的方法。

这道题看完题思路大致清晰,总体分开两个函数写,一个判断回文串,一个判断镜像串。

回文串判断好写,循环判断前半截与后半截是否一致即可。

关键在判断镜像串,一开始就也没多想,简单的判断呗~虽然知道要写好多,但也懒得细想。先判断字符串中有没有不是镜像字符的,有就直接返回0,没有再依次判断对称位置上的镜像字符是否对应,有不对应的就直接返回0,全都对应最后返回1.

虽然直接AC了,但这样写完了190行,突然感觉我好傻~
先贴出来吧~

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 10005

int pal(char str[MAX_SIZE])//palindrome
{
    int i,j,slen;
    slen=strlen(str);
    for (i=0,j=slen-1;i<slen/2;i++,j--)
        if (str[i]!=str[j])
            break;
    if (i==slen/2)
        return 1;
    return 0;
}

int mir (char str[MAX_SIZE])//mirrored
{
    int i,j,slen;
    slen=strlen(str);
    for (i=0;i<slen;i++)
    {
        switch (str[i])
        {
            case 'B':
                return 0;
            case 'C':
                return 0;
            case 'D':
                return 0;
            case 'F':
                return 0;
            case 'G':
                return 0;
            case 'K':
                return 0;
            case 'N':
                return 0;
            case 'P':
                return 0;
            case 'Q':
                return 0;
            case 'R':
                return 0;
            case '4':
                return 0;
            case '6':
                return 0;
            case '7':
                return 0;
            case '9':
                return 0;
        }

    }
    for (i=0;i<slen/2;i++)
    {
        switch(str[i])
        {
            case 'A':
                if (str[slen-i-1]=='A')
                    continue;
                else
                    return 0;
            case 'E':
                if (str[slen-i-1]=='3')
                    continue;
                else
                    return 0;
            case 'H':
                if (str[slen-i-1]=='H')
                    continue;
                else
                    return 0;
            case 'I':
                if (str[slen-i-1]=='I')
                    continue;
                else
                    return 0;
            case 'J':
                if (str[slen-i-1]=='L')
                    continue;
                else
                    return 0;
            case 'L':
                if (str[slen-i-1]=='J')
                    continue;
                else
                    return 0;
            case 'M':
                if (str[slen-i-1]=='M')
                    continue;
                else
                    return 0;
            case 'O':
                if (str[slen-i-1]=='O')
                    continue;
                else
                    return 0;
            case 'S':
                if (str[slen-i-1]=='2')
                    continue;
                else
                    return 0;
            case 'T':
                if (str[slen-i-1]=='T')
                    continue;
                else
                    return 0;
            case 'U':
                if (str[slen-i-1]=='U')
                    continue;
                else
                    return 0;
            case 'V':
                if (str[slen-i-1]=='V')
                    continue;
                else
                    return 0;
            case 'W':
                if (str[slen-i-1]=='W')
                    continue;
                else
                    return 0;
            case 'X':
                if (str[slen-i-1]=='X')
                    continue;
                else
                    return 0;
            case 'Y':
                if (str[slen-i-1]=='Y')
                    continue;
                else
                    return 0;
            case 'Z':
                if (str[slen-i-1]=='5')
                    continue;
                else
                    return 0;
            case '1':
                if (str[slen-i-1]=='1')
                    continue;
                else
                    return 0;
            case '2':
                if (str[slen-i-1]=='S')
                    continue;
                else
                    return 0;
            case '3':
                if (str[slen-i-1]=='E')
                    continue;
                else
                    return 0;
            case '5':
                if (str[slen-i-1]=='Z')
                    continue;
                else
                    return 0;
            case '8':
                if (str[slen-i-1]=='8')
                    continue;
                else
                    return 0;
        }
    }
    return 1;
}

int main()
{
    char str[MAX_SIZE];
    while (gets(str)!=NULL)
    {
        int pa,mi;
        pa=pal(str);
        mi=mir(str);
        if (pa==0&&mi==0)
            printf("%s -- is not a palindrome.\n",str);
        else if (pa==1&&mi==0)
            printf("%s -- is a regular palindrome.\n",str);
        else if (pa==0&&mi==1)
            printf("%s -- is a mirrored string.\n",str);
        else if (pa&&mi)
            printf("%s -- is a mirrored palindrome.\n",str);
        printf("\n");
    }
    return 0;
}


AC之后感觉这题这么写实在太狠了,然后又看了一下网上代码,看到

首先可以用两个数组把题目中的表格存起来

char  *ch = "AEHIJLMOSTUVWXYZ12358";
char  *re = "A3HILJMO2TUVWXY51SEZ8";

这才受到启发,把原来代码进行了改进,但这样要注意判断镜像串的时候要讨论字符串长度是否为1,否则会WA

修改后AC的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 10005

int pal(char str[MAX_SIZE])
{
    int i,j,slen;
    slen=strlen(str);
    for (i=0,j=slen-1;i<slen/2;i++,j--)
        if (str[i]!=str[j])
            break;
    if (i==slen/2)
        return 1;
    return 0;
}

int mir (char str[MAX_SIZE])
{
    char *ch="AEHIJLMOSTUVWXYZ12358";
    char *re="A3HILJMO2TUVWXY51SEZ8";
    int i,j,slen;
    slen=strlen(str);
    if (slen==1)
    {
        for (j=0;j<strlen(ch);j++)
            if (str[0]==ch[j]&&str[0]==re[j])
                return 1;
        return 0;
    }
    else
    {
        for (i=0;i<slen/2;i++)
        {
            for (j=0;j<strlen(ch);j++)
                if (str[i]==ch[j]&&str[slen-i-1]==re[j])
                {
                    j=-1;
                    break;
                }
            if (j!=-1)
                return 0;
        }
        return 1;
    }
}

int main()
{
    char str[MAX_SIZE];
    while (gets(str)!=NULL)
    {
        int pa,mi;
        pa=pal(str);
        mi=mir(str);
        if (pa==0&&mi==0)
            printf("%s -- is not a palindrome.\n",str);
        else if (pa==1&&mi==0)
            printf("%s -- is a regular palindrome.\n",str);
        else if (pa==0&&mi==1)
            printf("%s -- is a mirrored string.\n",str);
        else if (pa&&mi)
            printf("%s -- is a mirrored palindrome.\n",str);
        printf("\n");
    }
    return 0;
}


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值