Rust: codewars的Molecule to atoms
来源:互联网 发布:b2b源码授权费用 编辑:程序博客网 时间:2024/06/06 01:21
算法:就是给出化学中的分子式,按要求格式进行输出。举例如下:
parse_molecule("H2O"); // water // Ok([("H", 2), ("O", 1)]) parse_molecule("Mg(OH)2"); // magnesium hydroxide // Ok([("Mg", 1), ("O", 2), ("H", 2)] parse_molecule("K4[ON(SO3)2]2"); // Fremy's salt // Ok([("K", 4), ("O", 14),("N", 2),("S", 4)]) parse_molecule("pie") // Err(ParseError)
其中,Ok([(“K”, 4), (“O”, 14),(“N”, 2),(“S”, 4)]) 是按其中的K,O,N,S出现的先后顺序排列。
说明一下,这题看起来很简单,但是实际难度还是有的。在codewars是第3级难度(1级最难,8级最易)。
一、我的解法
//思路:”K4[ON(SO3)2]2” =>K4[ONSO3SO3]2” =>K4+ONSO3SO3+ONSO3SO3”=KKKK+…..
// 第一步:去化学式中的数字去掉
// 第二步:去()去掉
// 第三步:去[]去掉
// 输出要按化学式的字母顺序输出。
use std::collections::{HashMap};#[derive(Debug)]pub struct ParseError { info: ErrType, }pub enum ErrType { ValidErr, //"Not a valid molecule", MismatchErr, //"Mismatched parenthesis", NoErr, //"ok"}impl std::fmt::Debug for ErrType { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match *self { ErrType::ValidErr => write!(f, "{}", " Mismatched parenthesis"), ErrType::MismatchErr => write!(f, "{}", "Not a valid molecule"), _ => write!(f, "{}", "no_err"), } }}impl ParseError { pub fn new(information: &str) -> ParseError { ParseError { info: get_err_info(information) } }}pub fn get_err_info(s: &str) -> ErrType { let v = _vec(&s); let sum_bracket_1 = &v.iter() .filter(|x| ["(".to_string(), ")".to_string()].contains(&x)) .collect::<Vec<_>>() .len(); let sum_bracket_2 = &v.iter() .filter(|x| ["[".to_string(), "]".to_string()].contains(&x)) .collect::<Vec<_>>() .len(); if sum_bracket_1 % 2 != 0 || sum_bracket_2 % 2 != 0 { return ErrType::MismatchErr; } //pie problem let mut c = 0; let mut _chars: Vec<String> = Vec::new(); ("abcdefghijklmnopqrstuvwxyz") .chars() .into_iter() .map(|x| { _chars.push(x.to_string()); x }) .collect::<Vec<_>>(); for e in v { if _chars.contains(&(e.to_lowercase())) { c += 1; } else { c = 0; } if c >= 3 { return ErrType::ValidErr; } } return ErrType::NoErr;}type Molecule = Vec<(String, i32)>;pub fn parse_molecule(s: &str) -> Result<Molecule, ParseError> { let parse_err = ParseError::new(s); match parse_err.info { ErrType::ValidErr | ErrType::MismatchErr => return Err(parse_err), _ => { let output: Molecule = parse_str(s.to_string()); return Ok(output); } }}//大小写fn _vec(s: &str) -> Vec<String> { let mut data: Vec<String> = Vec::new(); let mut c = 0_usize; let len = s.len(); s.chars() .into_iter() .map(|x| { c += 1_usize; if c == len { let curr = s.chars().nth(c - 1_usize).unwrap(); if len == 1 { data.push(curr.to_string()); } else { let precurr = s.chars().nth(c - 2_usize).unwrap(); if precurr.is_lowercase() == true || (precurr.is_lowercase() == false && precurr.is_lowercase() == false) { data.push(curr.to_string()); } } } else { let next = s.chars().nth(c).unwrap(); let curr = s.chars().nth(c - 1_usize).unwrap(); match next.is_lowercase() { true => { if curr.is_lowercase() == false { data.push((&s[(c - 1_usize)..c + 1_usize]).to_string()); } else { data.push(curr.to_string()); } } _ => { if curr.is_lowercase() == false { data.push(curr.to_string()); } } } } x }) .collect::<Vec<_>>(); data}fn parse_str(str: String) -> Vec<(String, i32)> { let data = _vec(&str); let mut list: Vec<String> = Vec::new(); let mut output: HashMap<String, i32> = HashMap::new(); let mut str_series: Vec<String> = Vec::new(); for i in 0..data.len() { let curr = data.get(i).unwrap(); if i >= 1_usize { let precurr = data.get(i - 1_usize).unwrap(); if let Ok(m) = data.get(i).unwrap().parse::<i32>() { if ["(", ")", "[", "]"].iter().any(|x| (&precurr).contains(x)) == false { (0..m - 1_i32).map(|_| list.push(precurr.to_string())).collect::<Vec<_>>(); } else { list.push(curr.to_string()); } } else { list.push(curr.to_string()); } } else { list.push(curr.to_string()); } } list.clone() .into_iter() .map(|x| { if str_series.contains(&x) == false && x.chars().into_iter().any(|w| w.is_numeric()) == false && vec!["(", ")", "[", "]"] .iter() .map(|y| y.to_string()) .collect::<Vec<_>>() .contains(&x) == false { str_series.push(x.to_string()); } x }) .collect::<Vec<_>>(); let list_2 = insert_repeat(&list, ("(".to_string(), ")".to_string())); let list_3 = insert_repeat(&list_2, ("[".to_string(), "]".to_string())); list_3.into_iter() .map(|x| { let count = output.entry(x).or_insert(0_i32); *count += 1_i32 }) .collect::<Vec<_>>(); let vec = str_series.iter() .map(|x| (x.to_string(), *output.get(x).unwrap())) .collect::<Vec<(String, i32)>>(); vec}fn insert_repeat(list: &Vec<String>, _str: (String, String)) -> Vec<String> { let mut list_2: Vec<String> = Vec::new(); let mut bracket_1 = 0_usize; let mut bracket_2 = 0_usize; let mut is_insert = true; for i in 0..list.len() { let temp = list.get(i).unwrap().to_string(); if temp == _str.0 { bracket_1 = i; bracket_2 = i; is_insert = false; } else if temp == _str.1 { bracket_2 = i; } if let Ok(n) = list.get(i).unwrap().parse::<i32>() { if list.get(i - 1_usize).unwrap().to_string() == _str.1 { (0..n) .map(|_| for j in bracket_1 + 1_usize..bracket_2 { let tp = list.get(j).unwrap().to_string(); list_2.push(tp); }) .collect::<Vec<_>>(); bracket_1 = i; bracket_2 = i; is_insert = true; } else { if is_insert { list_2.push(temp); } } } else { if is_insert { list_2.push(temp); } } } list_2}
运行:
fn main{ println!("1=>{:?}", parse_molecule("pie")); println!("2=>{:?}", parse_molecule("Mg(OH)2")); println!("3=>{:?}", parse_molecule("K4[ON(SO3)2]2")); println!("4=>{:?}", parse_molecule("K4[ON(SO3)22"));}
输出结果:
阅读全文
0 0
- Rust: codewars的Molecule to atoms
- Rust: codewars的DNA to RNA Conversion
- Rust: codewars 的Duplicate Encoder
- Rust: codewars的Bleatrix Trotter
- Rust: codewars的prize draw算法
- Rust: codewars的primes-in-numbers
- Rust : codewars的up AND down 算法
- Rust : codewars的Sum of Pairs
- Rust: codewars的Roman Numerals Encoder
- Rust: codewars的Sum by Factors
- Rust: codewars的Highest and Lowest
- Rust : codewars的Product of consecutive Fib numbers
- Rust: codewars 的Count of positives / sum of negatives
- Rust: codewars的Simple Substitution Cipher Helper算法题、N种不简单的解法集
- Rust: HDF5文件的处理探索(to be continued.......)
- Rust : Pointer......to be continued
- codewars:Convert string to camel case
- (转)Rust: Rust的 Deref 运算符
- python--leetcode485. Max Consecutive Ones
- 二维码扫描
- 会话跟踪的多种方法
- 游戏小透明与Construct 2的初次邂逅
- 中缀表达式转为后缀表达式
- Rust: codewars的Molecule to atoms
- (M)Dynamic Programming:673. Number of Longest Increasing Subsequence
- 高通Qualcomm平台lk(light kernel)启动流程3——到高通lcm屏点亮
- 自定义view箭头绕圆环旋转
- 文章标题
- kotlin实现一个简单的新闻客户端-01
- 重温数据结构:二叉树的常见方法及三种遍历方式 Java 实现
- Java Activiti(1)---基础流程
- Python 之 基础面向对象编程