Reputation: 33
The Question is to check a valid username:
Conditions are:
1.The username consists of 8 to 30 characters inclusive. If the username consists of less than 8 or greater than 30 characters, then it is an invalid username.
2.The username can only contain alphanumeric characters and underscores (_). Alphanumeric characters describe the character set consisting of lowercase characters [a-z], uppercase characters [A-Z], and digits [0-9].
3.The first character of the username must be an alphabetic character, i.e., either lowercase character [a-z] or uppercase character [A-Z].
Sample Input:
8
Julia
Samantha
Samantha_21
1Samantha
Samantha?10_2A
JuliaZ007
Julia@007
_Julia007
Sample Output:
Invalid
Valid
Valid
Invalid
Invalid
Valid
Invalid
Invalid
I am getting wrong output to some cases.
For Input: JuliaZ007 , I should get Valid but getting Invalid. Remaining are correct.
Can I know what's wrong in the code.
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");
}
}
}
}
Upvotes: 2
Views: 2778
Reputation: 516
Not the best solution but you can simply update the range of number of characters. Here's an example of regex.
/^(?=.{6,20}$)(?![_.])(?!.*[_.]{2})[a-zA-Z0-9._]+(?<![_.])$/
Upvotes: 0
Reputation: 20914
Note that methods in class java.lang.Character
, such as isLetterOrDigit
, will check for characters (or digits) in any language.
Since your question stipulates that the digits must be those commonly referred to as arabic numerals and the letters must be those in the English alphabet, the below code uses the unicode code points of each character in the user-entered userName
.
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);
}
}
}
Just for the sake of it, here is a solution that uses the 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);
}
}
}
Upvotes: 0
Reputation: 1689
In your case regular expression is most appropriate:
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;
}
}
Your problem is caused by the flag
.
Before JuliaZ007
, you have the name Samantha?10_2A
, but this name sets the flag
to 0
.
And when you are in the JuliaZ007
, the flag
is always 0
and you get a InValid
.
To correct this problem, you can reset flag
to 1
on each new name.
For this, you can simply move the int flag = 1
in the while.
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");
}
}
}
}
Upvotes: 1
Reputation: 6168
The username consists of 8 to 30 characters inclusive. If the username consists of less than 8 or greater than 30 characters, then it is an invalid username.
boolean valid = true;
if (userName.length() < 8 || userName.length() > 30) {
valid = false;
}
The username can only contain alphanumeric characters and underscores
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;
}
}
}
The first character of the username must be an alphabetic character
if (valid) {
valid = Character.isLetter(userName.charAt(0));
}
Once you execute all validation steps, simply return valid;
. On a side note, you can check the rule of the first character while looping to check the validity of the remaining character. I just did separate checks for clarity and for separating all three requirements for validation.
LASTLY, I want to point out this is most likely NOT the most optimal solution for non-regex. However, I broke it down in these steps because I feel strongly that as a beginner developer, you should attack problems in this manner: first break down the problem into individual, smaller problems. Then, come up to the solution of each independently, and lastly, integrate the smaller solutions into the final product.
Upvotes: 0