Advertisement
Guest User

Untitled

a guest
Mar 21st, 2019
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.64 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement