20200613-01 PAT 甲級試題 02 Read Number in Chinese

思路講解

核心一: 數值的分解

1.1 大單位分解

因爲需要添加 “Yi" 和 " Wan” 兩個單位,所以我的思路第一步是將其拆解成 3 個部分

//這裏使用的是 C++ 所以單位轉化規範一點比較好
 int num_array[] = {static_cast<int>(n/100000000), //億
                    static_cast<int>(n % 100000000 / 10000), //萬
                    static_cast<int>(n % 10000)}; //個
1.2 小單位分解

經過上一步驟的分解,每個 4 位數字內部單位規律是一致的,都是 Qian Bai Shi,所以可以寫一個函數進行進一步的分解,我採用的是直接分解成個位數

//數據分解爲個位數
auto temp {val};
for (int i = 3; i >= 0; i--) {
    ge_num[i] = temp % 10;
    temp /= 10;
}

核心二: 添加 0

根據題目可知,ling 是必須要的,但不能重複出現
舉例:
1 起始數字前 不能有零
2 零不能重複出現
3 特別是如 100000001 => yi Yi ling yi 萬單位處爲 0 則需要加上 ling
4 整數單位後的 0 可以忽略,如 1000 =>yi Qian; 100=> yi Bai; 10=> yi Shi

源碼

#include <cstdio>
#include <cmath>
#include <string>

using namespace std;

string num_zn[] = {
    "ling","yi","er","san","si","wu","liu","qi","ba","jiu"
};
string unit_zn[] = {"Qian", "Bai", "Shi"};
string UNIT_YI = "Yi";
string UNIT_WAN = "Wan";
//每個數字之後需要添加一個空格
string add_string(string & val) {
    return val + " ";
}
//簡單得到單位
string get_unit(const int & v) {
    if (v < 3) {
        return add_string(unit_zn[v]);
    }
    return "";
}
//分段處理 4 位數字
/*!
 * \brief digits_4 handle 4 bit number
 * \param val number
 * \param ch string
 * \param need_add_ling If the "ling" is not required, set the value to false
 *  因爲這裏只處理 4 位數字,並不清楚首位是否爲零,由上一級指定,默認需要添加 ling
 */
void digits_4(const int & val, string & ch, const bool need_add_ling = true) {
    string str_temp {""};
    int ge_num[4] = {0, 0, 0, 0};

    //數據分解爲個位數 1234 分解 [4, 3, 2, 1]
    auto temp {val};
    for (int i = 3; i >= 0; i--) {
        ge_num[i] = temp % 10;
        temp /= 10;
    }
    //數據處理
    int zero_count {0};
    //這樣就是準確識別出 0100 1001 1010 這種
    for (int i = 0; i < 4; i++) {
        //0090 遇到0計1
        if (ge_num[i] == 0)
            zero_count++;
        else {
            // 1 若是首位如 100 10000 這種不需要加零 str_temp == "" && need_add_ling && zero_count != 0
            // 2 中間位連續0 只寫一個 ling // str_temp != "" && zero_count != 0
            if (((str_temp == "" && need_add_ling) || str_temp != "")
                 && zero_count != 0)
                str_temp += add_string(num_zn[0]);

            str_temp += add_string(num_zn[ge_num[i]]) + get_unit(i);
            zero_count = 0;
        }
    }

    ch += str_temp;
}

int main() {

    long long n;
    scanf("%lld", &n);

    string res {""};
    if (n < 0)
        res = "Fu ";
    //取正整數
    n = abs(n);

    //值爲零則輸出 ling
    if (n > 0) {
        //分解得到數據分解成億,萬,個單位
        int num_array[] = {static_cast<int>(n/100000000), //億
                           static_cast<int>(n % 100000000 / 10000), //萬
                           static_cast<int>(n % 10000)}; //個

        //億之前不需要添加 ling
        string temp_str {""};
        if (num_array[0]) {
            digits_4(num_array[0], temp_str, false);
            temp_str += add_string(UNIT_YI);
        }
        res += temp_str;

        //萬值爲0,則判斷前後億和個的值都不爲0,則添加 ling,不爲零則隨意 
        // 10000001 yi Yi ling yi
        temp_str = "";
        if (num_array[1]) {
            digits_4(num_array[1], temp_str, num_array[0] > 0);
            temp_str += add_string(UNIT_WAN);
        } else if (num_array[2] && num_array[0]) {
            temp_str += add_string(num_zn[0]);
        }
        res += temp_str;

        //只要之前wan的值爲0, 那就不需要添加 ling, 如1, 10000001這種
        temp_str = "";
        if (num_array[2]) {
            digits_4(num_array[2], temp_str, num_array[1] > 0);
        }
        res += temp_str;
    } else {
        res += num_zn[0];
    }

    printf("%s", res.c_str());

    return 0;
}

推薦課程

尹成老師帶你學算法


數據結構核心原理與算法應用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章