can someone please elaborate the following code? - java

This code is the first one I've seen. I am curious as to how it changes all character from a to z into uppercase when the last line of code was only written with (ch[i] - 'a' + 'A').
if (ch[i] >= 'a' && ch[i] <= 'z') {
// Convert into Upper-case
ch[i] = (char)(ch[i] - 'a' + 'A');
}

The line:
ch[i] = (char)(ch[i] - 'a' + 'A');
Sets ch[i] to its associated uppercase due to a constant difference between an uppercase letter and its lowercase form.
For means of communication, the line can be re-written as:
ch[i] = (char)(ch[i] + ('A' - 'a'));
By adding this constant difference the line yields the lowercase letter's uppercase character.

Related

Count Vowels and Consonants

I was exploring this code which gives a count of vowels and consonants, but didn't understand this else if (ch >= 'a' && ch <= 'z') line of code. Please tell me what's the logic behind it.
import java.util.Scanner;
public class Vowels {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
System.out.println("Enter string");
String str = sc.nextLine();
int vowl = 0;
int conso = 0;
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
vowl++;
} else if (ch >= 'a' && ch <= 'z') {
conso++;
}
}
System.out.println(vowl);
System.out.println(conso);
}
}
A benefit of chars is that you can operate with them like if they were integers.
For example, you can do you this as well 'a' + 3 = 'd'
Meaning that 'a' < 'd' = true.
notice the if statement catches all vowels
whats ever is not a vowel will either be a capital letter, a number, a special character or consonants
else if (ch >= 'a' && ch <= 'z')
this checks if its not a vowel does it atleast fall in the range of small letter 'a'-'z' and is not a special charecter or a number.( we knonw its not a vowel but is it in the ascii range 26=a -51=z)
refer to the ASCII table to understand the range comparison
The comparison of characters the way it is done can create confusion, as you can see from Java: Character comparison.
Basically #TDG is correct by saying that ch is checked to be between 'a' and 'z', and thus the check might be translated as "is ch a lower case character?"
The tricky part is that depending on the language people use the expectation can be different, especially since language specific characters are not taken into account. In German language, 'รถ' would definitely qualify as lower case character but is not in the range of the check. The complexity may get evident by studying the Unicode code charts.
The best check is to use Character.isLowerCase().
char is a character that represented by a number which is the index of the character in the ASCII/unicode table, since the the alphabet characters are arranged in order in the ASCII table, the following code checks if the ch is in the range of the lowercase alphabet characters representation which is 97 to 122 in the table.
using (int) ch you can see the decimal value of the character and can compare it with the index in the ASCII table.
you can see the ASCII table here:https://www.asciitable.com/

print Alphabets Aa Bb Cc Dd

I'm trying to print Aa Bb Cc but it always repeat A to z then B to z.
char ch, ch2;
for(ch = 'A'; ch <= 'Z'; ch++){
for(ch2 = 'a'; ch2 <= 'z'; ch2++)
System.out.println(ch + "" + ch2);
You don't want nested loops:
for(ch = 'A'; ch <= 'Z'; ch++)
for(ch2 = 'a'; ch2 <= 'z'; ch2++) {
/* All combinations of ch and ch2: Aa..AzBa..Bz..Za..Zz */
}
But a single one:
for(char ch = 'A'; ch <= 'Z'; ch++){
System.out.println(ch + "" + (char)(ch - 'A' + 'a'));
Edit: what does (char)(ch - 'A' + 'a') stand for?
ch in 'A'..'Z' range (from for loop)
ch - 'A' in 0..26 range
ch - 'A' + 'a' in 'a'..'z' range
Finally, since ch - 'A' + 'a is of type int and want it be 'a', not 96 we cast int bak to (char) or you can use Character.toLowerCase(ch) as M. Prokhorov suggested in comments below:
for(char ch = 'A'; ch <= 'Z'; ch++){
System.out.println(ch + "" + Character.toLowerCase(ch));
As #Dmitry indicated, you don't want nested loops.
You can take advantage of the fact that Java chars can be converted to and from ints due to how characters are represented. See the Wikipedia article on ASCII for more details on that. It also has a handy chart of the ASCII values for each character. For example, A is ASCII 65, and a is ASCII 97. That being said, you can do arithmetic in order to "convert" between uppercase and lowercase letters. Uppercase and lowercase letters differ by 32.
That being said, you can do this with two lines of code:
for(char ch = 'A'; ch <= 'Z'; ch++){
System.out.println(ch + "" + (char)(ch + 32));
Or you could also use one of the excellent solutions that #Dmitry suggested.
How a nested loop works:
Step 1: First, Compiler will check for the condition inside the first for loop.
If the condition is True then statements inside the For loop will be
executed. It means, compiler will enter into second For loop (In your case ch has the value 'A'). Goto
Step 2
If the condition is False then, compiler will exit from For Loop
Step 2: Compiler will check for the condition inside the second for loop.
If the condition is True, statements inside the second For loop will
be executed. It means, it will execute from Statement 1 to N.(In your case from 'a' to 'Z')
If the condition is False, compiler will exit from second For Loop
Step 3: Once it exit from second for loop, compiler will check for the condition inside the for loop (repeating Step 1 ) (Here your outer loop variable ch will have the value 'B' and so on)
A simple trick could be to intialize your ch2 variable outside the loop and work with a simple loop:
char ch, ch2 = 'a';
for(ch = 'A'; ch <= 'Z'; ch++){
System.out.println(ch + "" + ch2++);}
}

Swap numerals in a String by byte operation

I have a long String containing literals (both upper and lowercase) and numerals (0 to 9).
I am doing some byte operations on that string. So for example I am replacing all uppercase literals with their lowercase equivalents like this:
byte[] bytes = myString.getBytes();
for (int i = 0; i < bytes.length; i++) {
if(bytes[i] >= 'A' && bytes[i] <= 'Z')
bytes[i] = (byte)( 'a' + (bytes[i] - 'A'));
}
myString = new String(bytes);
I also want to swap all numerals i.e. replace all 0 by 9, all 1 by 8 and so on the same way but couldn't figure out the exact statement. I tried:
if(bytes[i] >= '0' && bytes[i] <= '9') bytes[i] = (byte)( '0' + (bytes[i] - '9'));
but it just adds some special chars to my output, so I think the if statement is wrong. Any idea how to swap those numerals in a byte operation?
Your order of operands is wrong.
bytes[i] = (byte)( '9' - (bytes[i] - '0'));
When doing stuff like this, always have an ascii table at hand http://www.asciitable.com/
In terms of the special chars when manipulating digits, you have the subtraction the wrong way round:
'0' + (bytes[i] - '9')
should be
'0' + ('9' - bytes[i])
If you are manipulating characters, use String.toCharArray(), not String.getBytes(): String is logically a char[], not byte[].
Single characters in the string may be converted to two bytes; doing arithmetic on individual bytes may result in you changing "half" of the character, which will probably lead to funky results when you try to convert it back to a string.
You can do pretty much the same thing using chars instead:
char[] chars = myString.toCharArray();
for (int i = 0; i < chars.length; i++) {
if(chars[i] >= 'A' && chars[i] <= 'Z')
chars[i] = (char) ('a' + (chars[i] - 'A'));
}
myString = new String(chars);
It would be much easier to read and less error-prone to use Character.toLowercase(chars[i]) (similar methods exist for digits), rather than doing arithmetic on character values.
You can't use to replace numbers like the same way you are replacing the lower to upper and vice versa. Because ASCII values for numbers are in series and you are going beyond that limit. Instead of that you have to try 10 if conditions like this;
if(bytes[i] == '0')
bytes[i] = '9'
else if(bytes[i] == '1')
bytes[i] = '8'
And so on....

How do I get the numerical value/position of a character in the alphabet (1-26) in constant time (O(1)) without using any built in method or function?

How do I get the numerical value/position of a character in the alphabet (1-26) in constant time (O(1)) without using any built in method or function and without caring about the case of the character?
If your compiler supports binary literals you can use
int value = 0b00011111 & character;
If it does not, you can use 31 instead of 0b00011111 since they are equivalent.
int value = 31 & character;
or if you want to use hex
int value = 0x1F & character;
or in octal
int value = 037 & character;
You can use any way to represent the value 31.
This works because in ASCII, undercase values are prefixed with 011, and uppercase 010 and then the binary equivalent of 1-26.
By using the bitmask of 00011111 and the AND operand, we covert the 3 most significant bits to zeros. This leaves us with 00001 to 11010, 1 to 26.
Adding to the very good (self) answer of Charles Staal.
Assuming ascii encoding following will work. Updated from the kind comment of Yves Daoust
int Get1BasedIndex(char ch) {
return ( ch | ('a' ^ 'A') ) - 'a' + 1;
}
This will make the character uppercase and change the index.
However a more readable solution (O(1)) is:
int Get1BasedIndex(char ch) {
return ('a' <= ch && ch <= 'z') ? ch - 'a' + 1 : ch - 'A' + 1;
}
One more solution that is constant time but requires some extra memory is:
static int cha[256];
static void init() {
int code = -1;
fill_n (&cha[0], &cha[256], code);
code = 1;
for(char s = 'a', l = 'A'; s <= 'z'; ++s, ++l) {
cha[s] = cha[l] = code++;
}
}
int Get1BasedIndex(char ch) {
return cha[ch];
}
We can get their ASCII values and then subtract from the starting character ASCII(a - 97, A - 65)
char ch = 'a';
if(ch >=65 && ch <= 90)//if capital letter
System.out.println((int)ch - 65);
else if(ch >=97 && ch <= 122)//if small letters
System.out.println((int)ch - 97);
Strictly speaking it is not possible to do it portably in C/C++ because there is no guarantee on the ordering of the characters.
This said, with a contiguous sequence, Char - 'a' and Char - 'A' obviously give you the position of a lowercase or uppercase letter, and you could write
Ord= 'a' <= Char && Char <= 'z' ? Char - 'a' :
('A' <= Char && Char <= 'Z' ? Char - 'A' : -1);
If you want to favor efficiency over safety, exploit the binary representation of ASCII codes and use the branchless
#define ToUpper(Char) (Char | 0x20)
Ord= ToUpper(Char) - 'a';
(the output for non-letter character is considered unspecified).
Contrary to the specs, these snippets return the position in range [0, 25], more natural with zero-based indexing languages.

How would I loop around the alphabet? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 8 years ago.
Improve this question
This is a bit more trickier than I thought..
I am creating a java program that is encrypted:
the input is 'a' and shift the letter by 5 which goes to 'f'
which is simple in ASCII but when I get to the letter z i want the program to loop back around to 'a' and start over if that makes sense just i have no idea where to start!
The key is modulus division:
char c;
c = (char)((c - 'a' + 5) % 26 + 'a');
c - 'a' gives you the number of the letter 0-25, which is then shifted up by 5 and the remainder after dividing by 26 is then added to 'a' to give up back the character for the letter.
Use mod % operator.
char translated = (char) ('a' + (charOriginal -'a' + 5) % ('z' - 'a' + 1));
Here it is :
public char encrypt(char c)
{
return Character.isLowerCase(c) ? (char)((c - 'a' + 5) % 26 + 'a') : (char)((c - 'A' + 5) % 26 + 'A');
}
I've edited my post, now it checks lower/upper case.
If you don't and minus 'a' for uppercase, it won't work. For example, encrypt('Y') would have returned '^' instead of 'D'.
You could try something like this:
/**
* Shifts a letter 5 letters, if the char is a letter,
* other wise (if a number or symbol) just returns the char.
* Jumps back to 'a' or 'A' when it goes past 'z' or 'Z'.
*/
public char shift5(char letter) {
char letterToReturn = letter;
if(letterToReturn >= 'a' && letter <= 'z') {
// letter is lowercase
letterToReturn = shiftLetter(letterToReturn , 5);
} else if(letter >= 'A' && letter <= 'Z') {
// letter is uppercase
letterToReturn = shiftLetter(letterToReturn , 5);
}
return letterToReturn;
}
/**
* Shifts a letter to the next letter the specified amount of times.
* Jumps back to 'a' or 'A' when it goes past 'z' or 'Z'.
*/
public char shiftLetter(char letter, int amountToShift) {
char letterToReturn = letter;
for (int i = 1; i <= amountToShift; i++) {
letterToReturn ++;
if(letterToReturn == (char)((int)'z' + 1) {
// letter has gone past 'z', so change to 'a'
letterToReturn = 'a'
} else if(letterToReturn == (char)((int)'Z' + 1) {
// letter has gone past 'Z', so change to 'A'
letterToReturn = 'A'
}
}
return letterToReturn;
}
This code handles lowercase, uppercase, and characters that aren't letters.

Categories

Resources