• 字符、散列、模拟--P1055 ISBN号码


    题目描述

    每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字、1位识别码和3位分隔符,其规定格式如x-xxx-xxxxx-x,其中符号-就是分隔符(键盘上的减号),最后一位是识别码,例如0-670-82162-4就是一个标准的ISBN码。ISBN码的首位数字表示书籍的出版语言,例如0代表英语;第一个分隔符-之后的三位数字代表出版社,例如670代表维京出版社;第二个分隔符后的五位数字代表该书在该出版社的编号;最后一位为识别码。

    识别码的计算方法如下:

    首位数字乘以1加上次位数字乘以2……以此类推,用所得的结果mod11,所得的余数即为识别码,如果余数为10,则识别码为大写字母X。例如ISBN号码0-670-82162-4中的识别码4是这样得到的:对067082162这9个数字,从左至右,分别乘以1,2,…,9再求和,即0×1+6×2+……+2×9=158,然后取158mod11的结果4作为识别码。

    你的任务是编写程序判断输入的ISBN号码中识别码是否正确,如果正确,则仅输出Right;如果错误,则输出你认为是正确的ISBN号码。

    输入输出格式

    输入格式:

    一个字符序列,表示一本书的ISBN号码(保证输入符合ISBN号码的格式要求)。

    输出格式:

    一行,假如输入的ISBN号码的识别码正确,那么输出Right,否则,按照规定的格式,输出正确的ISBN号码(包括分隔符-)。
    在这里插入图片描述

    思路

    使用一个char数组接收输入,可以一个一个接收,也可以整体接收。比较是否错误时,最简单是字符化为数字在进行比较,但是因为输入有可能是X,所以需要分成两种情况进行比较,即是输入X和不是X,是X时只能通过判断验证数字是否是10,不是X可以将字符与’0’相减转化为字符。
    如果是数字转化为字符的话,创建一个数字->字符的映射,可以使用数字作为数组的坐标,散列到对应的字符

    AC1

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int main() {
        char ins[10];
        scanf("%c-%c%c%c-%c%c%c%c%c-%c", &ins[0], &ins[1], &ins[2], &ins[3], &ins[4], &ins[5], &ins[6], &ins[7], &ins[8],
              &ins[9]);
        int temp = 0;
        //计算
        for (int i = 1; i <= 9; ++i) {
            //第0-8的输入
            temp = i * (ins[i - 1] - '0') + temp;
        }
        //输入最后一位是X时
        if (ins[9] == 'X') {
            if ((temp % 11) == 10){
                printf("Right");
                return 0;
            }
            else
                {
                    sprintf(&ins[9], "%d", (temp % 11));
                    printf("%c-%c%c%c-%c%c%c%c%c-%c", ins[0], ins[1], ins[2], ins[3], ins[4], ins[5], ins[6], ins[7], ins[8],ins[9]);
                    return 0;
                }
        }
        //输入不是X的情况
        if ((ins[9] - '0') != (temp % 11)) {
            //两者不相同
            if ((temp % 11) == 10) {
                ins[9] = 'X';
            } else {
                //数字转化字符
                sprintf(&ins[9], "%d", (temp % 11));
            }
            printf("%c-%c%c%c-%c%c%c%c%c-%c", ins[0], ins[1], ins[2], ins[3], ins[4], ins[5], ins[6], ins[7], ins[8],
                   ins[9]);
        } else
            printf("Right");
        return 0;
    }
    

    AC2

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int main() {
        char ins[13],chs[10];
        //数字散列到字符的表
        char mod[11] ={'0','1','2','3','4','5','6','7','8','9','X'};
        gets(ins);
        int j = 0;
        for (int i = 0; i < 13; ++i) {
            if (ins[i]!='-')
                chs[j++]=ins[i];
        }
        int temp = 0;
        for (int k = 0; k < 9; ++k) {
            temp = temp+(k+1)*(chs[k]-'0');
        }
        if(mod[temp%11]==chs[9])
            printf("Right");
        else{
            ins[12]=mod[temp%11];
            puts(ins);
        }
        return 0;
    }
    

    学到的点

    1 字符转数字不方便可以考虑做一个散列表用于数字转字符串
    2 gets(*p)获取输入的字符串
    3 sprintf(*p,“格式符”,数字)将数字赋值字符p

  • 相关阅读:
    人月神话阅读笔记03
    学习进度十六
    计算最长英语链
    学习进度十五
    人月神话阅读笔记02
    找“水王”
    学习进度十四
    用户体验评价
    学习进度十三
    学习进度十二
  • 原文地址:https://www.cnblogs.com/sunqiangstyle/p/10312286.html
Copyright © 2020-2023  润新知