SHARE
TWEET

Untitled

a guest Mar 21st, 2019 43 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. use std::process::exit;
  2. use std::cell::RefCell;
  3.  
  4. struct Calculator {
  5.     numbers: RefCell<Vec<f64>>,
  6.     operator: RefCell<Vec<u8>>,
  7.     expression: String,
  8. }
  9.  
  10. impl Calculator {
  11.     pub fn new(expr: String) -> Self {
  12.         Calculator {
  13.             numbers: RefCell::new(Vec::new()),
  14.             operator: RefCell::new(Vec::new()),
  15.             expression: expr,
  16.         }
  17.     }
  18.  
  19.     pub fn run(&self) -> Result<f64, String> {
  20.  
  21.         let mut sign: u8 = 0;   //入栈签名
  22.         let mut vernier: u8 = 0;   //移动游标
  23.         let mut locat: usize = 0;    //切片定位
  24.         let mut bracket: u32 = 0;    //括号标记
  25.         let expr = &self.expression;
  26.         let bytes = self.expression.as_bytes();
  27.         const PI: f64 = 3.141592653589793;
  28.  
  29.         let priority = |x: &u8| -> u8 {
  30.             match x {
  31.                 b'+' | b'-' => 1,
  32.                 b'*' | b'/' | b'%' => 2,
  33.                 b'^' => 3,
  34.                 _ => exit(0),
  35.             }
  36.         };
  37.  
  38.         let computing = |x: &u8| -> Result<f64, String> {
  39.             match x {
  40.                 b'+' => {
  41.                     let c1 = self.numbers.borrow_mut().pop().unwrap();
  42.                     let c2 = self.numbers.borrow_mut().pop().unwrap();
  43.                     return Ok(c2 + c1);
  44.                 }
  45.  
  46.                 b'-' => {
  47.                     let c1 = self.numbers.borrow_mut().pop().unwrap();
  48.                     let c2 = self.numbers.borrow_mut().pop().unwrap();
  49.                     return Ok(c2 - c1);
  50.                 }
  51.  
  52.                 b'*' => {
  53.                     let c1 = self.numbers.borrow_mut().pop().unwrap();
  54.                     let c2 = self.numbers.borrow_mut().pop().unwrap();
  55.                     return Ok(c2 * c1);
  56.                 }
  57.  
  58.                 b'/' => {
  59.                     let c1 = self.numbers.borrow_mut().pop().unwrap();
  60.                     let c2 = self.numbers.borrow_mut().pop().unwrap();
  61.                     if c1 == 0.0 {
  62.                         return Err("Divide By Zero".to_string());
  63.                     }
  64.                     return Ok(c2 / c1);
  65.                 }
  66.  
  67.                 b'%' => {
  68.                     let c1 = self.numbers.borrow_mut().pop().unwrap();
  69.                     let c2 = self.numbers.borrow_mut().pop().unwrap();
  70.                     if c1 == 0.0 {
  71.                         return Err("Divide By Zero".to_string());
  72.                     }
  73.                     return Ok(c2 % c1);
  74.                 }
  75.  
  76.                 b'^' => {
  77.                     let c1 = self.numbers.borrow_mut().pop().unwrap();
  78.                     let c2 = self.numbers.borrow_mut().pop().unwrap();
  79.                     return Ok(c2.powf(c1));
  80.                 }
  81.  
  82.                 _ => exit(0),
  83.             }
  84.         };
  85.  
  86.         for (index, &value) in bytes.iter().enumerate() {
  87.             match value {
  88.                 b'0' ..= b'9' | b'.' => {
  89.                     if vernier != b')' {    //数字前是右括号,则表达式错误。
  90.                         vernier = b'A';
  91.                         continue
  92.                     }
  93.                     return Err("Expression Error".to_string());
  94.                 }
  95.  
  96.                 ch @ b'+' | ch @ b'-' | ch @ b'*' | ch @ b'/' | ch @ b'%' | ch @ b'^' => {
  97.  
  98.                     let negative1 = ch == b'-' && vernier == b'(' && vernier != b'A';
  99.                     let negative2 = ch == b'-' && vernier != b')' && vernier != b'A' && vernier != b'-';
  100.  
  101.                     if negative1 == true || negative2 == true {    //检查是减号还是负号
  102.                         vernier = b'-';
  103.                         continue
  104.                     }else if vernier != b'A' && vernier != b')' {    //运算符前面是非数字、非右括号,则表达式错误。
  105.                         return Err("Expression Error".to_string());
  106.                     }
  107.  
  108.                     vernier = b'B';
  109.  
  110.                     if sign != b'A' {
  111.                         match expr[locat..index].parse::<f64>() {   //将运算符前的数字取出来
  112.                             Ok(value) => {
  113.                                 self.numbers.borrow_mut().push(value);   //读取的数字进栈
  114.                                 sign = b'A';
  115.                             }
  116.                             Err(_) => return Err("Invalid number".to_string()),
  117.                         }
  118.                     }
  119.  
  120.                     while self.operator.borrow().len() != 0 && self.operator.borrow().last().unwrap() != &b'(' {
  121.                         let p1 = priority(self.operator.borrow().last().unwrap());
  122.                         let p2 = priority(&ch);
  123.                         if p1 >= p2 {    //优先级比较
  124.                             let res = computing(self.operator.borrow().last().unwrap());    //调用二元运算函数
  125.                             match res {
  126.                                 Ok(_) => {
  127.                                     self.numbers.borrow_mut().push(res.unwrap());    //运算结果进栈
  128.                                     self.operator.borrow_mut().pop();    //运算符出栈
  129.                                 }
  130.                                 Err(_) => return res,
  131.                             }
  132.                         } else {
  133.                             break
  134.                         }
  135.                     }
  136.  
  137.                     self.operator.borrow_mut().push(ch);     //运算符进栈
  138.                     locat = index + 1;    //移动切片定位
  139.                     sign = b'B';
  140.                     continue
  141.                 }
  142.  
  143.                 ch @ b'(' => {
  144.                     if sign != b'A' && vernier != b'A' && vernier != b'-' {    //左括号前如果是数字或负号,则表达式错误。
  145.                         self.operator.borrow_mut().push(ch);     //左括号直接进栈
  146.                         locat = index + 1;   //移动切片定位
  147.                         bracket = bracket + 1;
  148.                         vernier = b'(';
  149.                         continue
  150.                     }
  151.                     return Err("Expression Error".to_string());
  152.                 }
  153.  
  154.                 b')' => {
  155.                     if sign != b'A' && vernier == b'A' {    //上一次进栈是运算符,同时括号前必须是数字。
  156.                         match expr[locat..index].parse::<f64>() {   //将运算符前的数字取出来
  157.                             Ok(value) => {
  158.                                 self.numbers.borrow_mut().push(value);   //读取的数字进栈
  159.                                 sign = b'A';
  160.                             }
  161.                             Err(_) => return Err("Invalid number".to_string()),
  162.                         }
  163.                     }
  164.  
  165.                     vernier = b')';
  166.  
  167.                     if bracket > 0 && sign == b'A' {    //运算符栈中必须有左括号,右括号前必须是数字。
  168.                         while self.operator.borrow().last().unwrap() != &b'(' {    //遇到左括号时停止循环
  169.                             let res = computing(&self.operator.borrow_mut().pop().unwrap());    //调用二元运算函数
  170.                             match res {
  171.                                 Ok(_) => self.numbers.borrow_mut().push(res.unwrap()),    //运算结果进栈
  172.                                 Err(_) => return res,
  173.                             }
  174.                         }
  175.  
  176.                         self.operator.borrow_mut().pop();     //左括号出栈
  177.                         locat = index + 1;     //移动切片定位
  178.                         bracket = bracket - 1;
  179.                         continue
  180.                     }
  181.  
  182.                     return Err("Expression Error".to_string());
  183.                 }
  184.  
  185.                 b'=' => {
  186.                     if bracket > 0 || vernier == b'-' || vernier == b'B' {    //等号前还有左括号、负号、运算符,则表达式错误。
  187.                         return Err("Expression Error".to_string());
  188.                     }
  189.  
  190.                     if sign != b'A' {
  191.                         match expr[locat..index].parse::<f64>() {   //将运算符前的数字取出来
  192.                             Ok(value) => {
  193.                                 self.numbers.borrow_mut().push(value);   //读取的数字进栈
  194.                                 sign = b'A';
  195.                             }
  196.                             Err(_) => return Err("Invalid number".to_string()),
  197.                         }
  198.                     }
  199.  
  200.                     while self.operator.borrow().len() != 0 {     //直到运算符栈为空停止循环
  201.                         let res = computing(&self.operator.borrow_mut().pop().unwrap());     //调用二元运算函数
  202.                         match res {
  203.                             Ok(_) => self.numbers.borrow_mut().push(res.unwrap()),    //运算结果进栈
  204.                             Err(_) => return res,
  205.                         }
  206.                     }
  207.  
  208.                     let res = self.numbers.borrow_mut().pop().unwrap();     //清空最后一个数据栈
  209.                     return Ok(res);
  210.                 }
  211.  
  212.                 b'A' => {
  213.                     vernier = b'A';
  214.                     if sign != b'A' {
  215.                         match expr[locat..index].parse::<f64>() {   //将运算符前的数字取出来
  216.                             Ok(value) => {
  217.                                 self.numbers.borrow_mut().push(value);   //读取的数字进栈
  218.                                 sign = b'A';
  219.                             }
  220.                             Err(_) => return Err("Invalid number".to_string()),
  221.                         }
  222.                     }
  223.  
  224.                     if sign == b'A' {
  225.                         let res = self.numbers.borrow_mut().pop().unwrap();
  226.                         self.numbers.borrow_mut().push(res.abs());    //Abs(X) X的绝对值
  227.                         locat = index + 1;    //移动切片定位
  228.                         continue
  229.                     }
  230.  
  231.                     return Err("Expression Error".to_string());
  232.                 }
  233.  
  234.                 b'S' => {
  235.                     vernier = b'A';
  236.                     if sign != b'A' {
  237.                         match expr[locat..index].parse::<f64>() {   //将运算符前的数字取出来
  238.                             Ok(value) => {
  239.                                 self.numbers.borrow_mut().push(value);   //读取的数字进栈
  240.                                 sign = b'A';
  241.                             }
  242.                             Err(_) => return Err("Invalid number".to_string()),
  243.                         }
  244.                     }
  245.  
  246.                     if sign == b'A' {
  247.                         let res = self.numbers.borrow_mut().pop().unwrap();
  248.                         if res >= 0.0 {
  249.                             self.numbers.borrow_mut().push(res.sqrt());    //Sqrt(X) X的平方根
  250.                             locat = index + 1;     //移动切片定位
  251.                             continue
  252.                         }
  253.                         return Err("Expression Error".to_string());
  254.                     }
  255.                     return Err("Expression Error".to_string());
  256.                 }
  257.  
  258.                 b'P' => {
  259.                     vernier = b'A';
  260.                     if sign != b'A' {     //标记符前面必须是字符或者为空
  261.                         self.numbers.borrow_mut().push(PI);    //Pi常量进入数字栈
  262.                         locat = index + 1;    //移动切片定位
  263.                         sign = b'A';
  264.                         continue
  265.                     }
  266.                     return Err("Expression Error".to_string());
  267.                 }
  268.  
  269.                 _ => return Err("Operator Error".to_string()),
  270.             }
  271.         }
  272.         Err("Possible Error".to_string())
  273.     }
  274. }
  275.  
  276. #[cfg(test)]
  277. mod test {
  278.     use super::Calculator;
  279.  
  280.     #[test]
  281.     fn test_add_fraction () {
  282.         let cal = Calculator::new(String::from("0.1+0.2="));
  283.         assert_eq!(0.3f64, cal.run().unwrap());
  284.     }
  285.    
  286.     #[test]
  287.     fn test_add_many_times() {
  288.         let cal = Calculator::new(String::from("0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+1="));
  289.         assert_eq!(1f64, cal.run().unwrap());
  290.     }
  291.    
  292.     #[test]
  293.     fn test_sub_many_times() {
  294.         let cal = Calculator::new(String::from("0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-1="));
  295.         assert_eq!(-1f64, cal.run().unwrap());
  296.     }
  297. }
  298.  
  299. fn main() {
  300.     // 四则混合运算(用法实例): '^'为乘方运算符 . '%'为求模运算符
  301.     let test1 = Calculator::new(String::from("10-3*(2/1-(6*2+(21+3/5)*8/3)*-2)+8*2^2%3="));
  302.     match test1.run() {
  303.         Ok(value) => println!("{}", value),
  304.         Err(msg) => println!("{}", msg),
  305.     }
  306.     // 函数混合运算(用法实例): "A=ABS" . "S=SQRT" . "P=PI"('P'被直接视为数字)
  307.     let test2 = Calculator::new(String::from("10*(2/1-(6*2+(-21.5A+3/5)-8*P/3)*23.5S)+8*2^2%3="));
  308.     match test2.run() {
  309.         Ok(value) => println!("{}", value),
  310.         Err(msg) => println!("{}", msg),
  311.     }
  312. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top