2020年3月1日 星期日

[zerojudge]a017. 五則運算

a017. 五則運算

先乘除後加減、括號優先程式是怎麼寫的?!不知道你小時後有沒有想過這種問題,至少我是沒有啦:D

做這題要先了解堆疊,對堆疊(Stack)這種資料結構不熟的話可以看看【Ken將】電腦課小教室 - Class.Null - 堆疊與佇列 ,再來了解運算式的前序、中序、後序表示法資料結構教學 : Infix 轉 Postfix
手稿

手稿

程式碼如下:

  1. /*a017. 五則運算
  2. *
  3. * 2020/2/28
  4. */
  5. import java.util.Scanner;
  6. import java.util.Stack;
  7.  
  8. public class Pa017{
  9.  
  10. public static void main(String[] args){
  11. Scanner scanner = new Scanner(System.in);
  12.  
  13. while(scanner.hasNext()){
  14. System.out.println(evaluate(scanner.nextLine()));
  15. }
  16. }
  17.  
  18. public static int evaluate(String s){
  19. String[] exp = s.split(" ");
  20.  
  21. Stack ops = new Stack();
  22. Stack vals = new Stack();
  23. for(String token: exp){
  24. if("(".equals(token)){
  25. ops.push(token);
  26. }else if(")".equals(token)){
  27. // 不斷計算直到遇到右括號
  28. while(!"(".equals(ops.peek())){
  29. vals.push(calc(vals.pop(), ops.pop(), vals.pop()));
  30. }
  31. // 把遇到的右括號pop掉
  32. ops.pop();
  33. }else if("+-*/%".contains(token)){
  34. // 如果ops還有運算子 且 ops最頂層運算子的優先順序 >= token運算子的優先順序
  35. while(!ops.isEmpty() && priority(ops.peek()) >= priority(token)){
  36. vals.push(calc(vals.pop(), ops.pop(), vals.pop()));
  37. }
  38. ops.push(token);
  39. }else{
  40. vals.push(Integer.parseInt(token));
  41. }
  42. }
  43. while(!ops.isEmpty()){
  44. vals.push(calc(vals.pop(), ops.pop(), vals.pop()));
  45. }
  46. return vals.pop();
  47. }
  48. public static int priority(String op){
  49. return "*/%".contains(op) ? 2 : "+-".contains(op) ? 1 : 0;
  50. }
  51. // ab位置對調
  52. public static int calc(int b, String operator, int a){
  53. switch(operator){
  54. case "+": return a + b;
  55. case "-": return a - b;
  56. case "*": return a * b;
  57. case "/": return a / b;
  58. case "%": return a % b;
  59. default:
  60. System.out.println("unknown operator");
  61. return 0;
  62. }
  63. }
  64. }

沒有留言:

張貼留言