我有一个简单的问题,但它最近让我疯了。 我正在制作化学课程(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”。
我还有哪些方法可以解决这个问题,以使其正常工作?
答案 0 :(得分: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]
答案 1 :(得分:0)
start + length of chemical name being tested
。因此,您需要比较Chem[x].getFormula().equals(Input.substring(start, start + Chem[x].getFormula().length()))
此外,您将start
推进Chem[x].getFormula().length()
。我认为您还需要验证start + Chem[x].getFormula().length()
小于总长度,否则您将获得String Index out of bounds exception。break
检查化学名称,否则您将继续与后来的名称进行比较,最终可能会使用found=false
。所以你的底部if
语句错误地以两个字符前进。例如,如果Fe
位于列表中的Zn
之前,则在找到Fe
之后找不到Zn
并且会跳过它。答案 2 :(得分:-2)
这是我谦虚的建议......对于你的程序的未来我想在你有多个O原子的情况下也会更好......如果需要的话......我会做什么......我将创建一个所谓的2d矩阵(使用更多的内存但更少的计算能力)26x26其中每个索引对应一个字母...所以我们知道元素符号是唯一的,最多2个字母(我不确定那些实验的...对不起:D)...然后你将逐个扫描字符串......让我们说你遇到F和e ..这会自动显示2d矩阵的索引......所以你会看到那个索引。 ..如果它是满的(通过某些标志)然后你会将Fe添加到你的一般清单......但是让我们说在F之后你看到了一个K ...然后当你看到矩阵时你会看到它是空的你会得出的结论是它是氟...无论如何,因为我说更多的内存空间更少计算...你的选择