All Your Base
1. Readme
你的所有基本
将一个数字,表示为一个基数中的数字序列,并转为其他基本
实施通用基本转换。给出一个a参数,表示为数字序列,将其转换为基数b。
笔记
- 尝试自己实现转换。请勿使用其他内容为您执行转换.
关于位置表示法
在位置表示法中,以数字表示b可以被理解为权力的线性组合b.
数字 42,基本为 10,意思是:
(4 * 10^1) + (2 * 10^0)
数字 101010,基本为 2,意思是:
(1 * 2^5) + (0 * 2^4) + (1 * 2^3) + (0 * 2^2) + (1 * 2^1) + (0 * 2^0)
号码 1120,基本为 3,意思是:
(1 * 3^3) + (1 * 3^2) + (2 * 3^1) + (0 * 3^0)
我想你明白了!
是。上面这三个数字完全一样。恭喜!
2. 开始你的表演
#[derive(Debug, PartialEq)] pub enum Error { InvalidInputBase, InvalidOutputBase, InvalidDigit(u32), } /// /// Convert a number between two bases. /// /// A number is any slice of digits. /// A digit is any unsigned integer (e.g. u8, u16, u32, u64, or usize). /// Bases are specified as unsigned integers. /// /// Return an `Err(.)` if the conversion is impossible. /// The tests do not test for specific values inside the `Err(.)`. /// /// /// You are allowed to change the function signature as long as all test still pass. /// /// /// Example: /// Input /// number: &[4, 2] /// from_base: 10 /// to_base: 2 /// Result /// Ok(vec![1, 0, 1, 0, 1, 0]) /// /// The example corresponds to converting the number 42 from decimal /// which is equivalent to 101010 in binary. /// /// /// Notes: /// * The empty slice ( "[]" ) is equal to the number 0. /// * Never output leading 0 digits. However, your function must be able to /// process input with leading 0 digits. /// pub fn convert(number: &[u32], from_base: u32, to_base: u32) -> Result<Vec<u32>, Error> { unimplemented!( "Convert {:?} from base {} to base {}", number, from_base, to_base ) }
3. 测试代码查看
# #![allow(unused_variables)] #fn main() { #[test] fn single_bit_one_to_decimal() { let input_base = 2; let input_digits = &[1]; let output_base = 10; let output_digits = vec![1]; assert_eq!( convert(input_digits, input_base, output_base), Ok(output_digits) ); } #[test] //#[ignore] fn binary_to_single_decimal() { let input_base = 2; let input_digits = &[1, 0, 1]; let output_base = 10; let output_digits = vec![5]; assert_eq!( convert(input_digits, input_base, output_base), Ok(output_digits) ); } #[test] //#[ignore] fn single_decimal_to_binary() { let input_base = 10; let input_digits = &[5]; let output_base = 2; let output_digits = vec![1, 0, 1]; assert_eq!( convert(input_digits, input_base, output_base), Ok(output_digits) ); } #[test] //#[ignore] fn binary_to_multiple_decimal() { let input_base = 2; let input_digits = &[1, 0, 1, 0, 1, 0]; let output_base = 10; let output_digits = vec![4, 2]; assert_eq!( convert(input_digits, input_base, output_base), Ok(output_digits) ); } #[test] //#[ignore] fn decimal_to_binary() { let input_base = 10; let input_digits = &[4, 2]; let output_base = 2; let output_digits = vec![1, 0, 1, 0, 1, 0]; assert_eq!( convert(input_digits, input_base, output_base), Ok(output_digits) ); } #[test] //#[ignore] fn trinary_to_hexadecimal() { let input_base = 3; let input_digits = &[1, 1, 2, 0]; let output_base = 16; let output_digits = vec![2, 10]; assert_eq!( convert(input_digits, input_base, output_base), Ok(output_digits) ); } #[test] //#[ignore] fn hexadecimal_to_trinary() { let input_base = 16; let input_digits = &[2, 10]; let output_base = 3; let output_digits = vec![1, 1, 2, 0]; assert_eq!( convert(input_digits, input_base, output_base), Ok(output_digits) ); } #[test] //#[ignore] fn fifteen_bit_integer() { let input_base = 97; let input_digits = &[3, 46, 60]; let output_base = 73; let output_digits = vec![6, 10, 45]; assert_eq!( convert(input_digits, input_base, output_base), Ok(output_digits) ); } #[test] //#[ignore] fn empty_list() { let input_base = 2; let input_digits = &[]; let output_base = 10; let output_digits = vec![]; assert_eq!( convert(input_digits, input_base, output_base), Ok(output_digits) ); } #[test] //#[ignore] fn single_zero() { let input_base = 10; let input_digits = &[0]; let output_base = 2; let output_digits = vec![]; assert_eq!( convert(input_digits, input_base, output_base), Ok(output_digits) ); } #[test] //#[ignore] fn multiple_zeros() { let input_base = 10; let input_digits = &[0, 0, 0]; let output_base = 2; let output_digits = vec![]; assert_eq!( convert(input_digits, input_base, output_base), Ok(output_digits) ); } #[test] //#[ignore] fn leading_zeros() { let input_base = 7; let input_digits = &[0, 6, 0]; let output_base = 10; let output_digits = vec![4, 2]; assert_eq!( convert(input_digits, input_base, output_base), Ok(output_digits) ); } #[test] //#[ignore] fn invalid_positive_digit() { let input_base = 2; let input_digits = &[1, 2, 1, 0, 1, 0]; let output_base = 10; assert_eq!( convert(input_digits, input_base, output_base), Err(Error::InvalidDigit(2)) ); } #[test] //#[ignore] fn input_base_is_one() { let input_base = 1; let input_digits = &[]; let output_base = 10; assert_eq!( convert(input_digits, input_base, output_base), Err(Error::InvalidInputBase) ); } #[test] //#[ignore] fn output_base_is_one() { let input_base = 2; let input_digits = &[1, 0, 1, 0, 1, 0]; let output_base = 1; assert_eq!( convert(input_digits, input_base, output_base), Err(Error::InvalidOutputBase) ); } #[test] //#[ignore] fn input_base_is_zero() { let input_base = 0; let input_digits = &[]; let output_base = 10; assert_eq!( convert(input_digits, input_base, output_base), Err(Error::InvalidInputBase) ); } #[test] //#[ignore] fn output_base_is_zero() { let input_base = 10; let input_digits = &[7]; let output_base = 0; assert_eq!( convert(input_digits, input_base, output_base), Err(Error::InvalidOutputBase) ); } #}
4. 答案
# #![allow(unused_variables)] #fn main() { pub type Digit = u32; #[derive(Debug, PartialEq)] pub enum Error { InvalidInputBase, InvalidOutputBase, InvalidDigit(Digit), } /// /// Convert a number between two bases. /// /// A number is any slice of digits. /// A digit is any unsigned integer (e.g. u8, u16, u32, u64, or usize). /// Bases are specified as unsigned integers. /// /// Return an `Err(.)` if the conversion is impossible. /// The tests do not test for specific values inside the `Err(.)`. /// /// /// You are allowed to change the function signature as long as all test still pass. /// /// /// Example: /// Input /// number: &[4, 2] /// from_base: 10 /// to_base: 2 /// Result /// Ok(vec![1, 0, 1, 0, 1, 0]) /// /// The example corresponds to converting the number 42 from decimal /// which is equivalent to 101010 in binary. /// /// /// Notes: /// * The empty slice ( "[]" ) is equal to the number 0. /// * Never output leading 0 digits. However, your function must be able to /// process input with leading 0 digits. /// pub fn convert<P: AsRef<[Digit]>>( digits: P, from_base: Digit, to_base: Digit, ) -> Result<Vec<Digit>, Error> { // check that both bases are in the correct range if from_base < 2 { return Err(Error::InvalidInputBase); } if to_base < 2 { return Err(Error::InvalidOutputBase); } // check that all digits are in the correct range specified by the base if let Some(&invalid) = digits.as_ref().iter().find(|&num| *num >= from_base) { return Err(Error::InvalidDigit(invalid)); } // convert all digits into a single large number let mut immediate = digits .as_ref() .iter() .rev() .enumerate() .map(|(i, &num)| num * from_base.pow(i as u32)) .fold(0, |accu, num| accu + num); // convert number into digits let mut res = Vec::new(); while immediate > 0 { res.push(immediate % to_base); immediate /= to_base; } // fix order of digits res.reverse(); Ok(res) } #}