代数字符串化简代码优化:如何实现同类项合并?
问题分析与解决方案
你的代码目前只实现了括号的符号展开功能,没有处理同类项合并,所以输入a-(a+b)时会得到展开后的a-a-b,而无法自动合并a和-a这两个同类项。另外原代码还有个小问题:用固定长度的char[]存储结果时,最后会包含未使用的空字符,应该用StringBuilder来动态构建结果更稳妥。
下面是完整的优化方案,分为两个核心步骤:括号符号展开 + 同类项合并。
步骤1:优化括号展开逻辑
先把原代码的字符数组替换为StringBuilder,避免空字符问题,同时保留栈处理符号的核心逻辑:
private String expandParentheses(String str) { StringBuilder res = new StringBuilder(); Stack<Integer> signStack = new Stack<>(); signStack.push(0); // 0代表正号环境,1代表负号环境 int i = 0; int len = str.length(); while (i < len) { char c = str.charAt(i); if (c == '+') { res.append(signStack.peek() == 1 ? '-' : '+'); } else if (c == '-') { res.append(signStack.peek() == 1 ? '+' : '-'); } else if (c == '(') { // 处理括号前的符号,决定新环境的符号 if (i > 0 && str.charAt(i-1) == '-') { signStack.push(signStack.peek() == 1 ? 0 : 1); } else { // 括号前是+或者开头的(,符号环境不变 signStack.push(signStack.peek()); } } else if (c == ')') { signStack.pop(); } else { // 字母直接追加 res.append(c); } i++; } return res.toString(); }
步骤2:实现同类项合并
展开后的表达式需要合并同类项,我们可以用Map来统计每个变量的系数,最后根据系数构建化简结果:
private String combineLikeTerms(String expandedStr) { Map<String, Integer> termMap = new HashMap<>(); int len = expandedStr.length(); int i = 0; // 处理表达式开头没有符号的情况,默认加正号 if (len > 0 && expandedStr.charAt(0) != '+' && expandedStr.charAt(0) != '-') { expandedStr = "+" + expandedStr; } while (i < expandedStr.length()) { // 提取当前项的符号 int sign = expandedStr.charAt(i) == '+' ? 1 : -1; i++; // 提取变量名(这里假设变量是单个字母,若支持多字母变量需要调整逻辑) StringBuilder var = new StringBuilder(); while (i < expandedStr.length() && Character.isLetter(expandedStr.charAt(i))) { var.append(expandedStr.charAt(i)); i++; } String varName = var.toString(); // 更新系数 termMap.put(varName, termMap.getOrDefault(varName, 0) + sign); } // 构建最终结果 StringBuilder result = new StringBuilder(); for (Map.Entry<String, Integer> entry : termMap.entrySet()) { int coeff = entry.getValue(); String var = entry.getKey(); if (coeff == 0) { continue; // 系数为0的项直接忽略 } // 处理符号 if (coeff > 0 && result.length() > 0) { result.append('+'); } else if (coeff < 0) { result.append('-'); } // 处理系数:1或-1时省略数字,只保留符号 int absCoeff = Math.abs(coeff); if (absCoeff != 1) { result.append(absCoeff); } result.append(var); } // 处理结果为空的情况(比如输入"a-a") return result.length() == 0 ? "0" : result.toString(); }
整合两个方法
最后在simplify方法里把两个步骤结合起来:
public String simplify(String str) { String expanded = expandParentheses(str); return combineLikeTerms(expanded); }
测试验证
- 输入
"a-(b+c)",展开后是"a-b-c",合并后结果为"a-b-c"(符合你的第一个示例) - 输入
"a-(a+b)",展开后是"a-a-b",合并后结果为"-b"(这里纠正下你的示例:a-(a+b)的正确化简结果是-b,不是b哦) - 输入
"2a-(a+3b)",展开后是"2a-a-3b",合并后结果为"a-3b"
注意事项
如果需要支持多字母变量(比如"abc")或者带数字系数的项(比如"3x"),只需要调整combineLikeTerms里提取变量和系数的逻辑即可,当前代码默认变量是单个字母,系数为1或-1。
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

