Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::process::exit;
- use std::cell::RefCell;
- struct Calculator {
- numbers: RefCell<Vec<f64>>,
- operator: RefCell<Vec<u8>>,
- expression: String,
- }
- impl Calculator {
- pub fn new(expr: String) -> Self {
- Calculator {
- numbers: RefCell::new(Vec::new()),
- operator: RefCell::new(Vec::new()),
- expression: expr,
- }
- }
- pub fn run(&self) -> Result<f64, String> {
- let mut sign: u8 = 0; //入栈签名
- let mut vernier: u8 = 0; //移动游标
- let mut locat: usize = 0; //切片定位
- let mut bracket: u32 = 0; //括号标记
- let expr = &self.expression;
- let bytes = self.expression.as_bytes();
- const PI: f64 = 3.141592653589793;
- let priority = |x: &u8| -> u8 {
- match x {
- b'+' | b'-' => 1,
- b'*' | b'/' | b'%' => 2,
- b'^' => 3,
- _ => exit(0),
- }
- };
- let computing = |x: &u8| -> Result<f64, String> {
- match x {
- b'+' => {
- let c1 = self.numbers.borrow_mut().pop().unwrap();
- let c2 = self.numbers.borrow_mut().pop().unwrap();
- return Ok(c2 + c1);
- }
- b'-' => {
- let c1 = self.numbers.borrow_mut().pop().unwrap();
- let c2 = self.numbers.borrow_mut().pop().unwrap();
- return Ok(c2 - c1);
- }
- b'*' => {
- let c1 = self.numbers.borrow_mut().pop().unwrap();
- let c2 = self.numbers.borrow_mut().pop().unwrap();
- return Ok(c2 * c1);
- }
- b'/' => {
- let c1 = self.numbers.borrow_mut().pop().unwrap();
- let c2 = self.numbers.borrow_mut().pop().unwrap();
- if c1 == 0.0 {
- return Err("Divide By Zero".to_string());
- }
- return Ok(c2 / c1);
- }
- b'%' => {
- let c1 = self.numbers.borrow_mut().pop().unwrap();
- let c2 = self.numbers.borrow_mut().pop().unwrap();
- if c1 == 0.0 {
- return Err("Divide By Zero".to_string());
- }
- return Ok(c2 % c1);
- }
- b'^' => {
- let c1 = self.numbers.borrow_mut().pop().unwrap();
- let c2 = self.numbers.borrow_mut().pop().unwrap();
- return Ok(c2.powf(c1));
- }
- _ => exit(0),
- }
- };
- for (index, &value) in bytes.iter().enumerate() {
- match value {
- b'0' ..= b'9' | b'.' => {
- if vernier != b')' { //数字前是右括号,则表达式错误。
- vernier = b'A';
- continue
- }
- return Err("Expression Error".to_string());
- }
- ch @ b'+' | ch @ b'-' | ch @ b'*' | ch @ b'/' | ch @ b'%' | ch @ b'^' => {
- let negative1 = ch == b'-' && vernier == b'(' && vernier != b'A';
- let negative2 = ch == b'-' && vernier != b')' && vernier != b'A' && vernier != b'-';
- if negative1 == true || negative2 == true { //检查是减号还是负号
- vernier = b'-';
- continue
- }else if vernier != b'A' && vernier != b')' { //运算符前面是非数字、非右括号,则表达式错误。
- return Err("Expression Error".to_string());
- }
- vernier = b'B';
- if sign != b'A' {
- match expr[locat..index].parse::<f64>() { //将运算符前的数字取出来
- Ok(value) => {
- self.numbers.borrow_mut().push(value); //读取的数字进栈
- sign = b'A';
- }
- Err(_) => return Err("Invalid number".to_string()),
- }
- }
- while self.operator.borrow().len() != 0 && self.operator.borrow().last().unwrap() != &b'(' {
- let p1 = priority(self.operator.borrow().last().unwrap());
- let p2 = priority(&ch);
- if p1 >= p2 { //优先级比较
- let res = computing(self.operator.borrow().last().unwrap()); //调用二元运算函数
- match res {
- Ok(_) => {
- self.numbers.borrow_mut().push(res.unwrap()); //运算结果进栈
- self.operator.borrow_mut().pop(); //运算符出栈
- }
- Err(_) => return res,
- }
- } else {
- break
- }
- }
- self.operator.borrow_mut().push(ch); //运算符进栈
- locat = index + 1; //移动切片定位
- sign = b'B';
- continue
- }
- ch @ b'(' => {
- if sign != b'A' && vernier != b'A' && vernier != b'-' { //左括号前如果是数字或负号,则表达式错误。
- self.operator.borrow_mut().push(ch); //左括号直接进栈
- locat = index + 1; //移动切片定位
- bracket = bracket + 1;
- vernier = b'(';
- continue
- }
- return Err("Expression Error".to_string());
- }
- b')' => {
- if sign != b'A' && vernier == b'A' { //上一次进栈是运算符,同时括号前必须是数字。
- match expr[locat..index].parse::<f64>() { //将运算符前的数字取出来
- Ok(value) => {
- self.numbers.borrow_mut().push(value); //读取的数字进栈
- sign = b'A';
- }
- Err(_) => return Err("Invalid number".to_string()),
- }
- }
- vernier = b')';
- if bracket > 0 && sign == b'A' { //运算符栈中必须有左括号,右括号前必须是数字。
- while self.operator.borrow().last().unwrap() != &b'(' { //遇到左括号时停止循环
- let res = computing(&self.operator.borrow_mut().pop().unwrap()); //调用二元运算函数
- match res {
- Ok(_) => self.numbers.borrow_mut().push(res.unwrap()), //运算结果进栈
- Err(_) => return res,
- }
- }
- self.operator.borrow_mut().pop(); //左括号出栈
- locat = index + 1; //移动切片定位
- bracket = bracket - 1;
- continue
- }
- return Err("Expression Error".to_string());
- }
- b'=' => {
- if bracket > 0 || vernier == b'-' || vernier == b'B' { //等号前还有左括号、负号、运算符,则表达式错误。
- return Err("Expression Error".to_string());
- }
- if sign != b'A' {
- match expr[locat..index].parse::<f64>() { //将运算符前的数字取出来
- Ok(value) => {
- self.numbers.borrow_mut().push(value); //读取的数字进栈
- sign = b'A';
- }
- Err(_) => return Err("Invalid number".to_string()),
- }
- }
- while self.operator.borrow().len() != 0 { //直到运算符栈为空停止循环
- let res = computing(&self.operator.borrow_mut().pop().unwrap()); //调用二元运算函数
- match res {
- Ok(_) => self.numbers.borrow_mut().push(res.unwrap()), //运算结果进栈
- Err(_) => return res,
- }
- }
- let res = self.numbers.borrow_mut().pop().unwrap(); //清空最后一个数据栈
- return Ok(res);
- }
- b'A' => {
- vernier = b'A';
- if sign != b'A' {
- match expr[locat..index].parse::<f64>() { //将运算符前的数字取出来
- Ok(value) => {
- self.numbers.borrow_mut().push(value); //读取的数字进栈
- sign = b'A';
- }
- Err(_) => return Err("Invalid number".to_string()),
- }
- }
- if sign == b'A' {
- let res = self.numbers.borrow_mut().pop().unwrap();
- self.numbers.borrow_mut().push(res.abs()); //Abs(X) X的绝对值
- locat = index + 1; //移动切片定位
- continue
- }
- return Err("Expression Error".to_string());
- }
- b'S' => {
- vernier = b'A';
- if sign != b'A' {
- match expr[locat..index].parse::<f64>() { //将运算符前的数字取出来
- Ok(value) => {
- self.numbers.borrow_mut().push(value); //读取的数字进栈
- sign = b'A';
- }
- Err(_) => return Err("Invalid number".to_string()),
- }
- }
- if sign == b'A' {
- let res = self.numbers.borrow_mut().pop().unwrap();
- if res >= 0.0 {
- self.numbers.borrow_mut().push(res.sqrt()); //Sqrt(X) X的平方根
- locat = index + 1; //移动切片定位
- continue
- }
- return Err("Expression Error".to_string());
- }
- return Err("Expression Error".to_string());
- }
- b'P' => {
- vernier = b'A';
- if sign != b'A' { //标记符前面必须是字符或者为空
- self.numbers.borrow_mut().push(PI); //Pi常量进入数字栈
- locat = index + 1; //移动切片定位
- sign = b'A';
- continue
- }
- return Err("Expression Error".to_string());
- }
- _ => return Err("Operator Error".to_string()),
- }
- }
- Err("Possible Error".to_string())
- }
- }
- #[cfg(test)]
- mod test {
- use super::Calculator;
- #[test]
- fn test_add_fraction () {
- let cal = Calculator::new(String::from("0.1+0.2="));
- assert_eq!(0.3f64, cal.run().unwrap());
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement