【问题标题】:Valid Username without Regex没有正则表达式的有效用户名
【发布时间】:2022-01-09 14:16:59
【问题描述】:

问题是检查一个有效的用户名:

条件是:

1.用户名由8到30个字符组成。如果用户名包含少于 8 个或多于 30 个字符,则该用户名无效。

2.用户名只能包含字母数字字符和下划线(_)。字母数字字符描述由小写字符 [a-z]、大写字符 [A-Z] 和数字 [0-9] 组成的字符集。

3.用户名的第一个字符必须是字母字符,即小写字符[a-z]或大写字符[A-Z]。

示例输入:

8

朱莉娅

萨曼莎

萨曼莎_21

1萨曼莎

萨曼莎?10_2A

朱莉娅Z007

朱莉娅@007

_Julia007

样本输出:

无效

有效

有效

无效

无效

有效

无效

无效

在某些情况下我得到错误的输出。

对于输入: JuliaZ007 ,我应该得到 Valid 但得到 Invalid。其余都是正确的。

我能知道代码有什么问题吗?

https://www.hackerrank.com/challenges/valid-username-checker/problem?isFullScreen=false

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 flag=1;
    int n = Integer.parseInt(scan.nextLine());
    while (n-- != 0) {
        String userName = scan.nextLine();
        char a[] = userName.toCharArray();
        String specialCharactersString = "!@#$%&*()'+,-./:;<=>?[]^`{|}";
        for (int i=0;i<userName.length();i++)
        {
        char ch = userName.charAt(i);
        if(specialCharactersString.contains(Character.toString(ch)) && Character.isLetterOrDigit(ch)==false) 
        {
            flag=0;
        }
        }
        if (userName.length()>=8 && userName.length()<=30 && Character.isLetter(a[0])==true && flag==1)                   {
            System.out.println("Valid");
        } else {
            System.out.println("InValid");
        }           
    }
}

}

【问题讨论】:

  • "在某些情况下我得到错误的输出" - 哪些?预期的输出和观察到的输出是什么?请edit发帖并添加这些信息。
  • @Turing85 对于输入:JuliaZ007,我应该得到 Valid 但得到 Invalid。
  • Hackerrank 问题需要一个带有正则表达式的解决方案。
  • @hfontanez 是的,但我想尝试不使用它。你能帮忙吗?
  • @Suhas 我为 HackerRank 想出的正则表达式与 JavaMan 在他的回答中使用的相同。

标签: java string


【解决方案1】:

用户名由 8 到 30 个字符组成(包括 8 到 30 个字符)。 如果用户名少于 8 个或多于 30 个字符,则为无效用户名

boolean valid = true;
if (userName.length() < 8 || userName.length() > 30) { 
    valid = false;
}

用户名只能包含字母数字字符和下划线

if (valid) {
    for (int  i = 0; i < userName.length(); i++) {
        boolean temp = c
        Character c = userName.charAt(i);
        valid = Character.isLetterOrDigit(c);
        // before invalidating, check to see if it is an underscore
        if (!valid) {
            valid = c == '_';
            if (!valid)
                break;
        }
    }
}

用户名的第一个字符必须是字母字符

if (valid) {
    valid = Character.isLetter(userName.charAt(0));
}

执行所有验证步骤后,只需 return valid;。附带说明一下,您可以在循环时检查第一个字符的规则以检查剩余字符的有效性。我只是为了清楚起见做了单独的检查,并将所有三个验证要求分开。

最后,我想指出这很可能不是非正则表达式的最佳解决方案。但是,我在这些步骤中对其进行了分解,因为我强烈认为作为初学者开发人员,您应该以这种方式解决问题:首先将问题分解为单个较小的问题。然后,独立提出每个解决方案,最后将较小的解决方案集成到最终产品中。

【讨论】:

  • "2.用户名只能包含字母数字字符和下划线 (_)" - 您错过了这部分要求。
【解决方案2】:

使用正则表达式

在你的情况下,正则表达式是最合适的:

import java.util.Scanner;
import java.util.regex.Pattern;

public class Solution {
    private static final Scanner scan = new Scanner(System.in);

    public static void main(String[] args) {
        final String regex = "^[a-zA-Z][\\w_]{7,29}$";
        final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);

        int n = Integer.parseInt(scan.nextLine());
        while (n-- != 0) {
            String userName = scan.nextLine();
            if (pattern.matcher(userName).matches())
                System.out.println("Valid");
            else
                System.out.println("InValid");
        }
    }

}

没有正则表达式

import java.util.Scanner;

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) {
            String userName = scan.nextLine();
            if (isValid(userName))
                System.out.println("Valid");
            else
                System.out.println("InValid");
        }
    }

    public static boolean isValid(String userName) {
        if (!Character.isAlphabetic(userName.charAt(0))
                || userName.length() < 8
                || userName.length() > 30)
            return false;
        for (char c : userName.toCharArray()) {
            if (!Character.isLetterOrDigit(c) && c != '_')
                return false;
        }
        return true;
    }
}

说明程序中出现问题的原因

您的问题是由flag引起的。

JuliaZ007 之前,您有名称Samantha?10_2A,但此名称将flag 设置为0。 当你在JuliaZ007 中时,flag 总是0,你会得到一个InValid

要解决此问题,您可以在每个新名称上将 flag 重置为 1。 为此,您可以简单地移动int flag = 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;
            String userName = scan.nextLine();
            char a[] = userName.toCharArray();
            String specialCharactersString = "!@#$%&*()'+,-./:;<=>?[]^`{|}";
            for (int i = 0; i < userName.length(); i++) {
                char ch = userName.charAt(i);
                if (specialCharactersString.contains(Character.toString(ch))
                        && Character.isLetterOrDigit(ch) == false) {
                    flag = 0;
                }
            }
            if (userName.length() >= 8 && userName.length() <= 30 && Character.isLetter(a[0]) == true && flag == 1) {
                System.out.println("Valid");
            } else {
                System.out.println("InValid");
            }
        }
    }

}

【讨论】:

  • OP 已经知道这一点并且想要一个没有正则表达式的答案。阅读 cmets,如有疑问,请咨询 OP。您可能是对的,这可能是最好的答案,但这对 OP 没有帮助,因为它不是被问到的。
  • 不鼓励仅使用代码的答案。我们应该解释导致问题的原因以及我们的解决方案如何解决问题。
  • 感谢 @hfontanez @Turing85 的建议,我改进了答案。
  • 谢谢@JavaMan 我得到了正确的输出。
  • 不客气@Suhas,如果有帮助,请不要犹豫验证答案。
【解决方案3】:

请注意,java.lang.Character 类中的方法(例如 isLetterOrDigit)将检查任何语言中的字符(或数字)。

由于您的问题规定数字必须是通常称为arabic numerals的数字,而字母必须是English alphabet中的数字,因此以下代码使用用户输入的@987654327中每个字符的unicode code points @。

import java.util.Scanner;

public class Solution {
    private static final Scanner scan = new Scanner(System.in);

    public static void main(String[] args) {
        String result;
        int n = Integer.parseInt(scan.nextLine());
        while (n-- != 0) {
            result = "invalid";
            String userName = scan.nextLine();
            int len = userName.length();
            if (len >= 8  &&  len <= 30) {
                char[] letters = userName.toCharArray();
                if ((letters[0] >= 65  &&  letters[0] <= 90)  ||  (letters[0] >= 97  &&  letters[0] <= 122)) {
                    int i = 1;
                    for (; i < len; i++) {
                        if ((letters[i] >= 48  &&  letters[i] <= 57)  ||
                            (letters[i] >= 65  &&  letters[i] <= 90)  ||
                            (letters[i] >= 97  &&  letters[0] <= 122) ||
                            (letters[i] == 95)) {
                            continue;
                        }
                        break;
                    }
                    if (i == len) {
                        result = "valid";
                    }
                }
            }
            System.out.println(result);
        }
    }
}

编辑

为了它,这里有一个使用stream API的解决方案。

import java.util.Scanner;

public class Solution {
    private static final Scanner scan = new Scanner(System.in);

    public static void main(String[] args) {
        String result;
        int n = Integer.parseInt(scan.nextLine());
        while (n-- != 0) {
            result = "invalid";
            String userName = scan.nextLine();
            int len = userName.length();
            if (len >= 8  &&  len <= 30) {
                char letter = userName.charAt(0);
                if ((letter >= 65 && letter <= 90) || (letter >= 97 && letter <= 122)) {
                    if (userName.chars()
                                .skip(1L)
                                .allMatch(c -> (c >= 48  &&  c <= 57)  || // c is a digit
                                               (c >= 65  &&  c <= 90)  || // c is uppercase letter
                                               (c >= 97  &&  c <= 122) || // c is lowercase letter
                                               (c == 95))) { // c is underscore
                        result = "valid";
                    }
                }
            }
            System.out.println(result);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-29
    • 1970-01-01
    相关资源
    最近更新 更多