题解 | #人民币转换#

人民币转换

http://www.nowcoder.com/practice/00ffd656b9604d1998e966d555005a4b

描述

题目描述

就是给我们一个正常的阿拉伯数字, 让我们转换为我们中文的大写数字

这道题目, 本质上来讲就是一个大模拟

样例解释

给定我们的样例输入:

151121.15

20220211131403

所以我们的样例输出就是

人民币拾伍万壹仟壹佰贰拾壹元壹角伍分

题解

解法一: C++代码

实现思路

首先我们小数点后面的位置好判断, 我们可以直接用三个判断语句进行操作

然后难点在于我们的小数点前面的一个判断, 我们要对每一个位置进行一个判断, 这个位置如果没有对应的单位, 就如我上图所讲, 那么我们就是要跟下一个有单位的组成一个, 然后转换为中文输出, 然后我们接下来有单位的正常输出就可以了, 有零的情况需要特殊判断

代码实现

#include <bits/stdc++.h>

using namespace std;

vector<string> single = {"零", "壹", "贰", "叁", "肆",
                         "伍", "陆", "柒", "捌", "玖"};

void sayPre(string &pre) {
    if (pre == "0") return ;
    // 判断小数点前面是不是空的
    for (int i = 0, j = pre.size() - 1; i < pre.size(); i++, j--) {
        // i代表的是我们遍历的字符串, j是我们i后面有几个数
        if (pre[i] != '0' and not(pre[i] == '1' and j % 4 == 1))
            cout << single[pre[i] - '0'];
        // 转换中文
        if (j != 0 and j % 8 == 0 and j >= 8) 
            cout << "亿";
        if (j != 0 and j % 4 == 0 and j % 8 != 0)
            pre[i + 1] == '0' ? cout << "万零" : cout << "万";
        if (j != 0 and j % 4 == 3 and pre[i] != '0') 
            pre[i + 1] == '0' and pre[i + 2] != '0' ? cout << "仟零" : cout << "仟";
        if (j != 0 and j % 4 == 2 and pre[i] != '0')
            pre[i + 1] == '0' and pre[i + 2] != '0' ? cout << "佰零" : cout << "佰";
        if (j != 0 and j % 4 == 1 and pre[i] != '0')
            cout << "拾";
    }
    // 上面的if分别对应后面输出的亿万千百十
    cout << "元";
    // 最后我们输出元
}

void sayEnd(string &end) {
    if (end == "00")
        cout << "整\n";
    else if (end[0] == '0')
        cout << single[end[1] - '0'] << "分\n";
    else if (end[1] == '0')
        cout << single[end[0] - '0'] << "角\n";
    else
        cout << single[end[0] - '0'] << "角" << single[end[1] - '0'] << "分\n";
    // 分类讨论, 讨论我们小数点后两位的所有情况
}

signed main() {
    string s;
    while (cin >> s) {
        string pre = "", end = "";
        bool okk = false;
        for (auto &it : s) {
            if (it == '.') {
                okk = true;
                continue;
            }
            okk ? end += it : pre += it;
        }
        // 这里我们以小数点为分隔, 把小数点前面的存储到了pre里面,
        // 小数点后面的存储到了end里面
        cout << "人民币";
        sayPre(pre), sayEnd(end);
    }
    return 0;
}

时空复杂度分析

对于本题目而言:

时间复杂度: O(1)O(1)

理由如下: 其实我们本质就是遍历了一个我们这个作为输入阿拉伯数字, 然而这个字符串的长度事实上并不会太长, 长度属于常数的级别, 所以我们可以把他理解为是O(1)O(1)

空间复杂度: O(1)O(1)

理由如下: 我们利用了常数级别的空间

对于这个代码而言:

时间复杂度: O(n)O(n)

理由如下: 遍历的是我们字符串的长度

空间复杂度: O(n)O(n)

理由如下: 我们需要把这个字符串存到两个字符串中

解法二: Python代码

实现思路

我们跟C++的代码类似, 但是我们用Python可以很好的把字符串区分为小数点前和小数点后, 然后我们再对每一个位置分别判断是否满足条件, 然后转换为中文或者输出他们的单位

代码实现

gewei = ['零', '壹', '贰', '叁', '肆',
         '伍', '陆', '柒', '捌', '玖']
# 个位的所有数字


def main():
    while True:
        try:
            pre, end = input().split('.')
            # 把我们输入的字符串以我们的小数点作为一个分隔
            print('人民币', end="")
            idx = len(pre)
            # 这个是我们每一个字符后面还有多少位
            for i in range(0, len(pre)):
                # 遍历我们所有的字符
                idx -= 1
                if pre[i] != '0' and not(pre[i] == '1' and idx % 4 == 1):
                    print(gewei[int(pre[i])], end="")
                # 这个是需要转换位中文的
                if idx != 0:
                    # 如果不是个位的话
                    if idx % 8 == 0 and idx >= 8:
                        print('亿', end="")
                    if idx % 4 == 0 and idx % 8 != 0:
                        if pre[i + 1] == '0':
                            print('万零', end="")
                        else:
                            print('万', end="")
                    if idx % 4 == 3 and pre[i] != '0':
                        if pre[i + 1] == '0' and pre[i + 2] != '0':
                            print('仟零', end="")
                        else:
                            print('仟', end="")
                    if idx % 4 == 2 and pre[i] != '0':
                        if pre[i + 1] == '0' and pre[i + 2] != '0':
                            print('佰零', end="")
                        else:
                            print('佰', end="")
                    if idx % 4 == 1 and pre[i] != '0':
                        print('拾', end="")
                    # 分别对我们的最后的单位进行一个判断
            if pre != '0':
                print('元', end="")
                # 正常输出
            if end == "00":
                print("整")
            elif end[0] == '0':
                print(gewei[int(end[1])] + "分")
            elif end[1] == '0':
                print(gewei[int(end[0])] + "角")
            else:
                print(gewei[int(end[0])] + "角" + gewei[int(end[1])] + "分")
            # 处理我们的小数点后面的位置
        except:
            break


if __name__ == '__main__':
    main()

时空复杂度分析

对于本题而言

时间复杂度: O(1)O(1)

理由如下: 其实我们本质就是遍历了一个我们这个作为输入阿拉伯数字, 然而这个字符串的长度事实上并不会太长, 长度属于常数的级别, 所以我们可以把他理解为是O(1)O(1)

空间复杂度: O(1)O(1)

理由如下: 我们利用了常数级别的空间

对于这个代码而言:

时间复杂度: O(n)O(n)

理由如下: 遍历的是我们字符串的长度

空间复杂度: O(n)O(n)

理由如下: 我们需要把这个字符串存到两个字符串中

机试题目题解 文章被收录于专栏

主要是机试题目的题目讲解和做法

全部评论
求问,在开头已经 idx -= 1 之后,再计算 not(pre[i] == '1' and idx % 4 == 1): 有意义吗?应该是在 -1之前计算 idx%4 == 1 吧?
点赞 回复 分享
发布于 2022-03-20 20:07
题目是double输入
点赞 回复 分享
发布于 2022-03-20 20:48
判断仟后面是否加零还需考虑个位的情况吧?
点赞 回复 分享
发布于 2022-07-23 22:57
idx -= 1为什么放在16行呢?
点赞 回复 分享
发布于 2023-06-04 13:55 浙江

相关推荐

拒绝无效加班的小师弟很中意你:求职意向没有,年龄、课程冗余信息可以删掉,需要提升项目经历。排版需要修改。
点赞 评论 收藏
分享
joe2333:怀念以前大家拿华为当保底的日子
点赞 评论 收藏
分享
评论
3
5
分享
牛客网
牛客企业服务