I've been trying to do this simple program where I need to check which digit of an integer number is the biggest one. So my initial thought was that I shall convert it all into an array and go with the for loop to check which element of an array is biggest. In order to do this I converted integer into String and then characters of the String into elements of an array. I ran into problem and I looked online for solution. What I don't understand is why do I need the " temp.charAt(i) - '0'" part in order to store characters of String as elements of the array. Why can't it be only arrTemp[i] = temp.charAt(i), without the "- '0'" part.
String temp = Integer.toString(n);
int arrTemp[] = new int[temp.length()];
int max = arrTemp[0];
for(int i = 0; i<temp.length(); i++) {
arrTemp[i] = temp.charAt(i) - '0';
'0' is the character '0', not the integer 0. Characters are represented using int values (ascii code).
The ascii code for '0' is the integer value 48.
int n = (int) '0'; //n would be 48.
So, to convert '0' to the integer 0, you need to subtract '0'-'0' = 48-48 = 0
To convert '9' to int 9:
'9' - '0' = 57-48 = 9
See ASCII code https://en.wikipedia.org/wiki/ASCII
In many programming languages(Java, C etc.), a character variable does not contain a character value itself rather the ascii value of the character variable. The ascii value represents the character variable in numbers, and each character variable is assigned with some number range from 0 to 127(in decimal number system). For example, the ascii value of 'A' is 65 and '0' is 48.
You can convert any digit character to integer by subtracting '0' from that character. This subtraction between characters is possible because of ascii values.
Imagine you want to convert digit character '9' to an integer 9. ASCII value of character '9' is 57 and ASCII value of character '0' is 48. Now, if you perform a subtraction operation of characters, '9' - '0', it will be treated like 57 - 48 and thus will give you a result of 9. This subtraction operation of characters converted a character '9' to an Integer 9.
Try this code example:
class Converter {
public static void main(String[] args) {
System.out.println('9'-'0');
}
}
You can see all of the characters points to an ascii value,
Related
I am new to java and and working on a crud calculator that takes input and holds it in an ArrayList to perform the calculations.
I am trying to add two values in an ArrayList<Character> and then replace the "+" with the sum.
if(listEqu.contains('+')) {
while(listEqu.indexOf('+') > -1) {
int plus = listEqu.indexOf('+');
int prev = listEqu.get(plus-1);
int nxt = listEqu.get(plus+1);
Character sum = (char) (nxt + prev);
listEqu.set(plus, sum);
System.out.println(listEqu);
}
}
When the input is 1+1, this returns [1, b, 1].
What I want is to return [1, 2, 1] .
Any advice? Thanks!
The problem is actually that adding two characters doesn't do what you expect.
The value of '1' + '1' is 'b'. If you want the next digit after '1' you add the integer 1 to it; i.e. '1' + 1 is '2'.
For a deeper understanding, you need to understand how character data is represented in Java.
Each char value in Java is an unsigned 16 bit integer that corresponds to a code point (or character code) in the Unicode basic plane. The first 128 of these code points (0 to 127) correspond to a characters in the old ASCII character set. In ASCII the codes that represent digits are 48 (for '0') through to 39 (for '9'). And the lowercase letters are 97 (for 'a') through to 122 (for 'z').
So as you can see, '1' + '1' -> 49 + 49 -> 98 -> 'b'.
(In fact there is a lot more to it than this. Not all char values represent real characters, and some Unicode code-points require two char values. But this is way beyond the scope of your question.)
How could I specify addition of numbers instead of addition of the characters?
You convert the character (digit) to a number, perform the arithmetic, and convert the result back to a character.
Read the javadoc for the Character class; e.g. the methods Character.digit and Character.forDigit.
Note that this only works while the numbers remain in the range 0 through 9. For a number outside of that range, the character representation consists of two or more characters. For those you should be using String rather than char. (A String also copes with the 1 digit case too ...)
Few things that can be improved with your code :
Converting the characters 1 into equivalent integer value:
int prev = Integer.parseInt(String.valueOf(listEqu.get(plus-1)));
int nxt = Integer.parseInt(String.valueOf(listEqu.get(plus+1)));
// Note : int prev = listEqu.get(plus-1) would store an ascii value of `1` to prev value i.e 49
And then converting the sum of those two values into Character back to be added to the list using Character.forDigit as:
Character sum = Character.forDigit(nxt+prev,10);
// Note Character sum = (char) (nxt + prev); is inconvertible
// and char sum = (char) (nxt + prev); would store character with ascii value 98(49+49) in your case 'b' to sum
you should first convert your prevand nxt to int value and then add them together like follow:
if(listEqu.contains('+')) {
while(listEqu.indexOf('+') > -1) {
int plus = listEqu.indexOf('+');
int prev = Integer.parseInt(listEqu.get(plus-1));
int nxt = Integer.parseInt(listEqu.get(plus+1));
Character sum = (char) (nxt + prev);
listEqu.set(plus, sum);
System.out.println(listEqu);
}
}
nxt and prev are char values. Tey take their value in the ASCII table, where '1' is 61 and 'b' is 142 (thus, '1' + '1' = 'b')
You need to substract '0' to get the number they represent. ('1' - '0' = 61 - 60 = 1)
The sum is not necessarily writable with one character, so you shouldn't put it back into a char array.
If you want to convert an integer to a string, use Integer.toString(i).
(And, if you want to, get the first character of the string and put it in the array, if that's what you want)
You need to parse the characters to their corresponding decimal value before you perform the addition, and then back to a character after. The methods Character.digit(char, int) and Character.forDigit(int, int) can do that (and I would use char since that is the type of prev and nxt). Like,
char prev = listEqu.get(plus - 1);
char nxt = listEqu.get(plus + 1);
Character sum = Character.forDigit(Character.digit(nxt, 10)
+ Character.digit(prev, 10), 10);
I have a question about the following snippet:
while (str.length() > i && str.charAt(i) >= '0' && str.charAt(i) <= '9') {
result = result * 10 + (str.charAt(i) - '0');
i++;
}
Could someone tell me why str.charAt(i) - '0' is considered and what does it do?
Also, why is the result multiplied by 10?
Thanks!
By doing Str.CharAt(i) -'0' you just convert the caracter to the real number value provided that character is in 0 .. 9 range.
The result = result * 10 thing is to "shift" previous result to the left (decimal base), since a new digit has been detected (and added to the result)
This code is probably doing a string to integer conversion, also a bad one since it seems that 12AAA34 would be converted to 1234 since non-digit charts are just skipped. It would be better if parsing stopped as soon as a non-digit char was found, like C atoi does (still accepting/skipping spaces)
First of all this Str.CharAt(i) - '0' is considered because both Str.CharAt(i) and '0' returns Characters which have their ascii values to be integers.
It means that taking the value of the String Str fetch the character at index number i of the String(Str). For example consider this String Emil.
Then "Emil".CharAt(0); will give me E. But E has an ascii value of 69 which is an integer. Also 0 has an ascii value of 48. So "Emil".CharAt(0); - 0 is equivalent to 69 - 48(thus the subtraction of two integer values) and returns and integer of 21.
It(Str.CharAt(i) - 0) is added to the results of results * 10 because Str.CharAt(i) - 0 returns a Character which can also be recognise as an Integer(ascii) in java.
Take a look at this stackoverflow page which also have an ascii to character table to make you understand more.
I want to find an integer representation of a character, then later on find a character representation of an int.
My current solution is this, but it doesn't work:
String s = "A"
Integer b = Character.getNumericValue(s.toCharArray()[0]); // 10
char c = Character.toChars(b)[0]; // (blank)
How should i do this?
There's a misunderstanding in how Character.getNumericValue(char) works.
Returns the int value that the specified Unicode character represents. For example, the character '\u216C' (the roman numeral fifty) will return an int with a value of 50.
The letters A-Z in their uppercase ('\u0041' through '\u005A'), lowercase ('\u0061' through '\u007A'), and full width variant ('\uFF21' through '\uFF3A' and '\uFF41' through '\uFF5A') forms have numeric values from 10 through 35. This is independent of the Unicode specification, which does not assign numeric values to these char values.
from the java docs.
In other words:
The method getNumericValue does not produce the UTF-16 value of the specified character, but attempts to produce a numeric value - in the sense that '0' will produce 0 - from the given value. And 'A' corresponds to 10 in hex.
But 10 is not the UTF16 value corresponding to 'A'.
A correct way of converting a char to it's corresponding UTF16-value would be to use one of the codepoint-methods from Character. Or if you're absolutely positive, all values will be of the BMP, you can use
char c = 'A';
int i = (int) c;
In this case Character.toChars(int) will also work.
int b = s.charAt(0); // 65
char c = (char) b // 'A'
int x=(int)compressedText.charAt(one1+1);
int y=(int)compressedText.charAt(one1+2);
count=x+y;
count1=(char)count;
the craracter value for compressedText.charAt(one1+2) and compressedText.charAt(one1+1) are each equal to 1 but when I try to debug my code it says count is equal to 98.
Casting a char that represents a numeric character to an int doesn't do what you think it does. It takes the Unicode value of the char (which is 49 for '1'). That explains why you get 98 instead of 2.
Because the code values for the characters '0' through '9' are 48 through 57, you can subtract '0' (48) from each char instead, e.g.
int x = compressedText.charAt(one1+1) - '0';
You'll need to undo this conversion if you are converting an int back to a char that is meant to represent the numeric character. Also you'll need to account for multiple characters if count is more than one digit (>= 10).
This method works in C, C++ and Java. I would like to know the science behind it.
The value of a char can be 0-255, where the different characters are mapped to one of these values. The numeric digits are also stored in order '0' through '9', but they're also not typically stored as the first ten char values. That is, the character '0' doesn't have an ASCII value of 0. The char value of 0 is almost always the \0 null character.
Without knowing anything else about ASCII, it's pretty straightforward how subtracting a '0' character from any other numeric character will result in the char value of the original character.
So, it's simple math:
'0' - '0' = 0 // Char value of character 0 minus char value of character 0
// In ASCII, that is equivalent to this:
48 - 48 = 0 // '0' has a value of 48 on ASCII chart
So, similarly, I can do integer math with any of the char numberics...
(('3' - '0') + ('5' - '0') - ('2' - '0')) + '0') = '6'
The difference between 3, 5, or 2 and 0 on the ASCII chart is exactly equal to the face value we typically think of when we see that numeric digit. Subtracting the char '0' from each, adding them together, and then adding a '0' back at the end will give us the char value that represent the char that would be the result of doing that simple math.
The code snippet above emulates 3 + 5 - 2, but in ASCII, it's actually doing this:
((51 - 48) + (53 - 48) - (50 - 48)) + 48) = 54
Because on the ASCII chart:
0 = 48
2 = 50
3 = 51
5 = 53
6 = 54
In C the + and - operators apply integer promotion*1 to their arguments, thus the result of subtracting (or adding) two chars is an int*2.
From the C-Standard:
5.1.2.3 Program execution
[...]
10 EXAMPLE 2 In executing the fragment
char c1, c2;
/* ... */
c1 = c1 + c2;
the ‘‘integer promotions’’ require that the abstract machine promote the value of each variable to int size and then add the two ints [...]
Applying this to the OP's implicitly given use case of
char c = 42;
... = c - `0`;
This would be lead to the above being the same as:
... = (int) c - (int) `0`; /* The second cast is redundant, as per Jens' comment. */
^ ^
+------ int -----+
*1: If the operators arguments have a lower rank than int they are promoted to an int.
*2: char has a lower rank than int.
There's no change going on. '0' is an int in C. It is a fancy way to write 48 (assuming ASCII).
You can convince yourself of this fact by computing the size of '0':
printf ("sizeof '0' is %zu\n", sizeof '0');
printf ("sizeof(char) is %zu\n", sizeof(char));
which in the first line very likely prints 4 (or 2) but probably not 1 like in the second row (again: in C; it's different for C++).
The numeric constant 0, without any qualifications, has type int. The result of the binary subtraction operation on a char and an int also has type int due to the usual type promotion process.