Roman Numerals
1. Readme
罗马数字
写一个函数,从普通数字,转换成罗马数字.
罗马人是一群聪明的人。他们征服了欧洲大部分国家,统治了几百年。他们发明了混凝土和直路,甚至 Bikinis 夜店。他们从来没有发现过的一件事就是数字零。这使得写作和约会他们的功绩的广泛历史稍有挑战性,但他们提出的数字系统仍在使用。例如,英国广播公司使用罗马数字制定他们的节目。
罗马人用字母 I(1)、V(5)、X(10)、L(50)、C(100)、D(500)和 M(1000) 写数字(注意这些字母有很多直线,因此很容易侵入石碑)。
1 => I
10 => X
7 => VII
不需要能 转换 超过 3000 的罗马数字
在较大的罗马数字的右边记上较小的罗马数字,表示大数字加小数字。 在较大的罗马数字的左边记上较小的罗马数字,表示大数字减小数字。
要在实践中看到这一点,请考虑 1990 的例子.
在罗马数字中,1990 是 MCMXC:
1000=M 900=CM 90=XC
CM = 1000 - 100 = 900
2008 被写成 MMVIII:
2000=MM 8=Ⅷ
参见:http://www.novaroma.org/via_romana/numbers.html
资源
维基百科https://zh.wikipedia.org/wiki/%E7%BD%97%E9%A9%AC%E6%95%B0%E5%AD%97
2. 开始你的表演
use std::fmt::{Display, Formatter, Result}; pub struct Roman; impl Display for Roman { fn fmt(&self, _f: &mut Formatter) -> Result { unimplemented!("Return a roman-numeral string representation of the Roman object"); } } impl From<u32> for Roman { fn from(num: u32) -> Self { unimplemented!("Construct a Roman object from the '{}' number", num); } }
3. 测试代码查看
# #![allow(unused_variables)] #fn main() { #[test] fn test_one() { assert_eq!("I", Roman::from(1).to_string()); } #[test] //#[ignore] fn test_two() { assert_eq!("II", Roman::from(2).to_string()); } #[test] //#[ignore] fn test_three() { assert_eq!("III", Roman::from(3).to_string()); } #[test] //#[ignore] fn test_four() { assert_eq!("IV", Roman::from(4).to_string()); } #[test] //#[ignore] fn test_five() { assert_eq!("V", Roman::from(5).to_string()); } #[test] //#[ignore] fn test_six() { assert_eq!("VI", Roman::from(6).to_string()); } #[test] //#[ignore] fn test_nine() { assert_eq!("IX", Roman::from(9).to_string()); } #[test] //#[ignore] fn test_twenty_seven() { assert_eq!("XXVII", Roman::from(27).to_string()); } #[test] //#[ignore] fn test_forty_eight() { assert_eq!("XLVIII", Roman::from(48).to_string()); } #[test] //#[ignore] fn test_fifty_nine() { assert_eq!("LIX", Roman::from(59).to_string()); } #[test] //#[ignore] fn test_ninety_three() { assert_eq!("XCIII", Roman::from(93).to_string()); } #[test] //#[ignore] fn test_141() { assert_eq!("CXLI", Roman::from(141).to_string()); } #[test] //#[ignore] fn test_163() { assert_eq!("CLXIII", Roman::from(163).to_string()); } #[test] //#[ignore] fn test_402() { assert_eq!("CDII", Roman::from(402).to_string()); } #[test] //#[ignore] fn test_575() { assert_eq!("DLXXV", Roman::from(575).to_string()); } #[test] //#[ignore] fn test_911() { assert_eq!("CMXI", Roman::from(911).to_string()); } #[test] //#[ignore] fn test_1024() { assert_eq!("MXXIV", Roman::from(1024).to_string()); } #[test] //#[ignore] fn test_3000() { assert_eq!("MMM", Roman::from(3000).to_string()); } #}
4. 答案
# #![allow(unused_variables)] #fn main() { use std::fmt; static ROMAN_MAP: [(usize, &'static str); 13] = [ (1, "I"), (4, "IV"), (5, "V"), (9, "IX"), (10, "X"), (40, "XL"), (50, "L"), (90, "XC"), (100, "C"), (400, "CD"), (500, "D"), (900, "CM"), (1000, "M"), ]; pub struct Roman { num: usize, } impl From<usize> for Roman { fn from(i: usize) -> Self { Roman::new(i) } } impl fmt::Display for Roman { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut start = self.num.clone(); let mut result = String::new(); for &(numeric, roman_string) in ROMAN_MAP.into_iter().rev() { while start >= numeric { result.push_str(roman_string); start = start - numeric; } } write!(f, "{}", result) } } impl Roman { fn new(num: usize) -> Roman { Roman { num: num } } } #}