Java计算化学式总质量的if-else逻辑优化方案咨询
化学式摩尔质量计算逻辑优化方案
原来用if-else逐个判断系数数值的实现有两个明显问题:仅支持2、3两个系数,遇到更大的数字或者多位数字(比如C6H12O6里的6、12)会完全计算错误;且逻辑冗余,无法通用扩展。优化方案如下:
核心优化:通用系数处理逻辑
不用针对每个数字写分支,直接将匹配到的数字转换为整型,按照「前一个元素质量 * (系数-1)」补加即可,兼容所有正整数系数,还能修复原有逻辑的冗余bug。
第一步:修改正则匹配规则,支持多位数字
把正则中的单数字匹配\d改为连续多数字匹配\d+,避免把12这类多位系数拆成1和2单独处理:
Pattern r = Pattern.compile("A[cglmrstu]|B[aehikr]?|C[adeflmnorsu]?|D[bsy]|E[rsu]|F[elmr]?|G[ade]|H[efgos]?|I[nr]?|Kr?|L[airuv]|M[dgnot]|N[abdeiop]?|Os?|P[abdmortu]?|R[abefghnu]|S[bcegimnr]?|T[abcehilm]|U(u[opst])?|V|W|Xe|Yb?|Z[nr]|\\d+|\\(|\\)");
第二步:重写遍历计算逻辑,删掉if-else分支
原有逻辑在识别到数字后,还会执行无效的元素质量查询(数字不可能匹配到元素,返回0属于冗余计算),优化后直接用continue跳过无效步骤:
double sum = 0; double previousElementWeight = 0; for (String s : el) { // 匹配到数字直接按系数补加质量 if (s.matches("\\d+")) { int count = Integer.parseInt(s); // 前一个元素已经累加过1次,这里只需要补加count-1次 sum += previousElementWeight * (count - 1); // 数字不属于元素,跳过后续元素处理逻辑 continue; } // 匹配到元素正常查询累加 double weight = ElementsDAO.findElementsWeight(s); previousElementWeight = weight; sum += weight; }
可选性能优化:改造ElementsDAO查询逻辑
原来每次查询元素质量都要遍历整个列表,元素量大时效率很低,改成HashMap存储元素符号和对应质量,查询效率可以从O(n)降到O(1):
public class ElementsDAO { public static List<Elements> elements = new ArrayList(); // 新增HashMap存储元素符号和质量的映射 public static Map<String, Double> symbolWeightMap = new HashMap<>(); static{ try { Scanner scn = new Scanner(new FileReader("elements.csv")); scn.nextLine(); // 跳过表头 while(scn.hasNext()) { String[] line = scn.nextLine().split(","); Elements e = new Elements(line[0], Integer.parseInt(line[1]), line[2], Double.parseDouble(line[3])); elements.add(e); // 加载元素时同时存入HashMap symbolWeightMap.put(e.getSymbol(), e.getWeight()); } } catch (FileNotFoundException ex) { Logger.getLogger(ElementsDAO.class.getName()).log(Level.SEVERE, null, ex); } } // 其他方法保留,重写查询质量的方法 public static double findElementsWeight(String symbol) { return symbolWeightMap.getOrDefault(symbol, 0d); } }
后续扩展建议
如果需要支持带括号的化学式(比如Al2(SO4)3),可以新增栈结构存储括号内的临时质量,匹配到闭合括号和后续系数时,将临时质量乘系数后再累加即可。
内容的提问来源于stack exchange,提问作者Andrei_I
相关产品推荐
相关产品推荐

