Java多维数组字符串元素对比:三张卡牌有效性校验错误排查
卡牌组合有效性判断问题排查与修复
问题描述
我正在准备实操考试的练习题,现在遇到了问题。我写了一个方法判断三张卡牌的组合是否有效,规则如下:
- 两张卡牌所有属性(形状、颜色、图案)都不匹配则为不同卡牌;
- 两张卡牌所有属性都匹配则为相同卡牌;
- 三张组合有效需满足:要么三张全是相同卡牌,要么三张全是不同卡牌。
现在程序运行时所有三组卡牌都被判定为“有效”,我排查了卡牌读取存储逻辑,觉得问题出在cardsAreValid方法的字符串属性对比逻辑里,但不确定,请求帮助。
相关代码
import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Check { public static boolean cardsAreValid(String [][] threeCards){ boolean sameShape = threeCards[0][0].equals(threeCards[1][0]) && threeCards[1][0].equals(threeCards[2][0]); boolean sameColour = threeCards[0][1].equals(threeCards[1][1]) && threeCards[1][1].equals(threeCards[2][1]); boolean samePattern = threeCards[0][2].equals(threeCards[1][2]) && threeCards[1][2].equals(threeCards[2][2]); if (sameShape == true && sameColour==true && samePattern==true) // if all attributes match - same so valid return true; else if (sameShape==false && sameColour==false && samePattern==false) // if no attributes match - distinct so valid return true; else return false; // if only 1 or 2 cards differ/match its invalid } public static void main (String [] args) { File inFile = new File("cards.txt"); String [][] cards = new String[3][3]; List<String> allLines = new ArrayList<>(); try (Scanner sc = new Scanner(inFile)) { while (sc.hasNextLine()) { allLines.add(sc.nextLine()); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } for (int i = 0; i < allLines.size(); i++) { String fullLine = allLines.get(i); System.out.println("Processing: " + fullLine); String [] singleCard = fullLine.split(" "); for (int j = 0; j < 3; j++) { int firstComma = singleCard[j].indexOf(",", 0); int secondComma = singleCard[j].indexOf(",", firstComma+1); String shape = singleCard[j].substring(0, firstComma); String colour = singleCard[j].substring(firstComma+1, secondComma); String pattern = singleCard[j].substring(secondComma+1); cards[j][0] = shape; cards[j][1] = colour; cards[j][2] = pattern; } if (cardsAreValid(cards) == true) { System.out.println("Valid"); } else System.out.println("Invalid"); } } }
cards.txt示例内容
square,blue,spot circle,red,solid triangle,green,stripe
square,blue,spot circle,red,solid triangle,green,solid
square,blue,spot square,blue,spot square,blue,spot square,blue,spot
square,blue,spot triangle,green,stripe
问题分析
- 核心逻辑错误:
cardsAreValid方法误解了“三张全是不同卡牌”的判断规则。你当前的逻辑认为只要所有属性组(形状、颜色、图案)都不完全相同就判定有效,但实际规则要求任意两张卡牌之间都必须是“所有属性不匹配”的不同卡牌。 - 数据残留问题:
cards数组在循环外创建,会导致上一次循环的旧数据残留,影响下一次判断。 - 异常输入未处理:没有判断每行的卡牌数量是否为3,会导致数组越界或错误判断。
修复方案
1. 重构cardsAreValid方法
修正判断逻辑,先判断三张是否完全相同,再判断三张是否两两完全不同:
public static boolean cardsAreValid(String[][] threeCards) { // 判断三张卡牌是否完全相同 boolean allSame = threeCards[0][0].equals(threeCards[1][0]) && threeCards[0][1].equals(threeCards[1][1]) && threeCards[0][2].equals(threeCards[1][2]) && threeCards[1][0].equals(threeCards[2][0]) && threeCards[1][1].equals(threeCards[2][1]) && threeCards[1][2].equals(threeCards[2][2]); if (allSame) { return true; } // 判断两张卡牌是否完全不同(所有属性都不匹配) boolean card0DiffCard1 = !threeCards[0][0].equals(threeCards[1][0]) && !threeCards[0][1].equals(threeCards[1][1]) && !threeCards[0][2].equals(threeCards[1][2]); boolean card0DiffCard2 = !threeCards[0][0].equals(threeCards[2][0]) && !threeCards[0][1].equals(threeCards[2][1]) && !threeCards[0][2].equals(threeCards[2][2]); boolean card1DiffCard2 = !threeCards[1][0].equals(threeCards[2][0]) && !threeCards[1][1].equals(threeCards[2][1]) && !threeCards[1][2].equals(threeCards[2][2]); // 三张两两完全不同则有效 return card0DiffCard1 && card0DiffCard2 && card1DiffCard2; }
2. 修复main方法的输入处理
- 将
cards数组移到循环内创建,避免数据残留 - 增加卡牌数量校验,过滤非3张的输入行:
public static void main (String [] args) { File inFile = new File("cards.txt"); List<String> allLines = new ArrayList<>(); try (Scanner sc = new Scanner(inFile)) { while (sc.hasNextLine()) { allLines.add(sc.nextLine()); } } catch (FileNotFoundException e) { e.printStackTrace(); } for (int i = 0; i < allLines.size(); i++) { String fullLine = allLines.get(i); System.out.println("Processing: " + fullLine); String [] singleCard = fullLine.split(" "); // 校验卡牌数量是否为3 if (singleCard.length != 3) { System.out.println("Invalid (card count not 3)"); continue; } // 每次循环重新创建数组,避免旧数据残留 String[][] cards = new String[3][3]; for (int j = 0; j < 3; j++) { int firstComma = singleCard[j].indexOf(",", 0); int secondComma = singleCard[j].indexOf(",", firstComma+1); String shape = singleCard[j].substring(0, firstComma); String colour = singleCard[j].substring(firstComma+1, secondComma); String pattern = singleCard[j].substring(secondComma+1); cards[j][0] = shape; cards[j][1] = colour; cards[j][2] = pattern; } System.out.println(cardsAreValid(cards) ? "Valid" : "Invalid"); } }
测试结果
针对提供的cards.txt示例,修复后的程序输出:
- 第一行:三张两两完全不同 → Valid
- 第二行:第二张与第三张图案相同,不属于两两完全不同 → Invalid
- 第三行:卡牌数量为4 → Invalid (card count not 3)
- 第四行:卡牌数量为2 → Invalid (card count not 3)
内容的提问来源于stack exchange,提问作者koder
相关产品推荐
相关产品推荐

