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

我的问题是它仅适用于 2 字符元素,例如“Fe”或“Zn”。我希望它也能识别像“K”这样的其他人。另一个问题是它有时会跳过一些其他元素。例如,如果我输入“FeZnHg”,它会将它们分成“Fe”、“Zn”和“Hg”。但是,如果我以不同的顺序输入它们,例如“ZnFeHg”,由于某种原因,它只会检测到“Zn”和“Hg”,而不是“Fe”。

我还有什么其他方法可以解决这个问题以使其正常工作?

4

3 回答 3

5

鉴于元素总是一个大写字符和一个或两个小写字符(只有在一些非常短暂的元素的情况下才两个),您可以使用带有一些前瞻的正则表达式将您的输入拆分为短字符串。

您可以使用 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、Umm、K]

于 2012-07-30T22:45:32.333 回答
0
  1. 与其预先定义 end ,不如做 end 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 out of bounds 异常。
  2. 当您找到化学名称匹配时,您需要break从内部循环中检查化学名称,否则您会继续与后来的名称进行比较,并可能以found=false. 因此,您的底部if语句错误地前进了两个字符。例如,如果FeZn您的列表中出现,则在找到Fe之后将不会找到Zn并会跳过它。
于 2012-07-30T22:41:47.867 回答
-2

这是我的谦虚建议...对于您的程序的未来,我想在您有多个 O 原子的情况下它也会更好...如果无论如何都需要...我会做什么...我会创建一个所谓的 2d 矩阵(使用更多内存但计算能力更少)26x26,其中每个索引对应一个字母......所以我们知道元素符号是唯一的,最多 2 个字母(我不确定那些实验性的......抱歉:D)...然后您将一一扫描字符串...假设您遇到 F 和 e..这会自动建议二维矩阵的索引...因此您将查看该索引内部...如果它是满的(通过某种标志),那么你会将 Fe 添加到你的总列表中......但是让我们说在 F 之后你看到了一个 K......然后当你查看矩阵时,你会看到它是空的,你会得出结论是氟...无论如何,正如我所说的更多的内存空间更少的计算......你的选择

于 2012-07-30T22:54:03.787 回答