Here is the code snippet i am trying to figure out whats happening
String line = "Hello";
for (int i = 0; i < line.length(); i++) {
char character = line.charAt(i);
int srcX = 0;
if (character == '.') {
}else{
srcX = (character - '0') * 20;
System.out.println("Character is " + (character - '0') +" " + srcX);
}
}
and executing that code will result to this
Character is 24 480
Character is 53 1060
Character is 60 1200
Character is 60 1200
Character is 63 1260
How a character minus the string which is "0" result in integer?? and where does the system base its answer to have 24,53,60,60,63?
You are allowed to subtract characters because char is an integer type.
The value of a character is the value of its codepoint (more or less, the details are tricky due to Unicode and UTF-16 and all that).
When you subtract the character '0' from another character, you are essentially subtracting 48, the code point of the character DIGIT ZERO.
So, for example, something like '5' - '0' would evaluate to 53 - 48 = 5. You commonly see this pattern when "converting" strings containing digits to numeric values. It is not common to subtract '0' from a character like 'H' (whose codepoint is 72), but it is possible and Java does not care. It simply treats characters like integers.
http://www.ascii.cl/
'0' is 48 in ascii
'H' is 72.
Therefore 72-48 gives you 24
Related
import java.util.*;
public class Dec2Hex {
public static void main (String[] args){
Scanner input new Scanner (System.in);
System.out.print("Enter a decimal number: ");
int decimal = input.nextInt();
String hex = "";
while (decimal != 0) {
int hexValue = decimal % 16;
char hexDigit = (0 <= hexValue && hexValue <= 9)?
(char)(hexValue + '0'): (char)(hexValue - 10 + 'A');
hex = hexDigit + hex;
decimal = decimal/16;
}
System.out.println("The hex number is " + hex);
}
}
This is an example in my book. I understand most of it but can't quite grasp a few parts. The example uses 1234 as the decimal entered.
The remainder of 1234/16 is 2 so hexValue is 2. Therefore hexDigit is 2 + '0'. But hexDigit is a character so what is the meaning of combining or adding 2 and '0'?
The final answer is 4D2. Where in the code did we ever provide instruction for any letter other than 'A'? How did it come up with a 'D'?
Thank you!
I understand now that the second part of the condition is takin a number like "13", subtracting 10 and adding that to 'A'. 3 + 'A' is 'D' in unicode.
I still do not understand adding the '0' to the first part of the condition. Couldn't we just say (char)(hexValue)? Why add '0'?
Thanks!
The remainder of 1234/16 is 2 so hexValue is 2. Therefore hexDigit is 2 + '0'. But hexDigit is a character so what is the meaning of combining or adding 2 and '0'?
The value 2 is an integer value, however the variable type is char. No problem in assigning such a value to a char variable, however this would result in the 0x02 character/byte, which is a control character, not a visible character to display. The digits in the ASCII table to display begins at 0x30 (which is the digit '0'). To get the character value to save in the char variable you add your calculated value 2 with the offset 0x30. To make this calculation easier you use the expression '0'. This is the exact value of 0x30 (or 48 in decimal).
The final answer is 4D2. Where in the code did we ever provide instruction for any letter other than 'A'? How did it come up with a 'D'?
The calculation is as follow:
1234 divided by 16 is 77 with a remainder of 2.
77 divided by 16 is 4 with a remainder of 13 (which is D).
4 divided by 16 is 0 with a remainder of 4.
This results in 4D2. To verify:
4*16*16 + 13*16 + 2 = 1234
Every char has a value number between 0 to 256, each of these numbers encode a printable sign.
For example the value of '0' is 48, and the value of 'A' is 65.
So when adding a constant offset to a character it's like going to that offset in that encoding.
For example '0' + 5 is '5', or 'A' + 3 is 'D'.
So as for your questions:
'0' + 2 is '2', i.e. the printable character of 2.
In the code hexValue had the value of 13, so hexDigit got the value (hexValue - 10 + 'A'), which is (hexValue - 10 + 'A') = 13 - 10 + 'A' = 'A' + 3 = 'D'.
2 + '0' = 2 + 48 = 50
(char)50 = '2'
Note that
'0' = 48
'1' = 49
'2' = 50
...
'9' = 57
Check ASCII Table to learn more about ASCII values.
Demo:
public class Main {
public static void main(String[] args) {
System.out.println((char) 50);
}
}
Output:
2
Ascii table is used for char type, so characters can be represented by decimal values. For example:
'0' in decimal 48
'1' in decimal 49
'2' in decimal 50
...
'9' in decimal 57
'A' in decimal 65
'B' in decimal 66
'C' in decimal 67
'D' in decimal 68
...
'Z' in decimal 90
'a' in decimal 97
'b' in decimal 98
...
'z' in decimal 122
Having that in mind your here are the answers to your questions:
We focus on the line
char hexDigit = (0 <= hexValue && hexValue <= 9)?
(char)(hexValue + '0'): (char)(hexValue - 10 + 'A');
The remainder of 1234/16 is 2 so hexValue is 2. Therefore hexDigit is
2 + '0'. But hexDigit is a character so what is the meaning of
combining or adding 2 and '0'?
For this question the part of interest is
(char)(hexValue + '0')
The value hexValue is 2, so hexValue + '0' is 50, because in ascii table '0' has decimal value 48. Than value of 50 is casted to char, which by ascii table is '2'.
The final answer is 4D2. Where in the code did we ever provide
instruction for any letter other than 'A'? How did it come up with a
'D'?
For this question the part of interest is
(char)(hexValue - 10 + 'A')
The value hexValue is 13. By asci table 'A' has value of 65 and 'D' has value of 68. So hexValue - 10 is 3 and when we sum 3 and 'A' we get 68. Finally we do cast to char and get 'D'.
You can easyly test the answers by executing this piece of code:
public class Main {
public static void main(String[] args) {
System.out.println("Decimal value: "+(2+'0')+" Char value:" +(char)(2+'0'));
System.out.println("Decimal value: "+(3 + 'A')+" Char value: "+ (char)(3+'A'));
}
}
Regards
I came across a code which checks whether a character is between 'a' and 'z' case insensitive. However, I don't understand what the line after that is doing which is:
alphabets[c - 'a']++;
Could someone please explain this code to me?
alphabets = new int[26];
for (int i = 0; i < str.length(); i++)
{
char c = str.charAt(i);
if ('a' <= c && c <= 'z')
{
alphabets[c - 'a']++; // what does this do?
}
}
This code counts the number of times every lower-case letter appears in the strings. alphabets is an array where the first (i.e., index 0) index holds the number of as, the second the amount of bs, etc.
Subtracting a from the character will produce the relative index, and then ++ will increment the counter for that letter.
A char in Java is just a small integer, 16 bits wide. Generally speaking, the values it holds are the values that Unicode [aside: Java does not represent characters as "ASCII"] assigns to characters, but fundamentally, chars are just integers. Thus 'a' is the integer 0x0061, which can also be written as 97.
So, if you have value in the range 'a' to 'z', you have a value in the range 97 to 122. Subracting 'a' (subtracting 97) puts it in the range 0 to 25, which is suitable for indexing the 26-element array alphabets.
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.
There is something that doesn't quite make sense to me. Why does this:
public static int[] countNumbers(String n){
int[] counts = new int[10];
for (int i = 0; i < n.length(); i++){
if (Character.isDigit(n.charAt(i)))
counts[n.charAt(i)]++;
}
return counts;
}
bring up an ArrayOutOfBounds error while this:
public static int[] countNumbers(String n){
int[] counts = new int[10];
for (int i = 0; i < n.length(); i++){
if (Character.isDigit(n.charAt(i)))
counts[n.charAt(i) - '0']++;
}
return counts;
}
does not? The only difference between the two examples is that the index for counts is being subtracted by zero in the second example. If I'm not mistake, shouldn't the first example display correctly since the same value is being checked?
Here are the value being passed for the two methods:
System.out.print("Enter a string: ");
String phone = input.nextLine();
//Array that invokes the count letter method
int[] letters = countLetters(phone.toLowerCase());
//Array that invokes the count number method
int[] numbers = countNumbers(phone);
This is the problem:
counts[n.charAt(i)]++;
n.charAt(i) is a character, which will be converted to an integer. So '0' is actually 48, for example... but your array only has 10 elements.
Note that the working version isn't subtracting 0 - it's subtracting '0', or 48 when converted to an int.
So basically:
Character UTF-16 code unit UTF-16 code unit - '0'
'0' 48 0
'1' 49 1
'2' 50 2
'3' 51 3
'4' 52 4
'5' 53 5
'6' 54 6
'7' 55 7
'8' 56 8
'9' 67 9
The code is still broken for non-ASCII digits though. As it can only handle ASCII digits, it would be better to make that explicit:
for (int i = 0; i < n.length(); i++){
char c = n.charAt(i);
if (c >= '0' && c <= '9') {
counts[c - '0']++;
}
}
'0' is quite different from 0. '0' is the code of the "zero" character.
problem is in the line counts[n.charAt(i)]. here n.charat(i) may return values larger than 9;
The confusion here is that you're thinking '0' == 0. This is not true. When treated as a number, '0' has the ASCII value for the character 0, which is 48.
Because n.charAt(i) returns a character which is then boxed to a number. In this case the character 0 is actually ASCII value 48.
By subtracting character '0', you are subtracting the value 48 and taking the index into a range that is 0-9 because you've checked the character is a valid digit.
String source = "WEDGEZ"
char letter = source.charAt(i);
shift=5;
for (int i=0;i<source.length();i++){
if (source.charAt(i) >=65 && source.charAt(i) <=90 )
letterMix =(char)(('D' + (letter - 'D' + shift) % 26));
}
Ok what I'm trying to do is take the string WEDGEZ, and shift each letter by 5, so W becomes B and E becomes J, etc. However I feel like there is some inconsistency with the numbers I'm using.
For the if statement, I'm using ASCII values, and for the
letterMix= statement, I'm using the numbers from 1-26 (I think). Well actually, the question is about that too:
What does
(char)(('D' + (letter - 'D' + shift) % 26)); return anyway? It returns a char right, but converted from an int. I found that statement online somewhere I didn't compose it entirely myself so what exactly does that statement return.
The general problem with this code is that for W it returns '/' and for Z it returns _, which I'm guessing means it's using the ASCII values. I really dont know how to approach this.
Edit: New code
for (int i=0;i<source.length();i++)
{
char letter = source.charAt(i);
letterMix=source.charAt(i);
if (source.charAt(i) >=65 && source.charAt(i) <=90 ){
letterMix=(char)('A' + ( ( (letter - 'A') + input ) % 26));
}
}
Well I'm not sure if this homework, so i'll be stingy with the Code.
You're Writing a Caesar Cipher with a shift of 5.
To address your Z -> _ problem...I'm Assuming you want all the letters to be changed into encoded letters (and not weird Symbols). The problem is ASCII values of A-Z lie between 65 and 90.
When coding Z (for eg), you end up adding 5 to it, which gives u the value 95 (_).
What you need to do is Wrap around the available alphabets. First isolate, the relative position of the character in the alphabets (ie A = 0, B = 1 ...) You Need to subtract 65 (which is ASCII of A. Add your Shift and then apply modulus 26. This will cause your value to wrap around.
eg, it your encoding Z, (ASCII=90), so relative position is 25 (= 90 - 65).
now, 25 + 5 = 30, but you need the value to be within 26. so you take modulus 26
so 30 % 26 is 4 which is E.
So here it is
char letter = message(i);
int relativePosition = letter - 'A'; // 0-25
int encode = (relativePosition + shift) % 26
char encodedChar = encode + 'A' // convert it back to ASCII.
So in one line,
char encodedChar = 'A' + ( ( (letter - 'A') + shift ) % 26)
Note, This will work only for upper case, if your planning to use lower case, you'll need some extra processing.
You can use Character.isUpperCase() to check for upper case.
You can try this code for convert ASCII values to Char
class Ascii {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
char ch=sc.next().charAt(0);
if(ch==' ') {
int in=ch;
System.out.println(in);
}
}
}