Algorithm: is to give the chemical formula, in accordance with the required format for output. Examples are as follows:
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",), ("N", 2), ("S", 4)])
parse_molecule ("pie")
//ERR (ParseError)
where, Ok ([("K", 4), ("O", "(" N ", 2), (" S ", 4)]) is arranged in the order in which the k,o,n,s appear.
Explain, this question looks very simple, but the actual difficulty still has. In the Codewars is the 3rd level difficulty (1 level hardest, 8 the most easy).
First, my solution
Idea: "K4[on (SO3) 2]2" =>k4[onso3so3]2 "=>K4+ONSO3SO3+ONSO3SO3" =kkkk+ ...
The first step: To remove the number of chemical formula
Step two: Go () remove
Step three: Go [] Remove
The output is to be printed in the alphabetical order of the chemical type.
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::D ebug 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)}}} 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_stri
Ng ());
return Ok (output);
}}//Case 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-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_s
Tring ());
} 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_stri Ng () = = _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}
Run:
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)"));
}
Output results: