Checking string for large amount of different, incremental values - java

Currently I am checking a string for the following:
if(parseCommand.contains("vlan1")
|| parseCommand.contains("Fa0/1i") || parseCommand.contains("Fa0/1o")
|| parseCommand.contains("Fa1/0") || parseCommand.contains("Fa1/1")
|| parseCommand.contains("Fa1/2") || parseCommand.contains("Fa1/3")
|| parseCommand.contains("Fa1/4") || parseCommand.contains("Fa1/5")
|| parseCommand.contains("Fa1/6") || parseCommand.contains("Fa1/7")
|| parseCommand.contains("Fa1/8") || parseCommand.contains("Fa1/9")
|| parseCommand.contains("Fa1/11") || parseCommand.contains("Gi0"))
{
//do things here
}
However it may contain vlan1 up to vlan4094 and i have to check for these. What is the simplest way to do this, do I have to stick it all in a for loop incrementing to 4094 I guess?
for (int i = 1; i <= 4094; i++)
{
if(parseCommand.contains("vlan"[i]))
{
//do stuff here
}
}
if(other conditions from above)
{
//do same stuff again here
}
Or else I could stick all the conditions in the for loop and do everything inside there. This all seems messy, is there a non-messy way of doing it?

I think this regex should do it:
String parseCommand = "vlan4094";
if (parseCommand.matches(".*?vlan([1-3][0-9]{3}|" +
"[1-9][0-9]{0,2}|" +
"40(9[0-4]|[0-8][0-9])).*"))
System.out.println("matches");
[1-3][0-9]{3} - 1000-3999
[1-9][0-9]{0,2} - 1-999
9[0-4] - 90-94
[0-8][0-9] - 00-89
40(9[0-4]|[0-8][0-9]) - 4000-4094
Something like this is probably simpler:
String parseCommand = "vlan4094";
if (parseCommand.startsWith("vlan"))
{
int v = Integer.parseInt(parseCommand.substring(4));
if (v >= 1 && v <= 4094)
/* do stuff */
}
Suggested change:
Replace:
parseCommand.contains("Fa1/0") || parseCommand.contains("Fa1/1")
|| parseCommand.contains("Fa1/2") || parseCommand.contains("Fa1/3")
|| parseCommand.contains("Fa1/4") || parseCommand.contains("Fa1/5")
|| parseCommand.contains("Fa1/6") || parseCommand.contains("Fa1/7")
|| parseCommand.contains("Fa1/8") || parseCommand.contains("Fa1/9")
with
parseCommand.matches(".*?Fa1/[0-9].*")

You can combie them into one boolean
boolean b = false;
for(int i = 1 ; i < 4094 ; i ++){
b = b || parseCommand.contains("vlan" + i);
}
Then check your boolean value

If the only problem is with "vlanXXX" you can remove the "vlan" part of the string:
parseCommand = parseCommand.replaceFirst("vlan", "");
and then cast it to int
int value = Integer.parseInt(parseCommand);
and then comparing this result with that whaat you want
if((value >= 1) && (value <= 4094)){....}
This will only work for the given case and you have to handle the case where parseCommand cannot be cast to int. And it is much more understandable than using whatever regular expresion

Related

Trying to understand a method

I have a method which I have to write called personalize. This is what it's suppose to do / what I've done so far.
// personalize takes a String and validates it
// if it is a valid plate, it changes the plateNumber to
// the new plateNumber and calculates the cost of the plate.
// the method returns true if the new plateNumber is valid and the plate was changed,
// and false if the new plateNumber was invalid and no changes were made.
// A personalized plate may be 3 up to 7 chars and 1 space or dash
// Use letters, numbers, dashes, and spaces ONLY
// A personalized plate costs $10 extra plus $5 per letter (not including dashes or spaces)
public boolean personalize(String vanity)
{
boolean valid = true;
vanity = "";
for(int i = 0; i < vanity.length(); i++)
{
if(vanity.length() < 7 && vanity.length() > 3)
{
valid = true;
}
if(Character.isLowerCase(vanity.charAt(i)) || vanity.length() > 7 || vanity.length() < 3 ||
vanity.charAt(i) == '!' || vanity.charAt(i) == '.' || vanity.charAt(i) == '$' ||
vanity.charAt(i) == '#' || vanity.charAt(i) == '*' || vanity.charAt(i) == '_' ||
vanity.charAt(i) == '#' || vanity.charAt(i) == '^' || vanity.charAt(i) == '&')
{
valid = false;
}
}
if(valid = true)
{
plateCost += 25;
}
return valid;
}
I know everything I have in this method isn't completely correct but I'm extremely confused on it. I was thinking about writing a helper method, but I'm unsure if it would be for the cost (newCost) or for the new plate number (personalizedPlate). Or would I have to write both? I'm not simply looking for the answer to my work. I'm really looking for someone to help me through the problem to better understand what to do and why I have to do it that way.
Don't try to do everything in one method. The following code demonstrates one way of implementing these requirements:
public class Plate {
int plateCost = 0;
public boolean personalize(String vanity) {
boolean valid = validate3to7chars(vanity);
valid = valid && hasOnlyOneSpaceOrDash(vanity);
valid = valid && hasValidCharacters(vanity);
if (valid) {
String plateWithoutSpacesAndDashes = vanity.replaceAll(" ", "").replaceAll("-", "");
plateCost = 10 + plateWithoutSpacesAndDashes.length() * 5;
}
return valid;
}
private boolean hasValidCharacters(String vanity) {
String toVerify = vanity.replaceAll(" ", "").replaceAll("-", ""); //remove dashes and spaces
return toVerify.matches("[0-9a-zA-Z]+"); // verify that the place has only numbers and letters
}
private boolean hasOnlyOneSpaceOrDash(String vanity) {
boolean spaces = vanity.lastIndexOf(" ") == vanity.indexOf(" ");
boolean dashes = vanity.lastIndexOf("-") == vanity.indexOf("-");
return spaces && dashes;
}
private boolean validate3to7chars(String vanity) {
return vanity.length() >= 3 && vanity.length() <= 7;
}
public static void main(String[] args) {
Plate p = new Plate();
System.out.println(p.personalize("abc-52s")); // true
System.out.println(p.personalize("123 52s")); // true
System.out.println(p.personalize(" abc62s")); // true
System.out.println(p.personalize("abc56s ")); // true
System.out.println(p.personalize("abc562+")); // false
System.out.println(p.personalize("12345678")); // false
}
}

How to Check Every Letter as a String

I'm failing the following test case:
#Test (timeout=3000) public void gatenot_0(){
GateNot g = new GateNot (new Wire("inw"), new Wire("outa"));
g.feed("0");
boolean ans = g.propagate();
assertEquals(sigs1, g.read());
}
which says "Invalid character" - Exception thrown by the following method:
public static List <Signal> fromString(String inps)
{
List<Signal> values = new ArrayList<Signal>();
for(int i = 0; i < inps.length(); i++)
{
if(inps.charAt(i) != '1' && inps.charAt(i) != '0'
&& inps.charAt(i) != 'X' && inps.charAt(i) != 'x'
&& inps.charAt(i) != ' ' && inps.charAt(i) != '\t')
throw new ExceptionLogicMalformedSignal(inps.charAt(0), "Invalid character!");
else if(inps.charAt(i) == '1')
values.add(HI);
else if(inps.charAt(i) == '0')
values.add(LO);
else if(inps.charAt(i) == 'X')
values.add(X);
else if(inps.charAt(i) == 'x')
values.add(X);
}
return values;
}
Everytime I pass something including "0" or "1" it throws Exception So, should I check every letter of String inps as a String instead of charAt(). If yes, how should I check that? Thanks in advance.
To check every letter as a string you could use
Character.toString(inps.charAt(i))
instead of just inps.charAt(i)
I would recommend storing it in a variable for each iteration instead of calling many times.
You could also do
String.valueOf(inps.charAt(i))
There is a shortcut
inps.charAt(i) + ""
And yet another way:
inps.substring(i, i + 1)
Note that if you end of converting each letter to string, you should use the .equals method when comparing them.
For more information about this, you can look at How to convert a char to a String?

Why is this becoming an infinite loop?

All i need this method to do is take a string lets say "aaxbb" and it will return true because there is an 'aa' and a 'bb',
If the string given is length = 0 or length = 1 it should fail.
The issue i'm having is that which i do not know.. i know that in my terminal after hasAdjacentPair's first test case Pass's, i get a blinking curser meaning that somehwere in this method i'm not kicking out of one of my loops for it to continue to check the string for any more adjacent pairs
the first test case passes while its an empty string "" = because it returned false
the second test case passes while its "a" = because it returned false
We are also not allowed to use Arrays :(
public boolean hasAdjacentPair(String str)
{
boolean result = false;
if (str.length() == 0)
{
result = false;
}
if (str.length() == 1)
{
result = false;
}
while (str.length() != 0)
{
for (int i = 0; i < str.length() - 1; ++i)
{
char adjChar = str.charAt(i);
char nextAdjChar = str.charAt(i + 1);
if (adjChar == nextAdjChar)
{
result = true;
}
}
}
return result;
}
Changed my while loop while (str.length() != 0) to while (str.length() != 0 && str.length() != 1) this enabled test 2 to work
EDIT 2 : After i completely took out the while (str.length() != 0) All 5 of my test cases pass :) so i guess it was just that?
while (str.length() != 0)
is always true and loop never end. Instead of if..if..while structure use either switch on length of string or if-else.
You could try something like this
if (str.length() == 0)
{
result = false;
}
else if (str.length() == 1)
{
result = false;
}
else
{
for (int i = 0; i < str.length() - 1; ++i)
{
char adjChar = str.charAt(i);
char nextAdjChar = str.charAt(i + 1);
if (adjChar == nextAdjChar)
{
result = true;
break;
}
}
If you checking for atleast one pair make use of break statement as you already know that you got the result
try this alternative:
boolean c = false;
//Your other code
while (str.length() != 0 && c == false)
{
for (int i = 0; i < str.length() - 1; ++i)
{
char adjChar = str.charAt(i);
char nextAdjChar = str.charAt(i + 1);
if (adjChar == nextAdjChar)
{
result = true;
}
}
c = true;
}
//Your other code
Is there a reason you have a while loop checking for the str length? The str is not modified in the loop.
What you most likely want is an if, else if, else structure.
You can most likely return true within the adjChar == nextAdjChar if statement and return false at the end of your function.

Cannot find symbol, Java and Strings

I've tried tinkering around with this for awhile and have yet to figure out what its giving me this error. The code is far from complete but I'm just trying to figure out why it says it can't find variable ch1. Any help is greatly appreciated!
public class PhoneNumber {
String phoneNumber;
public PhoneNumber(String num) {
phoneNumber = num;
}
public String decodePhoneNumber() {
// Takes string form phone number and decodes based on number pad
// Find code that makes if statement not care about caps
// so if a || b || c number[cnt] = 1 etc..
for (int cnt = 0; cnt < phoneNumber.length(); cnt++) {
char ch1 = phoneNumber.charAt(cnt);
if (Character.ch1.equalsIgnoreCase("a") || ("b") || ("c")) {
} else if (ch1.equalsIgnoreCase("d" || "e" || "f")) {
} else if (ch1.equalsIgnoreCase("j" || "k" || "l")) {
} else if (ch1.equalsIgnoreCase("m" || "n" || "o")) {
} else if (ch1.equalsIgnoreCase("p" || "q" || "r" || "s")) {
} else if (ch1.equalsIgnoreCase("t" || "u" || "v")) {
} else {
}
}
}
}
You have syntax errors and that is why you cannot find ch1.
Try modifying your code as per this syntax. These changes need to be done in all the conditionals.
if ((ch1 == 'a') || (ch1 == 'b') || (ch1 =='c')) {
If you want to make it work regardless of capital letters then you would need to normalize the input to lower case and then do the character comparison:
char ch1 = phoneNumber.toLowerCase().charAt(cnt);
if (ch1 == 'a' || ch1 == 'b' || ch1 == 'c') {
// Do something
}
...

Hexadecimal Validation Algorithm

I'm trying to validate a hexadecimal number and its not going too well. I'm trying the code below but my logic isn't exactly on the ball. Any help?
if (!array[i].equals("A") || !array[i].equals("B") || !array[i].equals("C") || !array[i].equals("D") || !array[i].equals("E") || !array[i].equals("F"))
{
b[i] = false;
}
else
{
b[i] = true;
}
The aim of the above code is to give me a true or false value. True being the value is between A to F false being the value isn't between A to F.
if ((array[i]-'A') > 5)
b[i]=false;
else
b[i]=true;
Change all || to &&.
Right now your if condition always evaluates to true (since any string is not equal to either "A" or "B").
Alternatively, replace the whole construct with:
b[i] = array[i].equals("A") || array[i].equals("B") || array[i].equals("C") ||
array[i].equals("D") || array[i].equals("E") || array[i].equals("F");
if (array[i].equals("A") || array[i].equals("B") || array[i].equals("C") || array[i].equals("D") || array[i].equals("E") || array[i].equals("F"))
{ b[i] = true; }
else
{ b[i] = false; }
alternatively you could use a List and use .contains() as well.
List<String> hexchars = new ArrayList<String>();
hexchars.add("A");
hexchars.add("B");
hexchars.add("C");
hexchars.add("D");
hexchars.add("E");
hexchars.add("F");
return hexchars.contains("A");
But a regular expression would be the cleanest way to do this in the long run.

Categories

Resources