2014-01-28 74 views
4

我在Java中實現Shunting Yard Algorithm,作爲我的AP計算機科學類的一個側面項目。我用Javascript實現了一個簡單的算法,只有基本的算術表達式(加法,減法,乘法,除法,求冪)。爲了將它拆分成一個數組,我所做的是找到每個運算符(+-*/^)以及數字和括號,然後在它們周圍放置一個空格,然後將其分割成一個數組。例如,中綴字符串4+(3+2)將被製作爲4 + (3 + 2),然後在空白處分割。在Java中Tokenizing中綴字符串

但是,我覺得這種方法非常慢,並且隨着您開始添加數學函數(例如正弦,餘弦,正切,絕對值等)而變得越來越難以實施。

sin(4+3)-8這樣的字符串拆分爲數組["sin","(" 4,"+",3,")","-",8]的最佳方法是什麼?

我可以用這個正則表達式,但我並沒有很好地理解它們,而且我試圖去了解它們,所以如果這對他們來說是最好的解決方案,請問解答器能解釋它的作用嗎?

回答

3

嘗試在正則表達式

(?<=[^\.a-zA-Z\d])|(?=[^\.a-zA-Z\d]) 

.split ING它將在其或者之前或之後的非字母數字字符或期間的任何地方分割字符串。

  • (?<=[^\.a-zA-Z\d])positive lookbehind。如果前面的字符串匹配(?<=...)中包含的子正則表達式,它匹配兩個字符之間的地方。
    • [^\.a-zA-Z\d]negated character class。它匹配中未包含的單個字符
      • \.符合字符.
      • a-z匹配az之間的任何小寫字符。
      • A-Z是一樣的,但是對於大寫字母。
      • \d相當於[0-9],所以它匹配任何數字。
  • |the equivalent of an "or"。它使正則表達式匹配正則表達式的前半部分或後半部分。
  • (?=[^\.a-zA-Z\d])與正則表達式的前半部分相同,只不過它是positive lookahead。它匹配兩個字符之間的地方,如果後面的字符串與(?=...)中包含的子正則表達式匹配。

您可以實現這個表達式在Java這樣的:

String str = "sin(4+3)-8"; 
String[] parts = str.split("(?<=[^\\.a-zA-Z\\d])|(?=[^\\.a-zA-Z\\d])"); 

結果:

["sin","(" 4,"+",3,")","-","8"]