gpt4 book ai didi

java - 用于在 Java 中解析化学方程式的正则表达式

转载 作者:行者123 更新时间:2023-12-01 18:00:45 25 4
gpt4 key购买 nike

我有一个程序应该从控制台读取一些字符串。如果出现字符串“end”,则应该开始计算并在控制台中写入字符串。

我正在读的字符串是一个化学方程式。该方程由这两个字符分开:->。我应该证明两边的原子数量是否相同。我发现this发布并尝试实现它,但我的正则表达式有问题。

例如:

如果公式前面有数字,我的正则表达式可以读取并计算化学方程式:

2 HCl + 2 Na -> 2 NaCl + H2

但如果没有数字,则无法正确计算:

HCl + Na -> NaCl + H2

我的代码:

public static void main(String[] args) {
Scanner s = new Scanner(System.in);
List<String> list = new ArrayList<String>();
String input = "";
while (!(input.equals("end"))) {
input = s.nextLine();
list.add(input);
}
int before = 0;
int after = 0;
list.remove(list.size() - 1);

for (int i = 0; i < list.size(); i++) {
String string = list.get(i);
string = string.replace("-", "");
String[] splitted = string.split(">");
Pattern firstPattern = Pattern.compile("(\\d+) (\\w+)");
Matcher firstMatcher = firstPattern.matcher(splitted[0]);
while (firstMatcher.find()) {
int element = Integer.parseInt(firstMatcher.group(1));
String count = firstMatcher.group(2);
final Pattern pattern = Pattern.compile("\\d+"); // the regex
final Matcher matcher = pattern.matcher(count); // your string
final ArrayList<Integer> ints = new ArrayList<Integer>(); // results
while (matcher.find()) { // for each match
ints.add(Integer.parseInt(matcher.group())); // convert to
// int
}
for (int j = 0; j < ints.size(); j++) {
before = before + element * ints.get(j);
}

}
Pattern secondPattern = Pattern.compile("(\\d+) (\\w+)");
Matcher secondMatcher = secondPattern.matcher(splitted[1]);
while (secondMatcher.find()) {
int element = Integer.parseInt(secondMatcher.group(1));
String count = secondMatcher.group(2);
final Pattern pattern = Pattern.compile("\\d+"); // the regex
final Matcher matcher = pattern.matcher(count); // your string
final ArrayList<Integer> ints = new ArrayList<Integer>(); // results
while (matcher.find()) { // for each match
ints.add(Integer.parseInt(matcher.group())); // convert to
// int
}
for (int j = 0; j < ints.size(); j++) {
after = after + element * ints.get(j);
}
}
if (before == after) {
System.out.println("formally correct");
} else {
System.out.println("incorrect");
}
}
}

以下是一些可供尝试的化学方程式示例:

输入:

HCl + Na -> NaCl + H2

2 HCl + 2 Na -> 2 NaCl + H2

12 CO2 + 6 H2O -> 2 C6H12O6 + 12 O2

结束

输出:

不正确

形式正确

不正确

最佳答案

所以,以下是我可以在您的逻辑中发现的问题:

  1. 您正在使用Pattern.compile("(\\d+) (\\w+)")匹配两侧的每个组件。在您尝试匹配 1 or more digits followed by a space followed by 1 or more word characters 的模式中。但在那里,数字是可选的。所以你需要它是 \\d*而不是第一个捕获组内容。空间也是可选的。所以你需要在模式中指定相同的内容。为了避免数字与第二个捕获组匹配(因为第一组变为可选),您需要使用 ([A-Z]\\w*) 。这确保了数字(如果有)将与第一组本身相匹配。因此,匹配两侧每个组件的模式应该是 Pattern.compile("(\\d*) ?([A-Z]\\w*)") .
  2. 您正在使用Pattern.compile("\\d+")匹配原子计数(如 H2 中的 2)。通过这种方式,如果任何元素具有单个原子,即如果您有CaCl2,您将错过对单个原子的计数。 ,你必须把它算作 1 个 Ca 原子和 2 个 Cl 原子。为此,您需要单独匹配每个元素,这可以使用 Pattern.compile("[A-Z][a-z]*(\\d*)") 之类的模式来完成。 .

  3. 您没有以正确的方式计算总数。将每个元素的分子和原子计数默认为 1,然后将每个元素的分子和原子计数相乘,然后将所有乘积相加即可得到总计数。

还有 2 个建议:

  1. 由于两边的计算逻辑相同,因此定义一个函数并调用它两次。
  2. 分割依据->本身。我认为您不需要先删除连字符,然后用 > 分割.

在深入代码之前尝试自己修改逻辑

这是我定义计算一方总数的函数的方式:

private static int calculateCount(String eqPart) {
Matcher matcher = Pattern.compile("(\\d*) ([A-Z]\\w*)").matcher(eqPart);
int totalCount = 0;
while (matcher.find()) {
String moleculeCountStr = matcher.group(1);
int moleculeCount = moleculeCountStr.isEmpty() ? 1 : Integer.parseInt(moleculeCountStr);
String molecule = matcher.group(2);
Matcher moleculeMatcher = Pattern.compile("[A-Z][a-z]*(\\d*)").matcher(molecule);
while (moleculeMatcher.find()) {
String atomCountStr = moleculeMatcher.group(1);
int atomCount = atomCountStr.isEmpty() ? 1 : Integer.parseInt(atomCountStr);
totalCount += moleculeCount * atomCount;
}
}
return totalCount;
}

使用每个分割结果(按 -> )调用该函数,并比较总数以查看方程是否正确。

关于java - 用于在 Java 中解析化学方程式的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41147597/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com