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 }
   }
}

#}



填充/相关