Evaluate postfix in Java - java

I'm trying to evaluate a postfix expression.
My code compiles but the final answer is wrong.
I tried looking at other answers but they weren't in Java.
public class PA36Stack
{
public static void main(String[] args)
{
PA31Stack an = new PA31Stack(12);
String g = "234*+";
int x = evaluate(an, g);
System.out.print(x);
}
public static int evaluate(PA31Stack b, String g)
{
int temp = 0;
for (int i = 0; i < g.length(); i++)
{
if (g.charAt(i) != '+' && g.charAt(i) != '-' && g.charAt(i) != '*' && g.charAt(i) != '/')
{
b.push(g.charAt(i));
}
else
{
int a = b.pop();
int c = b.pop();
if (g.charAt(i) == '+')
{
temp = a + c;
b.push(temp);
}
//nextone
if (g.charAt(i) == '-')
{
temp = (c - a);
b.push(temp);
}
//two
if (g.charAt(i) == '*')
{
temp = (c * a);
b.push(temp);
}
//three
if (g.charAt(i) == '/')
{
temp = (c / a);
b.push(temp);
}
}
}
return b.pop();
}
}

This is because you are using the ASCII values of the chars representing the numbers for the calculation.
Basically you need to convert the char representing the number to the int it actual represents, i.e. make of '1' a 1 and of '2' a 2 an so on.
To get around this problem you need to substract the ascii value of the char '0' while pop-ind out of the stack to get the real integer value and adding it on push.
Since you have not posted the code of your stack, I've edited it to use a java.util.Stack<Character> and got the correkt result of 14 for the expression 234*+
public static int evaluate(Stack<Character> b, String g) {
int temp = 0;
for (int i = 0; i < g.length(); i++) {
if (g.charAt(i) != '+' && g.charAt(i) != '-' && g.charAt(i) != '*'
&& g.charAt(i) != '/') {
b.push(g.charAt(i));
} else {
int a = b.pop() - '0';
int c = b.pop() - '0';
if (g.charAt(i) == '+') {
temp = a + c;
b.push((char)(temp + '0'));
}
// nextone
if (g.charAt(i) == '-') {
temp = (c - a);
b.push((char)(temp + '0'));
}
// two
if (g.charAt(i) == '*') {
temp = (c * a);
b.push((char)(temp + '0'));
}
// three
if (g.charAt(i) == '/') {
temp = (c / a);
b.push((char)(temp + '0'));
}
}
}
return b.pop() - '0';
}

Related

Simplify a given algebraic string. Output the simplified string without parentheses

The examples look like this, Input : "a-(b+c)" output "a-b-c", Input : "a-(a+b)" output "b"
I came up with this method, but the result for input: "a-(a+b)" is "a-a-b", which the correct one should be "b", how to improve that?
public String simplify(String str)
{
int len = str.length();
char res[] = new char[len];
int index = 0, i = 0;
Stack<Integer> s = new Stack<Integer> ();
s.push(0);
while (i < len) {
if (str.charAt(i) == '+') {
if (s.peek() == 1)
res[index++] = '-';
// If top is 0, append the same operator
if (s.peek() == 0)
res[index++] = '+';
} else if (str.charAt(i) == '-') {
if (s.peek() == 1)
res[index++] = '+';
else if (s.peek() == 0)
res[index++] = '-';
} else if (str.charAt(i) == '(' && i > 0) {
if (str.charAt(i - 1) == '-') {
// x is opposite to the top of stack
int x = (s.peek() == 1) ? 0 : 1;
s.push(x);
}
else if (str.charAt(i - 1) == '+')
s.push(s.peek());
}
else if (str.charAt(i) == ')')
s.pop();
else
res[index++] = str.charAt(i);
i++;
}
return new String(res);
}

I get java.lang.StringIndexOutOfBoundsException when translating c++ code into java code

I'm trying to solve this problem
https://vjudge.net/problem/UVALive-6805
I found solution but in c++ , Can anybody help me converting it to java code. I'm very newbie to programming
I tried a lot of solutions but non of them work.
Please I need help in this if possible
I don't know for example what is the equivalent for .erase function in c++ in java
Also is is sbstr in c++ provide different result from java ?
#include <iostream>
#include <string>
using namespace std;
int syllable(string word)
{
int L = word.size();
int syllable;
if (L>=7)
{
syllable = 3;
}
else if (L==6)
{
int indicator = 0;
for (int k=0; k<=L-2; k++)
{
string subword = word.substr(k, 2);
if (subword == "ng" || subword == "ny")
{
indicator++;
}
}
if (indicator == 0)
{
syllable = 3;
}
else
{
syllable = 2;
}
}
else if (L == 4 || L == 5)
{
syllable = 2;
}
else if (L == 3)
{
char Char = word[0];
if (Char=='a' || Char=='A' || Char=='e' || Char=='E' || Char=='i' || Char=='I' || Char=='o' || Char=='O' || Char=='u' || Char=='U')
{
syllable = 2;
}
else
{
syllable = 1;
}
}
else
{
syllable = 1;
}
return syllable;
}
int main()
{
string word;
int T;
cin >> T;
for (int i=1; i<=T; i++)
{
int syl[] = {0, -1, -2, -3};
string rhy[] = {"a", "b", "c", "d"};
int verse = 0;
int stop = 0;
while (stop == 0)
{
cin >> word;
int L = word.size();
char end = word[L-1];
if (end == '.')
{
stop = 1;
}
if (word[L-1] == ',' || word[L-1] == '.')
{
word = word.erase(L-1, 1);
L = word.size();
}
if (verse<=3)
{
syl[verse] = syl[verse] + syllable(word);
}
if (end == ',' || end == '.')
{
if (verse<=3)
{
rhy[verse] = word.substr(L-2, 2);
}
verse++;
if (verse<=3)
{
syl[verse] = 0;
}
}
}
int A = 0, B = 0, C = 0, D = 0;
for (int k=0; k<4; k++)
{
if (syl[k] >= 8 && syl[k] <= 12)
{
A = A + 10;
}
}
for (int k=0; k<2; k++)
{
if (rhy[k] == rhy[k+2])
{
B = B + 20;
}
}
for (int k=0; k<2; k++)
{
if (syl[k] == syl[k+2])
{
C = C + 10;
}
}
if (verse > 4)
{
D = (verse - 4) * 10;
}
int E = A + B + C - D;
cout << "Case #" << i << ": " << A << " " << B << " " << C << " " << D << " " << E << endl;
}
}
here is my trying
import java.util.*;
public class First {
public static int syllable(String word) {
int L = word.length();
int syllable;
if (L >= 7) {
syllable = 3;
} else if (L == 6) {
int indicator = 0;
for (int k = 0; k < L - 3; k++) {
String subword = word.substring(k, 2);
if (subword == "ng" || subword == "ny") {
indicator++;
}
}
if (indicator == 0) {
syllable = 3;
} else {
syllable = 2;
}
} else if (L == 4 || L == 5) {
syllable = 2;
} else if (L == 3) {
char Char = word.charAt(0);
if (Char == 'a' || Char == 'A' || Char == 'e' || Char == 'E' || Char == 'i' || Char == 'I' || Char == 'o'
|| Char == 'O' || Char == 'u' || Char == 'U') {
syllable = 2;
} else {
syllable = 1;
}
} else {
syllable = 1;
}
return syllable;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String word;
int T;
T = sc.nextInt();
for (int i = 1; i <= T; i++) {
int syl[] = { 0, -1, -2, -3 };
String rhy[] = { "a", "b", "c", "d" };
int verse = 0;
int stop = 0;
while (stop == 0) {
word = sc.next();
int L = word.length();
char end = word.charAt(L-1);
if (end == '.') {
stop = 1;
}
if (word.charAt(L-1) == ',' || word.charAt(L-1) == '.') {
word.substring(L-1, 1);
L = word.length();
}
if (verse <= 3) {
syl[verse] = syl[verse] + syllable(word);
}
if (end == ',' || end == '.') {
if (verse <= 3) {
rhy[verse] = word.substring(L - 2, 2);
}
verse++;
if (verse <= 3) {
syl[verse] = 0;
}
}
}
int A = 0, B = 0, C = 0, D = 0;
for (int k = 0; k < 4; k++) {
if (syl[k] >= 8 && syl[k] <= 12) {
A = A + 10;
}
}
for (int k = 0; k < 2; k++) {
if (rhy[k] == rhy[k + 2]) {
B = B + 20;
}
}
for (int k = 0; k < 2; k++) {
if (syl[k] == syl[k + 2]) {
C = C + 10;
}
}
if (verse > 4) {
D = (verse - 4) * 10;
}
int E = A + B + C - D;
System.out.println("Case #" + i + ": " + A + " " + B + " " + C + " " + D + " " + E);
}
}
}
The Exception is thrown by your second and your third call of String substring method. Your beginIndex is higher than your endIndex. As you can see in here https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring(int,%20int) beginIndex always has to be lower than the endIndex.
Before answering your question, there are some important points to mention in regards to Strings and Java in general.
Strings are immutable (This also applies to C++). This means that no method called on a String will change it, and that all methods simply return new versions of the original String with the operations done on it
The substring method in java has two forms.
One takes in beginIndex and returns everything from beginIndex to str.length() - 1 (where str represents a String)
The other takes in the beginIndex, and the endIndex, and returns everything from beginIndex to endIndex - 1. The beginIndex should never be larger than endIndex otherwise it throws an IndexOutOfBoundsException
C++'s substring method (string::substr()) takes in the beginning "index" and takes in the number of characters after it to include in the substring. So by doing substr(L-2, 2) you get the last two characters of the string.
Java will never allow you to go out of bounds. That means you need to constantly check whether you are within the bounds of anything you are iterating through.
With all this in mind, I would go and verify that all of the substring() method calls are returning the proper range of characters, and that you are properly reassigning the values returned from substring() to the proper variable.
To mimic C++'s string::erase(), depending on what part of the word you want to erase, you want to get the substring of the part before and the substring of the part after it and add them together.
Ex. Lets say I have a String line = "I do not like the movies"; Since it is impossible for anyone to not like movies, we want to cut out the word not
We do this by doing what I said above
String before = line.substring(0, 5); // This gives us "I do " since it goes up to but not including the 5th index.
String after = line.substring(5 + 3); // This gives us the rest of the string starting after the word "not" because not is 3 characters long and this skips to the 3rd index after index 5 (or index 8)
line = before + after; // This'll add those two Strings together and give you "I do like the movies"
Hope this helps!

Own String parser java which solves mathematical equations wrote down in a string

I've wrote a method/function in Java which returns the result of a given basic equation. This equation will be given as a String and I think I got this method working but don't know why I need this one line of Code because this should work without it. After trying for more than an hour to solve it I gave up and hope you can give me an aswer.
Here the Code:
public static double format(String s) {
char[] c = s.toCharArray();
if(s.contains("(")) {
int openbrackets = 0;
for (int i = 0; i < s.length() - 2; i++) {
if (c[i] == '(') openbrackets++;
else if (c[i] == ')') {
openbrackets--;
if(openbrackets == 0) {
s = s.replace(s.substring(s.indexOf('('), i+1), ""+(format(s.substring(s.indexOf('(')+1, i))));
break;
}
}
}
}
if (s.contains("(")) { // String can still contains brackets
s = "" + format(s);
}
c = s.toCharArray();
for(int i = c.length-1; i >= 0; i--) {
if(c[i] == '+') {
return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
} else if(c[i] == '-') {
return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
}
}
for(int i = s.length()-1; i > 0; i--) {
if(c[i] == '*') {
return format(s.substring(0, i)) * Double.parseDouble(s.substring(i+1, s.length()));
} else if (c[i] == '/') {
return format(s.substring(0, i)) / Double.parseDouble(s.substring(i+1, s.length()));
}
}
return s.equals("") ? 0 : Double.parseDouble(s); // I don't understand why I need to do this line
}
Description:
I don't know why I need this s.equals("") ? : because the String never should be empty however when I run it with this equation ((23)+(23-23-432-35-1-2-4231+2312+12323-(-3))*3/2) for example I get an error without it.
I need the parser to convert config Strings into Numbers for example when it comes to screenresolution. I know I can also use Libraries but I want to try these things by myself.
PS: Dont hate me just because I don't use libraries. I really tried to figure it out and I have fun doing it. I would just like to know why I have to write this little Codeline as I don't figure it out...
Edit: Error was a NumberFormatException as the Parsing got an empty String... Got my error now also the OverflowException which was mentioned in the comments...
EDIT: To everyone who MIGHT use something like this in the future:
Here the Code which actually works:
public static double format(String s) {
s = s.replace(" ", "");
s = s.replace("\t", "");
char[] c = s.toCharArray();
if(s.contains("(")) {
int openbrackets = 0;
for (int i = 0; i < s.length(); i++) {
if (c[i] == '(') openbrackets++;
else if (c[i] == ')') {
openbrackets--;
if(openbrackets == 0) {
s = s.replace(s.substring(s.indexOf('('), i+1), ""+(format(s.substring(s.indexOf('(')+1, i))));
break;
}
}
}
}
if (s.contains("(")) s = "" + format(s);
c = s.toCharArray();
for(int i = c.length-1; i > 0; i--) {
if(c[i] == '+') {
return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
} else if(c[i] == '-') {
return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
}
}
for(int i = s.length()-1; i > 0; i--) {
if(c[i] == '*') {
return format(s.substring(0, i)) * Double.parseDouble(s.substring(i+1, s.length()));
} else if (c[i] == '/') {
return format(s.substring(0, i)) / Double.parseDouble(s.substring(i+1, s.length()));
}
}
return s.equals("") ? 0 : Double.parseDouble(s);
}
I'm fairly sure this is at least one location in your code where you pass a 0 length string to your format function:
c = s.toCharArray();
for(int i = c.length-1; i >= 0; i--) {
if(c[i] == '+') {
return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
} else if(c[i] == '-') {
return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
}
}
Your loop counter in (int i = c.length-1; i >= 0; i--) will get decremented until it is 0 in value if there are no + or - values in the input string.
Then you call format(s.substring(0, i)) where i = 0 so I think this is one place where you will be passing a zero length/empty string to your function.
Please use a debugger and step through your code - not only would it teach you a valuable skill it would also probably give you the answer you're looking for.

Java: find in 2d array all adjacent elements with the same value, starting from a given element

I'm working on a program which contains a 2-dimensional 16x32 char array. What I want to do is, starting from a given element in this array, find all the elements that share the same value (in my case a blank space ' ') and that are horizontally and/or vertically linked to each other.
The method I'm using stores the indexes that it finds inside another array, called toShow (public static int toShow[][] = new int[30][30];). The problem is that this method does not seem to process towards the right side. Strangely enough, it seems to work on the other sides... Here's an example:
X1 123
31 1X
211 24
1X1 112X
111 12X34
111•2X32X
1X113X211
In this case, starting from the element marked as •, the method should store every ' ' character and all the neighbor numbers... but this is the result:
1••
1••
1•
1•
1•
1•
It does however usually work if it starts in the lower left corner, even though it does have to turn right!
I don't understand what's wrong with my code... Anyways here is the odd method:
public static void getEmptySurrounding(int xcoord, int ycoord) {
if (toShow[xcoord][ycoord] == 1) {
return;
}
else {
toShow[xcoord][ycoord] = 1;
}
//DOWN
if((ycoord!=29) && ycoord + 1 < 16) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord, ycoord + 1);
}
}
//RIGHT
if((xcoord!=15) && xcoord + 1 < 30) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord + 1, ycoord);
}
}
//UP
if((ycoord!=0) && ycoord - 1 >= 0) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord, ycoord - 1);
}
}
//LEFT
if((xcoord!=0) && xcoord - 1 >= 0) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord - 1, ycoord);
}
}
}
Thank you!
Based on the information you provided I made an application to test your method:
public class Mine {
private static char board[][] = new char[16][32];
private static int toShow[][] = new int[30][30];
public static void main(String[] args) {
int n = 0;
insert(n++, "X1 123");
insert(n++, "31 1X");
insert(n++, "211 24");
insert(n++, "1X1 112X");
insert(n++, "111 12X34");
insert(n++, "111 2X32X");
insert(n++, "1X113X211");
getEmptySurrounding(3, 5);
for (int i = 0; i < 30; i++) {
for (int j = 0; j < 30; j++) {
System.out.print(toShow[j][i]);
}
System.out.println();
}
}
public static void getEmptySurrounding(int xcoord, int ycoord) {
if (toShow[xcoord][ycoord] == 1) {
return;
}
else {
toShow[xcoord][ycoord] = 1;
}
// DOWN
if ((ycoord != 29) && ((ycoord + 1) < 16)) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord, ycoord + 1);
}
}
// RIGHT
if ((xcoord != 15) && ((xcoord + 1) < 30)) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord + 1, ycoord);
}
}
// UP
if ((ycoord != 0) && ((ycoord - 1) >= 0)) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord, ycoord - 1);
}
}
// LEFT
if ((xcoord != 0) && ((xcoord - 1) >= 0)) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord - 1, ycoord);
}
}
}
public static void insert(int n, String a) {
for (int i = 0; i < 16; i++) {
board[i][n] = a.length() <= i ? ' ' : a.charAt(i);
}
}
}
At the end it prints out the content of toShow, the relevant part is:
011111100000000000000000000000
011111110000000000000000000000
001111110000000000000000000000
001111100000000000000000000000
001110000000000000000000000000
001110000000000000000000000000
000100000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
which suggest that the method works correctly.
So probably the problem lies elsewhere in your program.

Binary to Decimal - java

I want to write a program which receive a string value and print the decimal number.
In addition, if the string value is not 1 or 0, I need to print a message.
I wrote this code but it is always getting inside the if command.
I Would appreciate your support!
Thank you
import java.util.Random;
public class Decimal {
public static void main(String[] args) {
String input = (args[0]);
int sum = 0;
for (int i = 0; i <= input.length(); i++) {
if (!(input.charAt(i) == '0') || (input.charAt(i) == '1')) {
System.out.println("wrong string");
break;
}
char a = input.charAt(i);
if (a == '1') {
sum |= 0x01;
}
sum <<= 1;
sum >>= 1;
System.out.println(sum);
}
}
}
The ! (not) operator of the if statement only applies to the first part:
if ( ! (input.charAt(i) == '0')
||
(input.charAt(i) == '1')
) {
So that is the same as:
if ((input.charAt(i) != '0') || (input.charAt(i) == '1')) {
When you actually meant to do:
if (input.charAt(i) != '0' && input.charAt(i) != '1') {
It's a good thing though, because once that works, you're going to get an IndexOutOfBoundsException when i == input.length(). Change the loop to:
for (int i = 0; i < input.length(); i++) {
And for performance, move variable a up and use it in that first if statement. Rename to c or ch is more descriptive/common.
Doing both sum <<= 1 and sum >>= 1 leaves you where you started. Is that what you wanted? You should also do the left-shift before setting the right-most bit.
Applying all that, I believe you meant to do this:
String input = args[0];
int sum = 0;
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c != '0' && c != '1') {
System.out.println("wrong string");
break;
}
sum <<= 1;
if (c == '1')
sum |= 1;
}
System.out.println(sum);

Categories