Java - validating a subject Code - java

I have a subject code e.g: ABC123 that is a string
I need to ensure that it is of length 6, the first 3 characters are letters and the last 3 are numbers.
I would like to try and do it all in an if statement? I can work the length but cannot figure out the numeric and letter part of things. e.g:
public void isValidCode(String subjectCode2){
str = subjectCode2;
if (str.length() == 6 && """"NEED TO TEST OTHERS HERE??""" ) {
System.out.println("The code is valid");
}
else {
System.out.println("The code is not valid");
}

You can always use Regular Expressions, and the matches() method of the String class.
if (str.matches("[a-zA-Z]{3}[0-9]{3}")) {
// Validation succeeded
}
else {
// Validation failed
}

To test that the first three letters are letters, you could use a loop. Similarly, use a loop for testing that the last three digits are numbers. You might find the functions in the Character class helpful.

I would change the method signature so that it is not a void method but rather declared to return a boolean. Then you could have several if statements that if false returns false. At the bottom, return true if it passes all tests.
public boolean isValidCode(String code) {
if (code.length() != 6) {
return false;
}
// here check if first 3 chars are letters
// here check if last 3 chars are numbers
return true;
}
Then the calling code can do a println if desired.
String test = "ABC123";
if (isValidCode(test)) {
System.out.println("The code is valid");
} else {
System.out.println("The code is not valid");
}

If by "letter", you mean to include letters in alphabets other than English, you'll need this.
if (str.matches("\\p{L}{3}\\d{3}")) {
Here, \p{L} matches any character that Unicode considers to be a letter, in any language.

Related

String anagram in Java

i am trying to create a program for string anagram that follows these conditions:
method should allow only letters, white space, commas and dots in an anagram. If there are any other characters, then the string cannot contain an anagram.
The method should ignore all white space, commas and dots when it checks the text.
If there are no letters in the text, then the text cannot be an anagram.
import java.util.Arrays;
import java.util.Scanner;
public class StringAnagram {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter first string: ");
String first = in.nextLine().toUpperCase();
System.out.print("Enter second string: ");
String second = in.nextLine().toUpperCase();
String result = isAnagram(first, second);
System.out.println(result);
}
private static String isAnagram(String first, String second) {
String answer = "";
if (first.matches("[A-Z\\.\\,\\s]")) {
String st = first.replaceAll("\\.\\,\\s", "");
String nd = second.replaceAll("\\.\\,\\s", "");
char[] arraySt = st.toCharArray();
char[] arrayNd = nd.toCharArray();
Arrays.sort(arraySt);
Arrays.sort(arrayNd);
if(Arrays.equals(arraySt, arrayNd)) {
answer = "Anagram.";
}
else {
answer = "No anagram.";
}
}
else {
answer = "No anagram.";
}
return answer;
}
}
However when the program tests these 2 sentences, they are not anagram but they should be anagram. I have no idea where to look for mistake.
Eleven plus two is thirteen.
Twelve plus one is thirteen.
If you start your method as follows, it will fulfil validations mentioned in the 1st and the 3rd points of your question:
if (first == null || second == null || first.equals("") || second.equals("") || !first.matches("[A-Za-z,. ]+")
|| !second.matches("[A-Za-z,. ]+")) {
return "No anagram.";
}
The next thing you should do is to replace all white space, commas and dots with "" in order to ignore them:
String st = first.replaceAll("[,. ]+", "");
String nd = second.replaceAll("[,. ]+", "");
The complete code is as follows:
private static String isAnagram(String first, String second) {
if (first == null || second == null || first.equals("") || second.equals("") || !first.matches("[A-Za-z,. ]+")
|| !second.matches("[A-Za-z,. ]+")) {
return "No anagram.";
}
String answer = "";
String st = first.replaceAll("[,. ]+", "");
String nd = second.replaceAll("[,. ]+", "");
if (st.equals("") || nd.equals("")) {
return "No anagram.";
}
char[] arraySt = st.toCharArray();
char[] arrayNd = nd.toCharArray();
Arrays.sort(arraySt);
Arrays.sort(arrayNd);
if (Arrays.equals(arraySt, arrayNd)) {
answer = "Anagram.";
} else {
answer = "No anagram.";
}
return answer;
}
A test run:
Enter first string: london
Enter second string: britain
No anagram.
Another test run:
Enter first string: ram
Enter second string: mar
Anagram.
Another test run:
Enter first string: .
Enter second string: .
No anagram.
Another test run:
Enter first string: ,
Enter second string: .
No anagram.
Another test run:
Enter first string: ra.m
Enter second string: a.m.r
Anagram.
This: first.matches("[A-Z\\.\\,\\s]") tests if the first value is a single character that is either 1 capital letter, or a dot, or a comma, or any whitespace character.
Completely not what you want.
You can add System.out.println statements all over the place to print where your code is and the value of relevant variables. Follow the code along like you're the computer. There where what you think should happen does not match with what the sysout statements tell you – there is a bug there (there can be many, especially if you write this much stuff without testing anything first).
Better yet, use a debugger.
NB: Something as trivial as replacing one of your No anagram. strings with anything else just so you know which of the two got triggered would already have helped a lot.
NB: first.replaceAll("\\.\\,\\s", ""); is also broken; you've written way too much code here; test each individual moving piece. It's like a bike that doesn't do anything after you put it together: Take it apart piece by piece, test each piece individually.
This solution accepts strings from console input. That portion is omitted since that is working for you.
The idea is to selectively reduce the essence of what you are comparing to the bare minimum. Comments are provide to explain the logic. In the examples, all but the third one report as an anagram.
System.out.println(isAnagram("radar", "darar"));
System.out.println(isAnagram("ra.,. dar", "d.,a rar"));
System.out.println(isAnagram("r+a.,. dar", "d.,a + rar"));
System.out.println(isAnagram("Eleven plus two is thirteen.", "Twelve plus one is thirteen."));
// This method accepts mixed case strings. The conversion to upper case is
// done within the method.
public static String isAnagram(String first, String second) {
// get rid of allowed characters and convert to upper case
String st = first.replaceAll("[., ]","").toUpperCase();
String nd = second.replaceAll("[., ]","").toUpperCase();
// Now get rid of all alpha characters and compare to the empty string.
// Only if both are equal are the strings potential anagrams.
// Otherwise, the illegal characters would be present.
if (st.replaceAll("[A-Z]","").equals("") &&
nd.replaceAll("[A-Z]","").equals("")) {
// this is your original code
char[] arraySt = st.toCharArray();
char[] arrayNd = nd.toCharArray();
Arrays.sort(arraySt);
Arrays.sort(arrayNd);
// don't set a value just return it's an
// anagram
if (Arrays.equals(arraySt, arrayNd)) {
return "Anagram.";
}
}
// Otherwise, it's not
return "No Anagram.";
}

How to validate phone number

I am trying to validate phone numbers in java. In my country, phone numbers either begin with 9 or 8 and only have 8 numbers. I have done
try {
Integer.parseInt(phoneNo);
}
catch (NumberFormatException e) {
msg += "Plese enter amount in Integers.\n";
}
if (phoneNo.length() == 0)
msg += "Please Enter Phone Number.\n";
if (phoneNo.length() != 8)
msg += "Invalid Phone Number.\n";
However I need to validate when the first digit of the number isn't 9 or 8. I am not entirely sure of how I am supposed to do that. Please explain how your code works as I am a student and I am trying to learn.
Just in case you are looking for a regular expression solution.
You can do use the following pattern ^(?=(?:[8-9]){1})(?=[0-9]{8}).* to perform the check.
Essentially what it does is;
From first character position ^
Look ahead and see if the first character is a 8 or 9 (?=(?:[8-9]){1})
Then see if there are a total of 8 digits (?=[0-9]{8})
If the above conditions is a match then mark this as matched .*
public static void main(String[] args) {
String telephoneNr = "88765432";
if (telephoneNr.matches("^(?=(?:[8-9]){1})(?=[0-9]{8}).*")) {
System.out.println("Valid phone number!");
}
else {
System.out.println("Invalid!");
}
}
Output:
Valid phone number!
The methods that you need to put this together are readily available on the String and Character classes.
Here is an example program that does what you are looking for:
public class Foo {
public static void main(String[] args) {
// First try null and the empty string
System.out.println(isValidPhoneNumber(null));
System.out.println(isValidPhoneNumber(""));
// Now try an otherwise valid string that doesn't have the right first character
System.out.println(isValidPhoneNumber("01234567"));
// Now try an invalid string
System.out.println(isValidPhoneNumber("9a934581"));
// Finally a valid number
System.out.println(isValidPhoneNumber("94934581"));
}
static boolean isValidPhoneNumber(String phoneNo) {
// First validate that the phone number is not null and has a length of 8
if (null == phoneNo || phoneNo.length() != 8) {
return false;
}
// Next check the first character of the string to make sure it's an 8 or 9
if (phoneNo.charAt(0) != '8' && phoneNo.charAt(0) != '9') {
return false;
}
// Now verify that each character of the string is a digit
for (char c : phoneNo.toCharArray()) {
if (!Character.isDigit(c)) {
// One of the characters is not a digit (e.g. 0-9)
return false;
}
}
// At this point you know it is valid
return true;
}
}
The output it produces is:
false
false
false
false
true
The final for-each loop could avoid re-checking the first character by using a for loop with an explicit counter, but the performance gain of not checking a single int doesn't outweigh the cleaner code and better readability of the for each construct.
Edit: also please note that I removed the validation error messages from the original question for better readability as the OP asked to explain what the code was doing.
Instead of taking the phone number in a Integer variable take it in a String variable.
Then check whether the 1st number is 9, 8 or not by using stringVariable.charAt(0)
and for length of the phone number use int len=stringVariable.length();
You can check the first character of the phoneNo:
if (phoneNo.charAt(0) != '9' && phoneNo.charAt(0) != '8') {
// the first character is not a 9 or an 8
}
Documentation for charAt from Oracle.

How to check if there are double letters in a 4 digit code in Java

The above question might seems vague but it's actually a very simple idea which i can't seem to figure out.
It basically is a 4 digit letter code containing letters from A to F for example: ABDF, BAAF, DBAF etc.
Now I'm trying to do some post input-handling where it must become impossible to enter a letter that is already in the code cause it has to be a unique 4 digit code with no repeating letter. I've been trying to make it work but none of my code seems to work so i'm back to scratch asking you guys for help :)
I hope this is somewhat clear otherwise i'll be happy to clear it up.
Thanks in advance.
Kind of a pseudocode but it would work.
String uniquePass="";
while(uniquePass.length<4){
String userInput=getUserInputChar()
if(uniquePass.contains(userInput))
rejectInputAndNotifyUser
else
uniquePass=uniquePass+userInput
}
public static boolean hasDuplicateChars(String string) {
Set<Character> chars = new HashSet<Character>();
for (char c : string.toCharArray()) {
if (!chars.add(c)) return false;
}
return true;
}
Set is a collection that contains no duplicate elements. We will use add method which returns true if this set did not already contain the specified element.
hasDuplicateChars functions iterates over characters in the input string using toCharArray function and for loop; each character is added to the chars set which is initially empty. If add method returns false it means that we have already encountered same character before. So we return false from our function.
Otherwise input is valid and method returns true.
using this function you'll be able to see if the string contains unique characters
public static boolean checkForUnique(String str){
boolean containsUnique = false;
for(char c : str.toCharArray()){
if(str.indexOf(c) == str.lastIndexOf(c)){
containsUnique = true;
} else {
containsUnique = false;
}
}
return containsUnique;
}
Update:
This will be ran everytime a user enters a character and if it fails, this would mean there is a duplicate. You have the choice of discarding that input or showing an error.
If you're validating the complete input, you can lean on the set semantics, and a few tricks
String s = "ABAF";
int count = new HashSet<>(Arrays.asList(s.split(""))).size();
if (count - 1 == 4) {
System.out.println("All ok");
} else {
System.out.println("Repeated letters");
}
the split("") will split the string to a an array like {"","A", "B", "A", "F"}.
The new HashSet<>(Arrays.asList(s.split(""))) will create a Set with String elements, and as the Set will bounce back the elements already contained, the size of the set for e.g. "AAAF" will be 3 (it'll contain the "", "A" and "F"). This way you can use the size of the set to figure out if all letters of a String are unique
If its while typing you'll than the solution depends on the input method, but you can have something like (pseudo stuff)
if (pass.contains(letter)) {
breakAndNotifyUser();
} else {
pass+=letter;
}

Finding if a specific character exists at a specific index

so I'm trying to figure out how to create a condition for my decision structure. I'm making a program that converts military time to conventional time. When times are entered, they must be in a XX:XX format, where X equals a digit. I'm wondering, how can I make a validation that checks to make sure that ":" always exists as a colon and is in the same spot?
myString.charAt(5) == ':'
Just change 5 to whatever you need, and check string length before you do this, so you don't ask for something past the end of a short string.
You could search the string with indexOf(), which returns the index at which the character is found. This will check if a colon is in the string and if it's in the right position.
if("10:00".indexOf(':') == 2)
// do something
It will return -1 if the value is not found. Check out the java documentation for more information.
Here is the answer for it
Suppose you had string that contains XX:XX
yourString="XX:XX"
yourString.contains(":") - return true - if exists
":" takes the 3rd position. So it will be 2(0,1,2)
yourString.charAt(2) == ':'
Together , it will be
if(yourString.contains(":") && yourString.charAt(2) == ':'){
//your logic here
}else{
something here
}
Here is one approach to that,
String[] test = new String[] { "00:00", "NN:NN", "12,13", "12:13" };
for (String fmt : test) {
boolean isValid = true;
for (int i = 0; i < fmt.length(); i++) {
char c = fmt.charAt(i);
if (i == 2) {
if (c != ':') { // here is the colon check.
isValid = false;
break;
}
} else {
// This checks for digits!
if (!Character.isDigit(c)) {
isValid = false;
break;
}
}
}
System.out.println(fmt + " is " + isValid);
}
Output is
00:00 is true
NN:NN is false
12,13 is false
12:13 is true
#WillBro posted a good answer but I give you another option:
myString.indexOf(":") == 5
With indexOf you can also look for full String inside a String.
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html
But for string format validations I suggest you to use Regular Expresions.
Here's a full example that does what you want to do:
http://www.mkyong.com/regular-expressions/how-to-validate-time-in-24-hours-format-with-regular-expression/

Java - See if a string contains any characters in it

The problem i'm having is when i check to see if the string contains any characters it only looks at the first character not the whole string. For instance I would like to be able to input "123abc" and the characters are recognized so it fails. I also need the string to be 11 characters long and since my program only works with 1 character it cannot go any further.
Here is my code so far:
public static int phoneNumber(int a)
{
while (invalidinput)
{
phoneNumber[a] = myScanner.nextLine();
if (phoneNumber[a].matches("[0-9+]") && phoneNumber[a].length() == 11 )
{
System.out.println("Continue");
invalidinput = false;
}
else
{
System.out.print("Please enter a valid phone number: ");
}
}
return 0;
}
For instance why if i take away the checking to see the phoneNumber.length() it still only registers 1 character so if i enter "12345" it still fails. I can only enter "1" for the program to continue.
If someone could explain how this works to me that would be great
Your regex and if condition is wrong. Use it like this:
if ( phoneNumber[a].matches("^[0-9]{11}$") ) {
System.out.println("Continue");
invalidinput = false;
}
This will only allow phoneNumber[a] to be a 11 character long comprising only digits 0-9
The + should be outside the set, or you could specifically try to match 11 digits like this: ^[0-9]{11}$ (the ^ and $ anchor the match to the start and end of the string).
You need to put the "+" after the "]" in your regex. So, you would change it to:
phoneNumber[a].matches("[0-9]+")
Why not try using a for loop to go through each character?
Like:
public static int phoneNumber(int a)
{
while (invalidinput)
{
int x = 0;
for(int i = 0; i < phoneNumber[a].length(); i++)
{
char c = phoneNumber[a].charAt(i);
if(c.matches("[0-9+]")){
x++;
}
}
if (x == phoneNumber[a].length){
System.out.println("Continue");
invalidinput = false;
}
else
{
System.out.print("Please enter a valid phone number: ");
}
}
return 0;
}
Are the legal characters in your phone numbers 0..9 and +? If so, then you should use the regular expression [0-9+]*, which matches zero or more legal characters. (If not, you probably meant [0-9]+.) Also, you can use [0-9+]{11} instead of your explicit check for a length of 11.
The reason that your current code fails, is that String#matches() does not check whether the regular expression matches part of the string, but whether it matches all of the string. You can see this in the JavaDoc, which points you to Matcher#matches(), which "Attempts to match the entire region against the pattern."

Categories

Resources