ASCII character ranges using for loop - java

How do I cover the range of all letters lowercase a-z & uppercase A-Z using a for loop? Currently I have:
public static boolean isJavaIdentifierStart (char c) {
if (c == 'a') { //how do I cover the range of all lowercase letters with a for loop?
return true;
} if (c=='Z') { //how do I cover all uppercase letters with a for loop?
return true;
} else if (c == '_') {
return true;
} else if (c == '$') {
return true;
} else
return false;
}
}

If would be much easier to test with the >= and <= operators:
if( c >= 'a' && c <= 'z' ) {
// do something
}
You don't actually need to test all of the values in the range, just make sure c falls inside it somewhere. You can do something similar for uppercase letters.
In fact you can simplify your method into a single return statement:
public static boolean isJavaIdentifierStart (char c) {
return (c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c == '_') ||
(c == '$');
}
However, I don't believe that Java identifiers can start with $, so your method is incorrect.

It's hard to guess what you want, but you could use:
for(char c = 'a'; c < 'z'; c++) {
System.out.println(c);
}
Edit to your comment:
Use this expression: (c >= 'a' && c <= 'Z') and similiar for range-
checking.
This works since char is a 16 bit unsigned integer, and therefore can be use in calculations.

Related

Automaton DFA implementation not working using Java

I'm studying right now, at my university, DFA and NFA automatons and how to implement some of them using Java code.
I am having some trouble with this exercise: we have 4 different laboratory turns (T1, T2, T3 and T4) and we need to write code in order to recognize if a particular string (composed of the university badge number of a student and his name, e.g., 123321Johnson) corresponds to T2 or T3.
We know that:
T1 is the turn of the ones who have an odd badge number and surname between "A" and "K"
T2 is the turn of even badge numbers and surnames between "A" and "K"
T3 is the turn of odd badge numbers and surnames between "L" and "Z"
T4 is the turn of even badge numbers and surnames between "L" and "Z"
We also know that the string has to be composed of at least one number and at least one letter.
E.g., the automaton has to accept "1232324Gac" or "1232323Lum" but not "121234Lum" or "121233Gac".
Here's the code I wrote:
import java.util.Scanner;
public class Es3 {
static Scanner sc = new Scanner(System.in);
String s = sc.next();
public static boolean scan(String s)
{
int state = 0;
int i = 0;
while (state >= 0 && i < s.length()) {
final char ch = s.charAt(i++);
switch (state) {
case 0:
if (ch >= 0 && ch <= 9)
state = 1;
else
state = -1;
break;
case 1:
if (ch >=0 && ch <=9)
state = 1;
else if (ch >='a' && ch <='k')
if ((s.charAt(i--))%2==0)
state = 2;
else
state = -1;
else if (ch >='l' && ch <='z')
if ((s.charAt(i--))%2==1)
state = 3;
else
state = -1;
else
state = -1;
break;
case 2:
if (ch >='a' && ch <='z')
state = 2;
else
state = -1;
break;
case 3:
if (ch >='a' && ch <='z')
state = 3;
else
state = -1;
break;
}
}
return (state == 2 || state == 3);
}
public static void main(String[] args)
{
System.out.println(scan(args[0]) ? "OK" : "NO");
}
}
Obviously, the code is not working, but this is important to show the general purpose of the exercise.
Could someone help me?
The reason your algorithm wasn't working is because you were trying to compare char values to int values, which wouldn't give the anticipated result. Also, when you were checking if a char value was in a certain letter range, you didn't take capital letters into account.
import java.util.Scanner;
public class Es3
{
static Scanner sc = new Scanner(System.in);
String s = sc.next();
public static boolean scan(String s)
{
int state = 0;
int i = 0;
while (state >= 0 && i < s.length()) {
final char ch = s.charAt(i++);
switch (state) {
case 0:
// Compare the char to the char values of the numbers
if (ch >= '0' && ch <= '9')
state = 1;
else
state = -1;
break;
case 1:
// Same here, compare the char to the char values of the numbers
if (ch >= '0' && ch <= '9')
state = 1;
// Check if the char is capital, as well as lowercase
else if ((ch >= 'a' && ch <= 'k') || (ch >= 'A' && ch <= 'K'))
// Convert the char to an int before performing the calculations
if ((Character.getNumericValue(s.charAt(i-1)))%2 == 0)
state = 2;
else
state = -1;
// Check if the char is capital as well
else if ((ch >= 'l' && ch <= 'z') || (ch >= 'L' && ch <= 'Z'))
// Convert from char to int before calculating
if ((Character.getNumericValue(s.charAt(i-1)))%2 == 1)
state = 3;
else
state = -1;
else
state = -1;
break;
case 2:
// Check if the char is capital as well
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
state = 2;
else
state = -1;
break;
case 3:
// Check if the char is capital as well
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
state = 3;
else
state = -1;
break;
}
}
System.out.println("State "+state);
return (state == 2 || state == 3);
}
public static void main(String[] args)
{
System.out.println(scan(args[0]) ? "OK" : "NO");
}
}
I think the code above should do what you’re trying to do.

Java- getting wrong output

Here's my code that I've written :
public String binary(String s)
{
String[] a = {
"0000","0001","0010","0011","0100","0101","0110","0111",
"1000","1001","1010","1011","1100","1101","1110","1111"
};
String k = "";
for(int i = 0; i <= s.length() - 1; i++)
{
if (s.charAt(i) == 'a') { k += a[10]; }
else if (s.charAt(i) == 'b') { k += a[11]; }
else if (s.charAt(i) == 'c') { k += a[12]; }
else if (s.charAt(i) == 'd') { k += a[13]; }
else if (s.charAt(i) == 'e') { k += a[14]; }
else if (s.charAt(i) == 'f') { k += a[15]; }
else { k += a[i]; }
}
return k;
}
I am getting output as a[0-9] = 0000. How can I fix this? What am I doing wrong?
The problem is with use of a[i]. It is a logical error. Because i is loop variable which indicates the current index in s String. But you are using it to indexing it in variable a. So, i variable is use incorrectly here.
Following is corrected (and a bit optimized) code. See it working here:
public class HexaDecimal
{
public String binary(String s)
{
String[] a= {"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
String k="";
for(int i=0;i<s.length();i++)
{
char ch = Character.toUpperCase(s.charAt(i));
if(ch>='A' && ch <= 'F') k+= a[ch - 'A' + 10];
else k+= a[ch - '0'];
}
return k;
}
}
Replace k+=a[i]; with k+=a[s.charAt(i) - '0'];
You're using your string index loop variable as an index into a rather than the character at that location in the string.
You need to do - '0' to convert from unicode codepoint to the value it represents as an ASCII digit (which I assume you want to use here)
Your last else does the incorrect calculation. It does not take into consideration what is inputted, only the position. You want it to be
else {
k += a[s.charAt(i) - '0'];
}
There are easier ways to get the binary representation of hexadecimals, and you probably also want to check the input that it does not contain anything else than 0-9 or a-f.
You can change the for loop to this:
for(int i=0; i < s.length(); i++)
{
char c = s.charAt(i);
if (c >= '0' && c <= '9') k += a[c - '0'];
else if (c >= 'a' && c <= 'f') k += a[c - 'a' + 10];
else if (c >= 'A' && c <= 'F') k += a[c - 'A' + 10];
else throw new InvalidArgumentException(s);
}
This is a lot simpler and self-explanatory, at least in my opinion. Handles digits, uppercase and lowercase letters, and fails in an expected way on bad input.

Java: Left-hand side of an argument must be a variable charAt error

I am replacing all vowels in a String with a char using a for loop.
public String replaceVowel(String text, char letter)
{
char ch;
for(int i = 0; i<text.length(); i++)
{
ch = text.charAt(i);
if(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' || ch == 'y')
{
ch = letter;
}
text.charAt(i) = ch;
}
return text;
}
The code trips on an error on line:
text.charAt(i) = ch;
In this line I am attempting to initialize the char at the loop's location of the string. However the line produces the error:
The left-hand side of an assignment must be a variable
Any help is appreciated!
As oppsed to C++, Java method call never return a variable "reference" (like C++ reference) so you can never assign a method call result.
Also Java string is immutable, which means you cannot change individual characters in a string without creating a new string. See this post Replace a character at a specific index in a string? on this topic.
charAt(index) returns the character in that index. It cannot be used for assigning values.
Something like this would work:
char ch;
String text = "hailey";
char letter = 't';
char[] textAsChar = text.toCharArray();
for(int i = 0; i<text.length(); i++)
{
ch = text.charAt(i);
if(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' || ch == 'y')
{
ch = letter;
}
textAsChar[i] = ch;
}
System.out.println(String.valueOf(textAsChar));

How can I uppercase and lowercase a Char

GWT is not allowing me to use Character.toUpperCase(char) and Character.toLowerCase(char). How can I rewrite the method bellow to not use the Character class or any external library
public static String toDisplayCase(String s) {
final String ACTIONABLE_DELIMITERS = " '-/"; // these cause the character following
// to be capitalized
StringBuilder sb = new StringBuilder();
boolean capNext = true;
for (char c : s.toCharArray()) {
c = (capNext)
? Character.toUpperCase(c)
: Character.toLowerCase(c);
sb.append(c);
capNext = (ACTIONABLE_DELIMITERS.indexOf((int) c) >= 0); // explicit cast not needed
}
return sb.toString();
}
If somehow, you are not allowed to use Character class (though that sounds quite crazy), you may add or subtract ASCII values.
eg:
for (char c : s.toCharArray()) {
c = (capNext)
? ( (c>='a'&&c<='z') ? c+32 : c) //to Upper Case
: ( (c>='A'&&c<='Z') ? c-32 : c) //to Lower Case
sb.append(c);
capNext = (ACTIONABLE_DELIMITERS.indexOf((int) c) >= 0); // explicit cast not needed
}
Just use basic operators
if (c >= 'a' && c <= 'z')
c = c - 'a' + 'A'; // lower to upper
if (c >= 'A' && c <= 'Z')
c = c - 'A' + 'a'; // upper to lower
Here are toLower and toUpper using ascii values. Hope it helps.
static char toUpperCase(char c) {
if (97 <= c && c <= 122) {
c = (char) ((c - 32));
}
return c;
}
static char toLowerCase(char c) {
if (65 <= c && c <= 90) {
c = (char) ((c + 32));
}
return c;
}

Converting charAt check 'containing A-Z' to 'not containing A-Z'

I would like to check if a String input contains characters other than alphabets. Below is my current code:
if ((name.charAt(i) >= 'a' && name.charAt(i) <= 'z') ||
((name.charAt(i) >= 'A' && name.charAt(i) <= 'Z')))
How can I change the code such that it functions as check if name.charAt(i) "is not equals to A to Z OR a to z?
Just negate your condition :
if (!((name.charAt(i) >= 'a' && name.charAt(i) <= 'z') || ((name.charAt(i) >= 'A' && name.charAt(i) <= 'Z'))))
String str = "1234";
if(!str.matches("[a-zA-Z]+")){
System.out.println("not contains alphabets");
}else{
System.out.println("contains alphabets");
}
I'll demonstrate a systematic approach to this which can help you in other similar situations. First, to improve readability, extract the char to a local var.
char ch = name.charAt(i);
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') ...
Now you can work with this in terms of DeMorgan's laws. To make things easier, I'll declare some helper boolean vars for each part:
boolean a = ch >= 'a',
z = ch <= 'z',
A = ch >= 'A',
Z = ch <= 'Z';
So, we have your original expression as
(a && z) || (A && Z)
We want the negative of that expression:
!(a && z || A && Z)
Let's clean it up. Apply
to get
!(a && z) && !(A && Z)
Then apply
to the inner expressions:
(!a || !z) && (!A || !Z)
Now substitute the original expresions back in, negating <= into >, >= into <:
(ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z')
this is the negated expression you are looking for, cleaned up of any explicit negations.
Instead of comparing characters for upper & lowercase, use Character.isLetter(char c) method as it checks for both the cases.
char[] chars = name.toCharArray();
boolean isAlphabet = true;
for (char c : chars) {
if (!Character.isLetter(c)) {
//if character is not A-Z or a-z
isAlphabet = false;
}
}

Categories