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"));}

输出结果:

这里写图片描述

原创粉丝点击