本文详解如何通过递归方法判断两个字符串在所有 'x' 字符的位置上是否完全一致,重点修复逻辑运算符误用(`||` 替代 `&&`)导致的匹配失败问题,并提供符合 java 规范的健壮实现。
在字符串匹配任务中,有时我们并不关心全部字符是否相等,而是仅要求特定字符(例如 'X')在两个字符串中出现的位置必须完全一致——即:若 strA[i] == 'X',则 strB[i] 也必须为 'X';反之,若 strB[i] == 'X',则 strA[i] 也必须为 'X';其余非 'X' 位置的字符可任意(无需相等)。这种“X-位置对齐”逻辑常见于模式校验、掩码比对等场景。
原始代码的核心缺陷在于 else 分支中的条件判断存在逻辑错误:
else if (strA.charAt(0) == 'X' || strB.charAt(0) != 'X') // ❌ 错误:应为 &&
return false;
else if (strA.charAt(0) != 'X' || strB.charAt(0) != 'X') // ❌ 错误:应为 &&
return equalX(strA.substring(1), strB.substring(1));使用 || 会导致条件过早触发。例如当 strA[0]='X' 且 strB[0]='a' 时,'X' == 'X' || 'a' != 'X' 为 true || true → true,错误进入 return false;但实际应仅在 strA[0] 是 'X' 而 strB[0] 不是 'X'(或反之)时才拒绝匹配。因此,正确逻辑应为:
以下是修正后的完整实现(已遵循 Java 命名规范,方法名小驼峰):
public class Exercise4 {
public static boolean equalX(String strA, String strB) {
// 基础情况:两串均为空 → 匹配成功
if (strA.isEmpty() && strB.isEmpty()) {
return true;
}
// strA 空但 strB 非空:仅当 strB 当前字符不是 'X' 才可跳过
else if (strA.isEmpty() && !strB.isEmpty()) {
return strB.charAt(0) != 'X' && equalX(strA, strB.substring(1));
}
// strB 空但 strA 非空:同理
else if (strB.isEmpty() && !strA.isEmpty()) {
return strA.charAt(0) != 'X' && equalX(strA.substring(1), strB);
}
// 两者均非空
else {
char a = strA.charAt(0);
char b = strB.charAt(0);
if (a == 'X' && b == 'X') {
// 位置均为 X → 必须匹配,继续递归
return equalX(strA.substring(1), strB.substring(1));
} else if (a == 'X' && b != 'X') {
// A有X而B无 → 失败
return false;
} else if (a != 'X' && b == 'X') {
// B有X而A无 → 失败
return false;
} else {
// 两者均非X → 位置合法,跳过并递归
return equalX(strA.substring(1), strB.
substring(1));
}
}
}
public static void main(String[] args) {
String strA = "XaXaXaX";
String strB = "XeXwXeX";
System.out.println(equalX(strA, strB)
? "\"" + strA + "\" == \"" + strB + "\""
: "\"" + strA + "\" != \"" + strB + "\"");
// 输出: "XaXaXaX" == "XeXwXeX"
}
}关键注意事项:
该实现准确表达了“X 字符位置严格对齐”的语义,是理解递归字符串处理与布尔逻辑设计的典型范例。