嗨
我正在编写一个图形界面程序来解决化学方程式,并将其用作其他功能,例如在不同的窗口中显示周期表。
正如标题所示,对象解析器的字符串有问题,希望对它的使用有所帮助。
它得到一个String
公式(C6H14 + O2 => CO2 + H2O
)并将其划分为不同的对象(分子具有存储名称和数量的元素列表),然后返回。注意*我将其设置为void
仅出于测试目的。
我将功能分为两部分:第一部分将String
读入Element对象;名称和数量。第二部分制作分子对象,并检查一个分子在哪里开始,另一分子在何处结束并相应地放置元素对象。这就是为什么我不过滤掉+
,=
和>
等数字动作的原因。
解析器:
public void formatFormula(String formula) {
List[] temp = new List[] {
new ArrayList<Molecule>(),
new ArrayList<Molecule>()
};
List<Element> ell = new ArrayList<>();
boolean newMol = true;
String crnN = null;
int crnQ=0;
int side = 0;
for (int i=0;i<formula.length()+1;i++) {
String d;
try { d = formula.substring(i,i+1); } catch (Exception e) { d = formula.substring(i-1); }
if (Character.isWhitespace(d.charAt(0))) continue;
if (isNumber(d)) {
crnQ = Integer.parseInt(crnQ+d);
} else if (d == d.toUpperCase()) {
if (crnN != null)
ell.add(new Element(crnN,crnQ));
crnN = d;
crnQ = 0;
} else {
crnN = crnN + d;
}
}
Element e;
for (int i=0;i<ell.size();i++) {
e = ell.get(i);
if (e.getName().charAt(0) == "+".charAt(0)) {
newMol = true;
continue;
}
if (e.getName().charAt(0) == "=".charAt(0) || e.getName().charAt(0) == ">".charAt(0)) {
newMol = true;
side = 1;
continue;
}
if (newMol) {
temp[side].add(new Molecule());
newMol=false;
} else {
((Molecule)temp[side].get(temp[side].size()-1)).addElement(e);
}
}
// Debugging.
for (Object f:temp[1]) {
System.out.println(((Molecule) f).getElements().get(0).getName());
}
}
我从中得到的价值观是完全错误的。在2
侧的第二个列表为空,在1
侧的列表2
和2
具有相同的值,并且Molecule对象的元素都不超过一个。>
它应该返回一个二维的分子数组,一个在箭头前,另一个在后。这些分子对象存储Element对象。
输入:
C6H14 + O2 => CO2 + H2O
输出:
C6H14 + O2 => CO2 + H2O
Obj(Molecule){ | Obj(Molecule){ || Obj(Molecule){ | Obj(Molecule){
Obj(Element){C:6} | Obj(Element){O:2}} || Obj(Element){C:1} | Obj(Element){H:2}
Obj(Element){H:14}} || Obj(Element){O:2}} | Obj(Element){O:1}}
注意*,这只是对象的表示。但是Molecule
存储了Element
的列表,这些列表又存储了String
和int
的值。
答案 0 :(得分:0)
很奇怪的代码。
我建议很少重构
1)使用“ =>”字符串拆分公式,并获得两个可以分别解析的公式(左和右)。
String delim="=>";
int p=s.indexOf(delim);
String left=s.substring(0, p);
String right=s.substring(p+delim.length());
List<Molecule> leftMolecules=parse(left);
List<Molecule> rightMolecules=parse(right);
2)创建函数parse
来解析您的公式的令牌
List<Molecule> parse(String formula) {
String [] molecules = formula.split("\\+"); // + is special character and requires escaping
List<Molecule> result = new ArrayList<>();
for (String m : molecules) {
m = m.trim(); // remove leading and trailing spaces
// here you parse single molecule like H2O etc
...
}
return result;
}
答案 1 :(得分:0)
我通过使用一个临时的Molecule对象变量解决了这个问题,然后将其插入列表中。
public Molecule[][] ParseString(String formula) {
List[] temp = new List[] {
new ArrayList<Molecule>(),
new ArrayList<Molecule>()
};
List<Element> ell = new ArrayList<>();
String crnN = null;
int crnQ=0;
int side = 0;
for (int i=0;i<formula.length()+1;i++) {
String d;
try { d = formula.substring(i,i+1); } catch (Exception e) { d = formula.substring(i-1); }
if (Character.isWhitespace(d.charAt(0))) continue;
if (isNumber(d)) {
crnQ = Integer.parseInt(crnQ+d);
} else if (d == d.toUpperCase()) {
if (crnN != null)
ell.add(new Element(crnN,crnQ));
crnN = d;
crnQ = 0;
} else {
crnN = crnN + d;
}
}
Molecule tempM = new Molecule();
boolean newMol = false;
for (Element e:ell) {
String n = e.getName();
if (n.charAt(0) == "+".charAt(0)) {
newMol = true;
temp[side].add(tempM);
tempM = new Molecule();
}
if (n.charAt(0) == "=".charAt(0)) {
newMol = true;
if (side == 0)
temp[side].add(tempM);
side = 1;
tempM = new Molecule();
}
if (n.charAt(0) == ">".charAt(0)) {
side = 1;
tempM = new Molecule();
continue;
}
if (newMol) {
newMol = false;
} else {
tempM.addElement(e);
}
}
temp[1].add(tempM);
return new Molecule[][]{
((Molecule[]) temp[0].toArray(new Molecule[temp[0].size()])),
((Molecule[]) temp[1].toArray(new Molecule[temp[1].size()]))
};