首页 > 解决方案 > 如何将 Rust 数字转换为英文单词,如 1 -> "one"?

问题描述

我的任务是将数字转换为文本(如 115 ->“一百十五)。数字将介于 0 和 18,446,744,073,709,551,615 之间(64 位无符号整数的最大值)。

最后的变换一定是18,446,744,073,709,551,615 -> “18,446,444,440,037,905,555,615”

标签: rust

解决方案


我碰巧手头有这个程序,因为它是“编码挑战”网站上的常见问题。您必须将数字分解为每组 3 位数字,然后调用函数以递归方式将数字序列化为文本。这是完整的解决方案:

use std::iter::successors;

const ONES: [&str; 20] = [
    "zero",
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
    "seven",
    "eight",
    "nine",
    "ten",
    "eleven",
    "twelve",
    "thirteen",
    "fourteen",
    "fifteen",
    "sixteen",
    "seventeen",
    "eighteen",
    "nineteen",
];
const TENS: [&str; 10] = [
    "zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty",
    "seventy", "eighty", "ninety",
];
const ORDERS: [&str; 7] = [
    "zero",
    "thousand",
    "million",
    "billion",
    "trillion",
    "quadrillion",
    "quintillion", // enough for u64::MAX
];

pub fn encode(num: u64) -> String {
    match num {
        0..=19 => ONES[num as usize].to_string(),
        20..=99 => {
            let upper = (num / 10) as usize;
            match num % 10 {
                0 => TENS[upper].to_string(),
                lower => format!("{}-{}", TENS[upper], encode(lower)),
            }
        }
        100..=999 => format_num(num, 100, "hundred"),
        _ => {
            let (div, order) =
                successors(Some(1u64), |v| v.checked_mul(1000))
                    .zip(ORDERS.iter())
                    .find(|&(e, _)| e > num / 1000)
                    .unwrap();

            format_num(num, div, order)
        }
    }
}

fn format_num(num: u64, div: u64, order: &str) -> String {
    match (num / div, num % div) {
        (upper, 0) => format!("{} {}", encode(upper), order),
        (upper, lower) => {
            format!("{} {} {}", encode(upper), order, encode(lower))
        }
    }
}

锈游乐场链接


推荐阅读