Trying to detect chars in if-statement - java

I'm having a bit of trouble with detecting a CHAR in an if statement.
I have a score integer, which i made in to a String, and from the string, i made a char Array.
My problem is, that when i try to detect what number the char is, it returns the "Error.png".
Please help me :)
code:
scoreString = "" + score;
System.out.println(scoreString + " - " + scoreString.length());
scoreA = scoreString.toCharArray();
for(int counter = 0; counter < scoreString.length(); counter++){
Texture drawT;
if(scoreA[counter] == 0) drawT = i0;
else if(scoreA[counter] == 1) drawT = i1;
else if(scoreA[counter] == 2) drawT = i2;
else if(scoreA[counter] == 3) drawT = i3;
else if(scoreA[counter] == 4) drawT = i4;
else if(scoreA[counter] == 5) drawT = i5;
else if(scoreA[counter] == 6) drawT = i6;
else if(scoreA[counter] == 7) drawT = i7;
else if(scoreA[counter] == 8) drawT = i8;
else if(scoreA[counter] == 9) drawT = i9;
else drawT = error;
MainClass.batch.draw(drawT, 5 + (9 * counter), 95);
}

scoreA[counter] == 1 compares a character to the numerical value of 1, which is not correct. '1' is not the same thing as 1. In fact, '1' is actually equal to 31 in hex. Use something like:
if(scoreA[counter] == '0') drawT = i0;
else if(scoreA[counter] == '1') drawT = i1;
//continue on
I obviously included a short snippet but it should be enough.

You want character literals.
You need to write
if(scoreA[counter] == '1')

Your mistake is thinking that the char representation for numbers are the same as the numbers themselves - they're not. chars represent ASCII characters (strictly speaking unicode but for this purpose we can just assume ASCII), so the code of the character 0 is NOT the number 0. To fix the problem you can just use char literals in your comparisons:
if(scoreA[counter] == '0') drawT = i0;
else if(scoreA[counter] == '1') drawT = i1;
... etc

Always you have to set character literals with in the single coats
i.e.
scoreA[counter] == '0'

Related

get characters from string by index in java

I may just be tired and not thinking properly anymore, but why is "13" only printed once here? (intelliJ tells me that "i == 11 | i == 13" is always true but I don't see how that makes sense)
for (int i = 0; i < 14; i++) {
System.out.println(i);
String line = clientReader.readLine();
int length = line.length();
if (i == 0 || i == 5 || i == 6) {
line = line.substring(7, length - 6);
} else if (i == 1 || i == 2 || i == 3 || i == 4 || i == 8 || i == 9 || i == 10 || i == 12) {
line = line.substring(8, length - 7);
} else if (i == 7) {
line = line.substring(9, length - 8);
} else if (i == 11 || i == 13) {
line = line.substring(10, length - 9);
}
data[i] = line;
System.out.println(i);
}
p.s. The line.substring does not give an error, if I add System.out.println(line) at the end of the last else if it prints the correct thing.
The last else if is always true because your loop control variable runs from 0 until 13 and the only two numbers you haven't checked before the last else if is 11 and 13 therefore if none of the above conditions are true then i will either be 11 or 13 hence why IntelliJ is smart enough to know it's always true and hence control will always be bound inside the last else if block when the above conditions are not met.
If you increase the loop condition to something like i < 15 or above then IntelliJ wouldn't state else if (i == 11 || i == 13) is always true as i could be 14.

expression evaluation using stack in java

My program is working with expression like 12 + 3 * 45.But Its not working expression like 12*4+(7/2). please give correction in my code.I am attaching my code:
import java.util.Stack;
public class EvaluateString
{
public static int evaluate(String expression)
{
char[] tokens = expression.toCharArray();
// Stack for numbers: 'values'
Stack<Integer> values = new Stack<Integer>();
// Stack for Operators: 'ops'
Stack<Character> ops = new Stack<Character>();
for (int i = 0; i < tokens.length; i++)
{
// Current token is a whitespace, skip it
if (tokens[i] == ' ')
continue;
// Current token is a number, push it to stack for numbers
if (tokens[i] >= '0' && tokens[i] <= '9')
{
StringBuffer sbuf = new StringBuffer();
// There may be more than one digits in number
while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9')
sbuf.append(tokens[i++]);
values.push(Integer.parseInt(sbuf.toString()));
}
// Current token is an opening brace, push it to 'ops'
else if (tokens[i] == '(')
ops.push(tokens[i]);
// Closing brace encountered, solve entire brace
else if (tokens[i] == ')')
{
while (ops.peek() != '(')
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
ops.pop();
}
// Current token is an operator.
else if (tokens[i] == '+' || tokens[i] == '-' ||
tokens[i] == '*' || tokens[i] == '/')
{
// While top of 'ops' has same or greater precedence to current
// token, which is an operator. Apply operator on top of 'ops'
// to top two elements in values stack
while (!ops.empty() && hasPrecedence(tokens[i], ops.peek()))
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
// Push current token to 'ops'.
ops.push(tokens[i]);
}
}
// Entire expression has been parsed at this point, apply remaining
// ops to remaining values
while (!ops.empty())
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
// Top of 'values' contains result, return it
return values.pop();
}
// Returns true if 'op2' has higher or same precedence as 'op1',
// otherwise returns false.
public static boolean hasPrecedence(char op1, char op2)
{
if (op2 == '(' || op2 == ')')
return false;
if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-'))
return false;
else
return true;
}
// A utility method to apply an operator 'op' on operands 'a'
// and 'b'. Return the result.
public static int applyOp(char op, int b, int a)
{
switch (op)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
if (b == 0)
throw new
UnsupportedOperationException("Cannot divide by zero");
return a / b;
}
return 0;
}
// Driver method to test above methods
public static void main(String[] args)
{
System.out.println(EvaluateString.evaluate("10 + 2 * 6"));
}
}
Let's take a look at your block which parses digits:
for (int i = 0; i < tokens.length; i++) {
// ...
if (tokens[i] >= '0' && tokens[i] <= '9')
{
StringBuffer sbuf = new StringBuffer();
// There may be more than one digits in number
while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9')
sbuf.append(tokens[i++]);
values.push(Integer.parseInt(sbuf.toString()));
}
// ...
}
Let's assume our tokens are {'1', '+', '2'} and your initial i value is 0. We're entering the if-body (as tokens[0] == 1), declare an sbuf variable and again make exactly the same check for that i (but we're inside the if-block with the same check as your while condition). So, we're going inside while loop, append tokens[0] to sbuf and increase our i. So now i is 1 and points to +, while condition is false, we parse "1" into 1 and add it to values. But now the next iteration of outer for-loop begins and the i value will be 2. So, we totally missed + as we incremented it's value inside while-loop but haven't processed it in any way.
Now let's find an alternative approach:
for (int i = 0; i < tokens.length; i++) {
// ...
if (tokens[i] >= '0' && tokens[i] <= '9') {
StringBuilder sb = new StringBuilder();
sb.append(tokens[i]);
// There may be more than one digits in number
while (i + 1 < tokens.length && tokens[i + 1] >= '0' && tokens[i + 1] <= '9') {
sb.append(tokens[++i]);
}
values.push(Integer.parseInt(sb.toString()));
}
// ...
}
This approach adds the current value right after declaring sb (I changed StringBuffer to StringBuilder as there is no need to use thread-safe StringBuffer implementation). Next we're checking the next value of i without incrementing. If it is also a number we're incrementing i and appending it to sb. Otherwise no changes to i happens and it will still point to the same value (1 in our case). Now your outer for-loop will increment it and you'll correctly process +.
By the way, if you're writing parser it's better not only return values.pop() but also check that values.size() == 1. If the size is not one then the expression either is not correct or has not been parsed correctly.

codingBat xyzMiddle fails in other tests

This is my task:
Given a string, does "xyz" appear in the middle of the string? To define middle, we'll say that the number of chars to the left and right of the "xyz" must differ by at most one.
The problem description and the failures in others use case can be seen by using the code below here
xyzMiddle("AAxyzBB") → true
xyzMiddle("AxyzBB") → true
xyzMiddle("AxyzBBB") → false
My solution is below. Since I can't see what 'other tests' are, please help me spot the problem. My method is to check if 'y' appears in the middle for odd or even a String.
public boolean xyzMiddle(String str) {
if (str.indexOf("xyz") < 0) return false;
int l = str.length();
int m = l / 2;
if (l % 2 != 0) {
if (str.charAt(m) != 'y') return false;
}
else {
if (str.charAt(m) != 'y' && str.charAt(m - 1) != 'y') return false;
}
return true;
}
The problem with your solution is that you are simply returning false in case the string in question has odd length
Which is actually not true, the pass use-cases for this task can be mathematically divided like below:
1)With xyz present in the middle and there is a string of length x + 1 and x to either the left or right of it.
taking length of string xyz as 3 the total length comes out to be:
(x) + 3 + (x + 1) = 2x + 4 --->Always even
so in the case above we just check is xyz is in the middle or not and return accordingly which is already handled in your code.
2) With xyz present in the middle and there are strings of length x to the left or right of it.
Again taking length of string xyz as 3 the total length comes out to be:
(x) + 3 + (x) = 2x + 3 --->Always odd
Hence as per your solution to return true in this case(last line of code) you need to filter out the cases when length is odd but xyz is not in the middle as below:
if (!(str.substring((m - 1), m + 2).equals("xyz")))
return false;
With this included your solutions looks like as below:
public boolean xyzMiddle(String str) {
if (str.indexOf("xyz") < 0) return false;
int l = str.length();
int m = l / 2;
if (l % 2 != 0) {
if (!(str.substring((m - 1), m + 2).equals("xyz")))
return false;
}
else {
if (str.charAt(m) != 'y' && str.charAt(m - 1) != 'y') return false;
}
return true;
}
Now it passes all the tests on codingBat.
if(str.length() <3) return false;
int ind = str.indexOf("xyz", str.length()/2 - 3) ;
String first = str.substring(0, ind);
String second = str.substring(ind+3);
return (first.length() == second.length() || first.length() +1 == second.length() || first.length() == second.length() + 1);

Decoding sentences in Java using arrays

So I am doing some practice problems for an upcoming exam and one of the problems is posing a bit of a challenge to me.
The problem states that our code should take a string that has been encoded and decode it. It must work as follows:
Each letter is decoded using the letter immediately before it in the alphabet ("b" becomes "a", "c" becomes "b" ect.)
"a" becomes "z".
each digit works the same way, 8 becomes 7, 5 becomes 4.
0 becomes 9.
characters neither letters nor digits are unchanged.
THE ONLY JAVA METHOD I CAN USE IS IO
Ex:
NFFU NF BU 23 JO UIF CFMM UPXFS
meet me at 12 in the bell tower
heres my current code, i cannot decide whether to use for loops or not. TBH I am not really sure how to tackle this.
public class prb1 {
public static void main(String[] args) {
char letter[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
int num[]={0,1,2,3,4,5,6,7,8,9};
System.out.println("Enter Message");
String mssg=IO.readString();
for(char i=0; i<letter.length; i++){
System.out.print(letter[i]--);}
for(int j=0; j<num.length; j++){
System.out.print(num[j]--);
}
}
}
The basic is like this. But this doesn't account yet for the a => z conversion.
String cypher ="ABCDEF";
String plain = "";
for (char c : cypher.toCharArray())
plain += (char) (c - 1);
System.out.println(plain);
With the modulo A => Z, it looks like this:
int A = 'A';
plain += (char) (((c - A - 1 + 26) % 26) + A);
The +26 is needed because java says -1 % 26 == -1 instead of 25.
So this just works for A-Z, but you can easily modify it to work for wider ranges.
You can use a loop to iterate through each character of the message and subtract one from its ascii code if its not a space, an a, or an A:
String message = "NFFU NF BU 23 JO UIF CFMM UPXFS";
String result = "";
for (char thisChar : message.toCharArray()) {
if (thisChar == ' ') {
result += " ";
} else if(thisChar == 'a') {
result += 'z';
} else if (thisChar == 'A') {
result += 'Z';
} else
result += (char)(thisChar - 1);
}
}
System.out.println(result);
Alternatively, you could do:
String message = "NFFU NF BU 23 JO UIF CFMM UPXFS";
String result = "";
for (int i = 0; i < message.length(); i ++) {
char thisChar = message.charAt(i);
if (thisChar == ' ') {
result += " ";
} else if(thisChar == 'a') {
result += 'z';
} else if (thisChar == 'A') {
result += 'Z';
} else
result += (char)(thisChar - 1);
}
}
System.out.println(result);
Technically,
else if(thisChar == 'a') {
result += 'z';
} else if (thisChar == 'A') {
result += 'Z';
}
could be shortened to:
else if(thisChar == 'a' || thisChar == 'A') {
result += (char)(thisChar + 25);
}

Base64.encode(bytearray, Base64.DEFAULT) result of this method will add 10 at last item

When i encode my byte array using Base64.encode(bytearray, Base64.DEFAULT) so result of this method will add 10 at last item in the resulting byte array and when i converting this resulting byte array into string than 10 will convert into \n(line feed) at the end
please let me know why the \n will append at the end
below is the code that will convert the string into byte array
int inLength = hexValue.length();
int i, o = 0;
long outByte = 0;
byte[] outBytes = new byte[(inLength / 2)];
for (i = 0; i < inLength; i++) {
char c = hexValue.charAt(i);
int value = -1;
if (c >= '0' && c <= '9')
value = (c - '0');
else if (c >= 'A' && c <= 'F')
value = 10 + (c - 'A');
else if (c >= 'a' && c <= 'f')
value = 10 + (c - 'a');
if (value >= 0) {
if (i % 2 == 1) {
outBytes[o++] = (byte) ((outByte << 4) | value);
outByte = 0;
} else {
outByte = value;
}
} else {
if (o != 0)
break;
}
}
return outBytes;
I can't comment right now so i had to leave a reply.
Is this code written by you? or Someone else?
For Base64 encoding, byte are processed in blocks of 3 bytes at a time. If the length of the array is not a multiple of three then either one or two '0' zero bytes is appended to make full block.
And why are you writing your own logic where there are some API available to do the work for you?
Update: I just run the code again with help of API.
Input String: 51b034267f00000144495444
And
Corresponding Base64 encoded String: NTFiMDM0MjY3ZjAwMDAwMTQ0NDk1NDQ0
Simply put, 3 bytes will result in 4 plain text encoded bytes.

Categories

Resources