2

単純な問題がありますが、最近気が狂いそうになっています。私は化学プログラム(より具体的にはAndroidアプリ)を作成しており、ユーザーが入力した要素を分離するメソッドを持っています。例えば「FeZnKPb」と入力すると、「Fe」「Zn」「K」「Pb」に分かれます。

そのために、いくつかのネストされたループと変数を使用して制御しています。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;
        }
    }
}

私の問題は、「Fe」や「Zn」などの 2 文字の要素でしか機能しないことです。「K」なども認識してほしい。もう 1 つの問題は、他の要素をスキップする場合があることです。たとえば、「FeZnHg」と入力すると、「Fe」、「Zn」、「Hg」に分けられます。しかし、「ZnFeHg」のように順番を変えて入力すると、なぜか「Zn」と「Hg」しか検出されず、「Fe」が検出されません。

これを正しく機能させるには、他にどのような方法でこれを解決できますか?

4

3 に答える 3

5

要素は常に大文字と 1 つまたは 2 つの小文字のいずれか (および非常に短命の要素の場合のみ 2 つ) であることを考えると、入力を短い文字列に分割するためにいくつかの先読みで正規表現を使用することができます。

split メソッドといくつかの先読みを使用して、文字列を要素文字列に分割できます。ナサニエル・フォードのコメントを考慮に入れる:

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);

次のリストが表示されます。

[Fe、Zn、K、Pb、うーん、K]

于 2012-07-30T22:45:32.333 に答える
0
  1. 終わりを事前に定義する代わりに、終わりを作りstart + length of chemical name being testedます。したがって、比較すると、Chem[x].getFormula().equals(Input.substring(start, start + Chem[x].getFormula().length())) だけ進みます。また、全長よりも短いことを検証する必要があると思います。そうしないと、String Index out of bounds 例外が発生します。startChem[x].getFormula().length()start + Chem[x].getFormula().length()
  2. 化学名の一致が見つかったらbreak、内側のループから化学名をチェックする必要があります。そうしないと、後の名前と比較し続け、found=false. したがって、一番下のifステートメントは誤って 2 文字進みます。たとえば、リストのFe前にある場合、見つかった後は見つからず、スキップされます。ZnFeZn
于 2012-07-30T22:41:47.867 に答える
-2

ここに私の謙虚な提案があります...あなたのプログラムの将来のために、複数のO原子がある場合のような場合にも良いと思います...とにかくそれが必要な場合...私は何をします...私はいわゆる 2 次元行列 (より多くのメモリを使用しますが、計算能力は低くなります) 26x26 で、各インデックスは文字に対応しています...したがって、要素記号は一意であり、最大で 2 文字であることがわかっています (これらの実験的なものについてはわかりません...申し訳ありません:D)...次に、文字列を 1 つずつスキャンします...F と e に遭遇したとしましょう..これにより、自動的に 2 次元行列のインデックスが提案されます...したがって、そのインデックス内を調べます...ifそれがいっぱいである場合(何らかの符号によって)、一般的なリストにFeを追加します...しかし、Fの後にKを見たとしましょう...次に行列を見ると、それが空であることがわかり、それがフッ素ですか…とにかく、私が言ったように、より多くのメモリスペースより少ない計算...あなたの選択

于 2012-07-30T22:54:03.787 に答える