簡體   English   中英

Scala-代數運算字符串

[英]Scala - string of algebraic operations

我有一個表示一些基本代數運算的字符串,例如:

 "42 * 67 + 4"

我想要一個類型的函數

 function (operation: String) : Int = {}

這樣它需要一串代數運算並返回實際的最終值,在這種情況下:2818

我會知道如何從這樣的字符串中提取數字,但是我還不清楚如何提取諸如“ +”,“-”,“ *”,“ /”之類的數學運算並實際進行計算。

在沒有任何外部庫的情況下,實現Shunting-yard算法來進行這種計算非常簡單:

def calculate(operation: String): Int = {
  var results: List[Int] = Nil
  var operators: List[String] = Nil

  def precedence(operator: String) = operator match {
    case "+" | "-" => 0
    case "*" | "/" => 1
  }

  def execute(operator: String): Unit = {
    (results, operator) match {
      case (x :: y :: rest, "+") => results = (y + x) :: rest
      case (x :: y :: rest, "-") => results = (y - x) :: rest
      case (x :: y :: rest, "*") => results = (y * x) :: rest
      case (x :: y :: rest, "/") => results = (y / x) :: rest
      case (_, _) => throw new RuntimeException("Not enough arguments")
    }
  }

  for (term <- "[1-9][0-9]*|[-+/*]".r.findAllIn(operation)) {
    util.Try(term.toInt) match {
      case util.Success(number) => results ::= number
      case _ =>
        val (operatorsToExecute, rest) = 
          operators.span(op => precedence(op) >= precedence(term))
        operatorsToExecute foreach execute
        operators = term :: rest
    }
  }
  operators foreach execute

  results match {
    case res :: Nil => res
    case _ => throw new RuntimeException("Too many arguments")
  }
}

這使用整數除法:

scala> calculate("3 / 2")
res0: Int = 1

並具有正確的加法和乘法優先級:

scala> calculate("2 + 2 * 2")
res1: Int = 6

支持:

  • 更多的操作,
  • 括號,例如2 * (2 + 2)
  • 浮點計算
  • 更好地測試公式的內容(目前,它只忽略數字和運算符以外的所有字符)
  • 不拋出錯誤(例如,返回Try[Int]Option[Int]等,而不是返回裸Int或拋出錯誤的當前行為)

留給讀者練習。

對於更復雜的事情,當然最好使用scala-parser-combinators或其他答案中建議的某些第三方解析庫。

因此,@GáborBakos發布了他的笑話評論,而我仍在撰寫和測試我的笑話答案,但無論如何我都會將其發布。

注意:有效。 有時。 一點點。 注意2:這是個玩笑!

def function(operation: String) = {
  val js = new javax.script.ScriptEngineManager().getEngineByName("JavaScript")
  js.eval(operation) match { case i: Integer => i.asInstanceOf[Int] }
}

function("42 * 67 + 4")
// => 2818 : Int

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM