2015-10-06 38 views
2

給出一個多項式,我試圖編寫代碼來創建一個多項式的程度的推移,和類似的術語相加比如......給的Java:StringTokenizer按照陣列

String term = "323x^3+2x+x-5x+5x^2" //Given 
What I'd like = "323x^3+5x^2-2x" //result 

到目前爲止,我「已經符號化給定的多項式除以這個...

term = term.replace("+" , "~+"); 
    term = term.replace("-", "~-"); 
    System.out.println(term); 
    StringTokenizer multiTokenizer = new StringTokenizer(term, "~"); 
    int numberofTokens = multiTokenizer.countTokens(); 
    String[] tokensArray = new String[numberofTokens]; 
    int x=0; 
    while (multiTokenizer.hasMoreTokens()) 
    { 

     System.out.println(multiTokenizer.nextToken()); 

    } 

從而造成

323x^3~+2x~+x~-5x~+5x^2 
323x^3 
+2x 
+x 
-5x 
+5x^2 

我怎麼會去splitt從x值中選擇係數,將每個係數保存在一個數組中,然後將這些度數放在與係數相同的不同數組中?然後,我將使用此算法添加類似術語....

for (i=0;i<=biggest_Root; i++) 
    for(j=0; j<=items_in_list ; j++) 
      if (degree_array[j] = i) 
       total += b1[j]; 
    array_of_totals[i] = total; 

任何和所有的幫助,非常感謝!

+0

我不能很好地理解您的問題 –

回答

2

您也可以更新條款,以便它們都具有係數:

s/([+-])x/\11/g 

那麼+ X^2 +成爲1X^2。

您的個人係數可以通過簡單的正則表達式拉出。 像這樣就足夠了:

/([+-]?\d+)x/  // match for x 
/([+-]?\d+)x\^2/ // match for x^2 
/([+-]?\d+)x\^3/ // match for x^3 
/([+-]?\d+)x\^4/ // match for x^4 

然後

sum_of_coefficient[degree] += match 

其中「匹配」是正則表達式匹配的parseInt函數(其中,係數爲1,並且沒有數例如特例+ X)。

sum_of_coefficient[3] = 323 
sum_of_coefficient[1] = +2+1-5 = -2 
sum_of_coefficient[2] = 5 
0

這看起來像一個家庭作業的問題,所以我不會在這裏透露一個完整的答案,但這裏是我怎麼會開始

public class Polynomial { 

private String rawPolynomial; 
private int lastTermIndex = 0; 
private Map<Integer, Integer> terms = new HashMap<>(); 

public Polynomial(String poly) { 
    this.rawPolynomial = poly; 
} 

public void simplify() { 
    while(true){ 
     String term = getNextTerm(rawPolynomial); 
     if ("".equalsIgnoreCase(term)) { 
      return; 
     } 
     Integer degree = getDegree(term); 
     Integer coeff = getCoefficient(term); 
     System.out.println(String.format("%dx^%d", coeff, degree)); 
     terms.merge(degree, coeff, Integer::sum); 
    } 
} 

private String getNextTerm(String poly) { 
... 
} 

private Integer getDegree(String poly) { 
    ... 
} 

private Integer getCoefficient(String poly) { 
    ... 
} 

@Override public String toString() { 
    return terms.toString(); 
} 
} 

和一些測試,讓你開始 -

public class PolynomialTest { 
    @Test public void oneTermPolynomialRemainsUnchanged() { 
     Polynomial poly = new Polynomial("3x^2"); 
     poly.simplify(); 
     assertTrue("3x^2".equalsIgnoreCase(poly.toString())); 
    } 

} 

你應該能夠填補空白,希望這有助於。如果你被困在某個地方,我會很樂意幫助你。

2

使用「正則表達式」模式,以簡化解析

和使代碼冷卻器和更簡潔

這裏是一個分析係數,可變和度爲一個工作示例每個術語基於迄今爲止解析的術語。它只是將示例中顯示的術語插入到字符串列表中,然後以相同的方式處理每個字符串。

該程序運行並生成輸出,如果你喜歡它,你可以將它拼接到你的程序中。試試看:

$ javac parse。java的

$ java的解析

侷限性和潛在的改進:

從技術上講係數和程度可能是小數,因此正則表達式可以很容易地改變來處理這些類型的數字。然後代替Integer.parseInt(),您可以使用Float.parseFloat()來將匹配的值轉換爲您可以使用的變量。

import java.util.*; 
import java.util.regex.*; 

public class parse { 
    public static void main(String args[]) { 

     /* 
     * Substitute this List with your own list or 
     * array from the code you've written already... 
     * 
     * vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ 

     List<String>terms = new ArrayList<String>(); 
     terms.add("323x^3"); 
     terms.add("+2x"); 
     terms.add("+x"); 
     terms.add("-5x"); 
     terms.add("+5x^2"); 

     /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ 

     for (String term : terms) { 

      System.out.print("Term: " + term + ": \n"); 

      Pattern pattern = Pattern.compile("([+-]*\\d*)([A-Za-z]*)\\^*(\\d*)"); 
      Matcher matcher = pattern.matcher(term); 

      if (matcher.find()) { 

       int coefficient = 1; 
       try { 
        coefficient = Integer.parseInt(matcher.group(1)); 
       } catch (Exception e) {} 

       String variable = matcher.group(2); 

       int degree = 1; 
       try { 
        degree = Integer.parseInt(matcher.group(3)); 
       } catch (Exception e) {} 

       System.out.println(" coefficient = " + coefficient); 
       System.out.println(" variable = " + variable); 
       System.out.println(" degree  = " + degree); 

       /* 
       * Here, do what you need to do with 
       *  variable, coefficient and degree 
       */ 

      } 
     } 
    } 
} 

說明在實施例的代碼的正則表達式的:

這是所使用的正則表達式:

([+-]*\\d*)([A-Za-z]*)\\^*(\\d*) 

每個括號中的部分表示I要匹配的術語的一部分和提取到我的結果。它將與該組圓括號相對應的組中的任何匹配。第一組括號進入組1,第二成組2等...

  1. 第一匹配器(由()分組),是([+-]*\\d*) ,其被設計匹配(例如提取液)的係數(如果有的話)並將其放入第1組中。它期望有零或多個出現'+'或' - '字符的零個或多個數字。我大概應該寫在[+-]?\\d*哪個匹配一個+-字符。

  2. 下一個分組匹配器是([A-Za-z]*)這表示匹配零個或多個大寫或小寫字母。 正試圖如有提取變量名,並將其放入組2

  3. 在此之後,有一個未分組\\^*,它匹配0個或更多字符^。它沒有被分組在括號中,因爲我們想要在文本中考慮^字符,但不能將它存儲在任何地方。我們對它後面的指數非常感興趣。 注意:兩個反斜槓是您如何在Java字符串中創建一個反斜槓。我們試圖表示的真實世界正則表達式是\^*。這裏逃脫的原因是因爲^未轉義在正則表達式中有特殊含義,但我們只想匹配/允許在我們解析的代數術語中在該位置處存在實際脫字符號的可能性。

  4. 最終模式組爲(\\d*)。除了字符串文字以外,正如大多數正則表達式的情況一樣,這隻會是\d*。它逃脫了,因爲,在默認情況下,在一個正則表達式,d,轉義,是指在文本的當前位置匹配文字d,但是,逃跑了,\d是匹配匹配任何數字[0-9](作爲模式的特定正則表達式模式javadoc解釋)。 *意味着期望(匹配)零點或更多位數。或者,+意味着期望在當前位置的文本中有一個或多個數字,並且?將意味着在當前位置的文本中預期有0或1個數字。因此,從本質上講,在最後一組的設計相匹配,並提取可選插入符後指數(如果有的話),把這個數字變成組3

記住()(括號)分組只是讓我們可以將這些區域解壓縮到單獨的組中。

如果這並不完全合理,請一般學習正則表達式並閱讀Java Pattern class javadoc online。這並不像他們第一次看到那樣可怕,對於任何程序員來說都是非常值得的研究,因爲它跨越了大多數流行的腳本語言和編譯器,所以只需學習一次,並且擁有一個非常強大的終身工具。

+0

您能否介紹一下模式和匹配器的工作原理?我對這部分有點困惑,如果例如一個數字沒有任何變量,我將如何去設置變量爲NULL? – Aaron

+0

我更新了文本以解釋我如何編寫[Pattern](http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html)作品。一般閱讀[正則表達式](http://www.zytrax.com/tech/web/regex.htm)。並找到使用Pattern獲得更多幫助的Java示例代碼。我*認爲*如果您省略x,則匹配應該起作用。請參閱上述第二部分的描述。它旨在允許沒有變量名稱。最好的事情是編譯它並進行實驗。您可以更改代碼中的術語,並根據模式javadoc使用正則表達式進行修改。祝你好運! – clearlight

+0

令人驚歎的細節,我不能夠感謝你。最後一個問題,將字符串標記器中的標記放置到數組列表中,就像創建一個新的數組列表並創建一個循環來執行'terms.add(StringTokenizer.next())'一樣簡單。 – Aaron