HackerRank合法用户名校验代码问题排查:JuliaZ007误判为Invalid
问题排查与修复
你遇到的问题核心在于**flag变量的初始化位置错误**,导致它的值在多个用户名校验之间没有重置,进而影响了后续合法用户名的判定。
具体原因分析
你的flag变量是在main方法开头初始化的(int flag=1;),这意味着它的生命周期覆盖整个程序运行过程。当处理到像Samantha?10_2A这样包含特殊字符的用户名时,flag会被设为0,而后续处理JuliaZ007时,flag并没有被重置回1——即使这个用户名完全符合规则,也会因为flag==0的条件不满足而被误判为Invalid。
除此之外,你的特殊字符检查逻辑也存在一点冗余:Character.isLetterOrDigit(ch)==false已经能判断字符不是字母数字,再结合specialCharactersString.contains(...)其实没必要,不过你没有把下划线标记为非法字符的逻辑是符合规则的(下划线是允许的),这部分可以进一步简化。
修复方案
方案1:修复flag的初始化位置
把flag的初始化移到while循环内部,每次处理新的用户名前都重置为1,确保每个用户名的校验都是独立的:
import java.io.*; import java.util.*; public class Solution { private static final Scanner scan = new Scanner(System.in); public static void main(String[] args) { int n = Integer.parseInt(scan.nextLine()); while (n-- != 0) { int flag=1; // 移到这里,每次循环重置flag String userName = scan.nextLine(); // 处理空字符串的边界情况,避免数组越界 if(userName.isEmpty()){ System.out.println("Invalid"); continue; } char a[] = userName.toCharArray(); for (int i=0;i<userName.length();i++) { char ch = userName.charAt(i); // 简化判断:如果字符不是字母数字也不是下划线,就标记为无效 if(!Character.isLetterOrDigit(ch) && ch != '_') { flag=0; break; // 找到非法字符后直接跳出循环,提升效率 } } if (userName.length()>=8 && userName.length()<=30 && Character.isLetter(a[0]) && flag==1) { System.out.println("Valid"); } else { System.out.println("Invalid"); } } } }
方案2:使用正则表达式(更简洁高效)
针对用户名的规则,我们可以用正则表达式一次性匹配所有条件,代码会更简洁易读:
^[A-Za-z]:首字符必须是字母[A-Za-z0-9_]{7,29}$:后面跟着7到29个字母、数字或下划线(总长度8-30)
import java.io.*; import java.util.*; public class Solution { private static final Scanner scan = new Scanner(System.in); // 预编译正则表达式,提升性能 private static final String USERNAME_PATTERN = "^[A-Za-z][A-Za-z0-9_]{7,29}$"; public static void main(String[] args) { int n = Integer.parseInt(scan.nextLine()); while (n-- != 0) { String userName = scan.nextLine(); if(userName.matches(USERNAME_PATTERN)){ System.out.println("Valid"); } else { System.out.println("Invalid"); } } } }
这两种方案都能正确处理JuliaZ007的测试案例,输出Valid。
内容的提问来源于stack exchange,提问作者Suhas
相关产品推荐
相关产品推荐

