Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7400034
  • 博文数量: 1756
  • 博客积分: 18684
  • 博客等级: 上将
  • 技术积分: 16232
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-02 10:28
个人简介

啥也没写

文章分类

全部博文(1756)

文章存档

2024年(2)

2023年(44)

2022年(39)

2021年(46)

2020年(43)

2019年(27)

2018年(44)

2017年(50)

2016年(47)

2015年(15)

2014年(21)

2013年(43)

2012年(143)

2011年(228)

2010年(263)

2009年(384)

2008年(246)

2007年(30)

2006年(38)

2005年(2)

2004年(1)

分类: 系统运维

2017-06-01 19:01:31


点击(此处)折叠或打开

  1. package main

  2. import (
  3.     "flag"
  4.     "fmt"
  5.     "strconv"
  6. )

  7. type StackNode struct {
  8.     Data interface{}
  9.     next *StackNode
  10. }

  11. type LinkStack struct {
  12.     top *StackNode
  13.     Count int
  14. }

  15. func (this *LinkStack) Init() {
  16.     this.top = nil
  17.     this.Count = 0
  18. }

  19. func (this *LinkStack) Push(data interface{}) {
  20.     var node *StackNode = new(StackNode)
  21.     node.Data = data
  22.     node.next = this.top
  23.     this.top = node
  24.     this.Count++
  25. }

  26. func (this *LinkStack) Pop() interface{} {
  27.     if this.top == nil {
  28.         return nil
  29.     }
  30.     returnData := this.top.Data
  31.     this.top = this.top.next
  32.     this.Count--
  33.     return returnData
  34. }

  35. //Look up the top element in the stack, but not pop.
  36. func (this *LinkStack) LookTop() interface{} {
  37.     if this.top == nil {
  38.         return nil
  39.     }
  40.     return this.top.Data
  41. }

  42. func main() {
  43.     str := flag.String("expression", "3?5*4-5*8/3+78*9", "expression")
  44.     flag.Parse()
  45.     fmt.Println("expression:", *str)
  46.     fmt.Println(Count(*str))
  47. }

  48. func Count(data string) float64 {
  49.     //TODO 检查字符串输入
  50.     var arr []string = generateRPN(data)
  51.     return calculateRPN(arr)
  52. }

  53. func calculateRPN(datas []string) float64 {
  54.     var stack LinkStack
  55.     stack.Init()
  56.     for i := 0; i < len(datas); i++ {
  57.         fmt.Println(datas[i])
  58.         if isNumberString(datas[i]) {
  59.             if f, err := strconv.ParseFloat(datas[i], 64); err != nil {
  60.                 panic("operatin process go wrong.")
  61.             } else {
  62.                 stack.Push(f)
  63.             }
  64.         } else {
  65.             p1 := stack.Pop().(float64)
  66.             p2 := stack.Pop().(float64)
  67.             p3 := normalCalculate(p2, p1, datas[i])
  68.             stack.Push(p3)
  69.         }
  70.     }
  71.     res := stack.Pop().(float64)
  72.     return res
  73. }

  74. func normalCalculate(a, b float64, operation string) float64 {
  75.     switch operation {
  76.     case "*":
  77.         return a * b
  78.     case "-":
  79.         return a - b
  80.     case "+":
  81.         return a + b
  82.     case "/":
  83.         return a / b
  84.     default:
  85.         panic("invalid operator")
  86.     }
  87. }

  88. func generateRPN(exp string) []string {
  89.     var stack LinkStack
  90.     stack.Init()
  91.     var spiltedStr []string = convertToStrings(exp)
  92.     var datas []string

  93.     for i := 0; i < len(spiltedStr); i++ { // 遍历每一个字符
  94.         tmp := spiltedStr[i] //当前字符
  95.         if !isNumberString(tmp) { //是否是数字
  96.             // 四种情况入栈
  97.             // 1 左括号直接入栈
  98.             // 2 栈内为空直接入栈
  99.             // 3 栈顶为左括号,直接入栈
  100.             // 4 当前元素不为右括号时,在比较栈顶元素与当前元素,如果当前元素大,直接入栈。
  101.             if tmp == "(" ||
  102.                 stack.LookTop() == nil || stack.LookTop().(string) == "(" ||
  103.                 (compareOperator(tmp, stack.LookTop().(string)) == 1 && tmp != ")") {
  104.                 stack.Push(tmp)
  105.             } else { // ) priority
  106.                 if tmp == ")" { //当前元素为右括号时,提取操作符,直到碰见左括号
  107.                     for {
  108.                         if pop := stack.Pop().(string); pop == "(" {
  109.                             break
  110.                         } else {
  111.                             datas = append(datas, pop)
  112.                         }
  113.                     }
  114.                 } else { //当前元素为操作符时,不断地与栈顶元素比较直到遇到比自己小的(或者栈空了),然后入栈。
  115.                     for {
  116.                         pop := stack.LookTop()
  117.                         if pop != nil && compareOperator(tmp, pop.(string)) != 1 {
  118.                             datas = append(datas, stack.Pop().(string))
  119.                         } else {
  120.                             stack.Push(tmp)
  121.                             break
  122.                         }
  123.                     }
  124.                 }
  125.             }
  126.         } else {
  127.             datas = append(datas, tmp)
  128.         }
  129.     }
  130.     //将栈内剩余的操作符全部弹出。
  131.     for {
  132.         if pop := stack.Pop(); pop != nil {
  133.             datas = append(datas, pop.(string))
  134.         } else {
  135.             break
  136.         }
  137.     }
  138.     return datas
  139. }

  140. // if return 1, o1 > o2.
  141. // if return 0, o1 = 02
  142. // if return -1, o1 < o2
  143. func compareOperator(o1, o2 string) int {
  144.     // + - * /
  145.     var o1Priority int
  146.     if o1 == "+" || o1 == "-" {
  147.         o1Priority = 1
  148.     } else {
  149.         o1Priority = 2
  150.     }
  151.     var o2Priority int
  152.     if o2 == "+" || o2 == "-" {
  153.         o2Priority = 1
  154.     } else {
  155.         o2Priority = 2
  156.     }
  157.     if o1Priority > o2Priority {
  158.         return 1
  159.     } else if o1Priority == o2Priority {
  160.         return 0
  161.     } else {
  162.         return -1
  163.     }
  164. }

  165. func isNumberString(o1 string) bool {
  166.     if o1 == "+" || o1 == "-" || o1 == "*" || o1 == "/" || o1 == "(" || o1 == ")" {
  167.         return false
  168.     } else {
  169.         return true
  170.     }
  171. }

  172. func convertToStrings(s string) []string {
  173.     var strs []string
  174.     bys := []byte(s)
  175.     var tmp string
  176.     for i := 0; i < len(bys); i++ {
  177.         if !isNumber(bys[i]) {
  178.             if tmp != "" {
  179.                 strs = append(strs, tmp)
  180.                 tmp = ""
  181.             }
  182.             strs = append(strs, string(bys[i]))
  183.         } else {
  184.             tmp = tmp + string(bys[i])
  185.         }
  186.     }
  187.     strs = append(strs, tmp)
  188.     return strs
  189. }

  190. func isNumber(o1 byte) bool {
  191.     if o1 == '+' || o1 == '-' || o1 == '*' || o1 == '/' || o1 == '(' || o1 == ')' {
  192.         return false
  193.     } else {
  194.         return true
  195.     }
  196. }

阅读(862) | 评论(0) | 转发(0) |
0

上一篇:搭建流媒体服务器

下一篇:yum安装MySQL5.7

给主人留下些什么吧!~~