2012-07-30 102 views
2

我有一個簡單的問題,但最近它一直在推動着我的堅果。 我正在製作化學程序(Android應用程序,更具體),我有一種方法可以分離用戶輸入的元素。例如,如果有人輸入「FeZnKPb」,它將被分成「Fe」,「Zn」,「K」和「Pb」。嵌套For-Loops - 使用數組對象分隔字符串元素

爲此,我使用了幾個嵌套循環和變量來控制它。我擁有Chem []數組中定義的所有元素。然後將分隔的元素存儲在名爲savedChem []的數組中。它基本上只是遍歷所有元素常量(Chem []),並將這些元素的名稱和公式複製到savedChem []中,如果它與輸入匹配的話。

這裏是我的代碼如下:

public void separateElements(String Input) 
{ 
    boolean found = false; 
    int start = 0; 
    int end = 2; 
    int length = Input.length(); 

    while(length >= end) 
    { 
     for(int x = 0; x < numChemicals; x++) 
     { 
      if((end + 0) > length) 
      { 
       end += 5; 
       break; 
      } 
      if(Input.substring(start, end).equals(Chem[x].getFormula())) 
      { 
       savedChem[numSaved].setName(Chem[x].getName()); 
       savedChem[numSaved].setFormula(Chem[x].getFormula()); 
       numSaved++; 
       start += 2; 
       end += 2; 
       found = true; 
      } 
      else 
      { 
       found = false; 
      } 
     } 
     if(!found) 
     { 
      start += 2; 
      end += 2; 
     } 
    } 
} 

我的問題是,它只有2個字符的元素,如「鐵」或「鋅」的作品。我希望它也能識別像「K」的其他人。另一個問題是,它有時會跳過一些其他元素。例如,如果我輸入「FeZnHg」,它會將它們分離爲「Fe」,「Zn」和「Hg」。但是,如果我按照「ZnFeHg」這樣的不同順序輸入它們,則由於某種原因,它只能檢測到「Zn」和「Hg」,而不是「Fe」。

還有什麼其他方法可以解決這個問題,使其正常工作?

+1

是否正確的大小寫敏感性約束?也就是說,水星會一直汞,或者它可能會顯示爲HG? – 2012-07-30 22:37:25

+0

您是否嘗試過一步一步地調試代碼?還是用一個正則表達式。 – Bhaskar 2012-07-30 22:46:23

+0

@NathanielFord是的,它永遠是這樣的。我有另一種方法來糾正這種情況。 – Pkmmte 2012-07-30 22:58:13

回答

5

鑑於元素總是或者是大寫字母和一個或兩個小寫字母(而且兩個只在一些非常短的元素的情況下),你可以使用正則表達式來分割你的輸入到短字符串中。

您可以使用split方法和一些lookahead將字符串拆分爲元素字符串。以納撒尼爾·福特的評論到:

public enum ChemicalElement { 
    F, Fe, Zn, K, Pb, Umm, //and so on... 
} 

public List<ChemicalElement> separateElements(String input) { 
    String[] inputParts = input.split("(?=[A-Z]{1,1}[a-z]{0,2})"); 

    List<ChemicalElement> elementList = new LinkedList<ChemicalElement>(); 
    for (int i = 1; i < inputParts.length; i++) { 
     String inputPart = inputParts[i]; 

     // note: throws IllegalArgumentException for unknown elements 
     ChemicalElement element = ChemicalElement.valueOf(inputPart); 
     if (null != element) { 
      elementList.add(element); 
     } 

    } 
    return elementList; 
} 

所以測試輸入這樣的:

String input = "FeZnKPbUmmK"; 
List<ChemicalElement> elements = this.separateElements(input); 

會給你下面的列表:

[鐵,鋅,鉀,鉛,嗯, K]

+1

我同意這種解決方案,假設字符串是大寫字母分隔的。我可能還建議將化學元素放入一個枚舉中,並在其中封裝比較代碼,以便您的函數可以返回一個'Set '而不是修改一個數組實例成員。 (這不是你想要的)。 – 2012-07-30 22:58:02

+0

@NathanielFord嗯,我真的希望它修改一個數組實例成員出於其他原因,因爲我也會使用它的其他值。這是該方法無效的原因之一。 我會嘗試梅森建議的,看看它是否有效。 – Pkmmte 2012-07-30 23:30:10

+0

謝謝,梅森!稍加修改後,您的解決方案就可以完美運行。 – Pkmmte 2012-07-31 00:40:53

0
  1. 而不是預先定義結束,使結束start + length of chemical name being tested。所以你會比較Chem[x].getFormula().equals(Input.substring(start, start + Chem[x].getFormula().length()))另外,你會提前startChem[x].getFormula().length()。我認爲你還需要驗證start + Chem[x].getFormula().length()小於總長度,否則你會得到String Index越界異常。
  2. 當您發現化學名稱匹配時,您需要從內部循環break檢查化學名稱,否則您會繼續與以後的名稱進行比較,並可能以found=false結束。所以你的底部if聲明錯誤地前進了兩個字符。例如,如果Fe在您的列表中出現在Zn之前,它在找到Zn後將不會找到Fe,並且會跳過它。
-2

這裏是我卑微的暗示......對於你的程序的未來,我想它會在諸如當你有多個O原子的情況下更好......如果這是需要的話......我會做什麼。 ..我會創建一個所謂的二維矩陣(使用更多的內存,但計算能力較低)26x26,其中每個索引對應一個字母......所以我們知道,元素符號是唯一的,最多2個字母(我不知道那些實驗的...遺憾:d)...那麼你會逐一掃描字符串...可以說你遇到F和E ..這會自動建議2d矩陣的索引...所以你會看看那個索引裏面...如果它是滿的(通過某些符號),那麼你會將Fe添加到你的一般列表中......但是讓我們在F後看到一個K ......然後當你看到矩陣時,你會看到它是空的,你會得出它是氟的結論......無論如何,我說更多的內存空間更少的計算......你的選擇

相關問題