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

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);
}

Related

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.

How to make multiplication and division counted first in my calculator?

Hello guys im trying to make a calculator that is based on user scanner input, The calculator works fine for calculating from left to right but im having difficulties putting priorities in *,/ and ()
for example 3+(5*2)+1 should be 14 instead mine is 17, and then when i tried
5+((2+1)*3)-1 it gives me weird error..
Can anyone help please? and how can i make my code appear more efficient and simpler thank you in advance.
So here is my code :
System.out.print("Input Equation : ");
n = s.next() + s.nextLine();
n = n.replaceAll("\\s+", "");
char[] nans = n.toCharArray();
c = 0;
for (int i = 0; i < n.length(); i++)
if (nans[i] == '+' || nans[i] == '-' || nans[i] == '/' || nans[i] == '*')
c++;
char[] op = new char[c];
int[] num = new int[c + 1];
c = 0;
for (int i = 0; i < n.length(); i++) {
if (nans[i] == '+' || nans[i] == '-' || nans[i] == '/' || nans[i] == '*') {
op[c] = nans[i];
c++;
}
}
c = 0;
for (int i = 0; i < n.length(); i++) {
if (nans[i] == '1' || nans[i] == '2' || nans[i] == '3' || nans[i] == '4' || nans[i] == '5'
|| nans[i] == '6' || nans[i] == '7' || nans[i] == '8' || nans[i] == '9' || nans[i] == '0')
nus = nus + nans[i];
else if (nans[i] == '+' || nans[i] == '-' || nans[i] == '/' || nans[i] == '*') {
num[c] = Integer.parseInt(nus);
nus = "";
c++;
}
if (i == n.length() - 1){
num[c] = Integer.parseInt(nus);
}
}
for (int i = 0; i < c; i++) {
if (op[i] == '+') {
result = result + num[i] + num[i + 1];
num[i + 1] = 0;
}
else if (op[i] == '-') {
result = result + num[i] - num[i + 1];
num[i + 1] = 0;
}
else if (op[i] == '/') {
result = (result + num[i]) / num[i + 1];
num[i + 1] = 0;
}
else if (op[i] == '*') {
result = (result + num[i]) * num[i + 1];
num[i + 1] = 0;
}
}
System.out.print(" = "+ result);
When you read a token (that is an argument for operator or simply a number), make sure that the next operator is not multiplication or division, otherwise, you want to calculate that one. You can achieve this by means of recursion easily.

String to Char || Char to String

Let suppose I have a button
case R.id.button:
which will do the following functionality:
int position;
String keyInStringForm = et2.getText().toString();
int keyInIntegerForm = Integer.parseInt(keyInStringForm);
String text = et1.getText().toString();
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == 'a' || text.charAt(i) == 'A') {
position = 0;
break;
} else if (text.charAt(i) == 'b' || text.charAt(i) == 'B') {
position = 1;
break;
} else if (text.charAt(i) == 'c' || text.charAt(i) == 'C') {
position = 2;
break;
} else if (text.charAt(i) == 'd' || text.charAt(i) == 'D') {
position = 3;
break;
} else if (text.charAt(i) == 'e' || text.charAt(i) == 'E') {
position = 4;
break;
} else if (text.charAt(i) == 'f' || text.charAt(i) == 'F') {
position = 5;
break;
} else if (text.charAt(i) == 'g' || text.charAt(i) == 'G') {
position = 6;
break;
} else if (text.charAt(i) == 'h' || text.charAt(i) == 'H') {
position = 7;
break;
} else if (text.charAt(i) == 'i' || text.charAt(i) == 'I') {
position = 8;
break;
} else if (text.charAt(i) == 'j' || text.charAt(i) == 'J') {
position = 9;
break;
} else if (text.charAt(i) == 'k' || text.charAt(i) == 'K') {
position = 10;
break;
} else if (text.charAt(i) == 'l' || text.charAt(i) == 'L') {
position = 11;
break;
} else if (text.charAt(i) == 'm' || text.charAt(i) == 'M') {
position = 12;
break;
} else if (text.charAt(i) == 'n' || text.charAt(i) == 'N') {
position = 13;
break;
} else if (text.charAt(i) == 'o' || text.charAt(i) == 'O') {
position = 14;
break;
} else if (text.charAt(i) == 'p' || text.charAt(i) == 'P') {
position = 15;
break;
} else if (text.charAt(i) == 'q' || text.charAt(i) == 'Q') {
position = 16;
break;
} else if (text.charAt(i) == 'r' || text.charAt(i) == 'R') {
position = 17;
break;
} else if (text.charAt(i) == 's' || text.charAt(i) == 'S') {
position = 18;
break;
} else if (text.charAt(i) == 't' || text.charAt(i) == 'T') {
position = 19;
break;
} else if (text.charAt(i) == 'u' || text.charAt(i) == 'U') {
position = 20;
break;
} else if (text.charAt(i) == 'v' || text.charAt(i) == 'V') {
position = 21;
break;
} else if (text.charAt(i) == 'w' || text.charAt(i) == 'W') {
position = 22;
break;
} else if (text.charAt(i) == 'x' || text.charAt(i) == 'X') {
position = 23;
break;
} else if (text.charAt(i) == 'y' || text.charAt(i) == 'Y') {
position = 24;
break;
} else if (text.charAt(i) == 'z' || text.charAt(i) == 'Z') {
position = 25;
break;
} else if (text.charAt(i) == ' ') {
position = 26;
break;
}
int initialResult = position + keyInIntegerForm;
int finalResult = initialResult % 26;
char resultantChar = alphabets[finalResult];
where as "alphabets" is a char array for a-z characters.
} // for
Now there will be more that one "resultantChar", I want those "resultantChar" to be combined together to form a string so I can set it onto a textview.
How do I do that
If I understood you correctly, try do something like this:
StringBuffer result = new StringBuffer();
for (int i = 0; i < text.length(); i++) {
...
char resultantChar = alphabets[finalResult];
result.append(resultantChar);
}
System.out.println(result);
Please, simplify your code using that!
char ch = 'Z';
ch = Character.toLowerCase(ch);
int position = Character.getNumericValue(ch) - Character.getNumericValue('a');
Or, for your case:
char ch = Character.toLowerCase(text.charAt(i));
if (ch >= 'a' && ch <= 'z') {
position = Character.getNumericValue(ch) - Character.getNumericValue('a');
} else if (ch == ' ') {
position = 26;
}
Use http://developer.android.com/reference/java/lang/StringBuilder.html stringbuilder you can append char with stringbuilder

Java Check Balanced Parentheses

I need to write a program that checks if the parenthesis are balanced, which I understand how to do and have already implemented. But, there is a second part that I'm having trouble with,
"Give an algorithm that returns the position in the string of the first offending parenthesis if the string is not properly nested and balanced That is, if an excess right parenthesis is found, return its position; if there are too many left parentheses, return the position of the first excess left parenthesis."
We haven't learned about stacks or regex so I can't utilize those. Below is my implementation to check if the nested parentheses are balanced.
public static int checkNest(char[] arr) {
int counter = 0,index = 0;
for(int i=0; i<arr.length; i++) {
if(arr[i] == '(')
counter++;
else if(arr[i] == ')')
counter--;
}
if(counter == 0)
index = -1;
return index;
}
Right now the incorrect index will always be 0, I need to manipulate my code to make the index of the incorrect parentheses correctly display.
In general, case when you have multiple parentheses' types, you have to use Stack. You have only one mistake: you should keep counter and increase it when you find an open parenthesis and decrease when finding a close one. When the counter is negative at any step of iteration - then it's not balanced`.
public static boolean isBalanced(String str) {
Deque<Character> stack = new LinkedList<>();
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch == '(' || ch == '[' || ch == '{')
stack.push(ch);
else {
if (stack.isEmpty())
return false;
char prv = stack.pop();
if (prv == '(' && ch != ')')
return false;
if (prv == '[' && ch != ']')
return false;
if (prv == '{' && ch != '}')
return false;
}
}
return stack.isEmpty();
}
In case you have only one type of parentheses, then you could have only one counter:
public static boolean isBalanced(String str) {
int count = 0;
for (int i = 0; i < str.length() && count >= 0; i++) {
if (str.charAt(i) == '(')
count++;
else if (str.charAt(i) == ')')
count--;
}
return count == 0;
}
For an extra right parenthesis, you can immediately return the current value of i if the counter is zero, but for an extra left parenthesis, you must continue to parse the string until the end, so you must memorise the position of the last left parenthesis with counter==0:
public static int checkNest(char[] arr) {
int counter = 0,index = -1;
for(int i=0; i<arr.length; i++) {
if(arr[i] == '(') {
if (counter == 0) {
index = i;
}
counter++;
} else if(arr[i] == ')') {
if (counter == 0) {
return i;
}
counter--;
}
}
if (counter == 0) {
return -1;
}
return index;
}
public static int checkNest(char[] arr) {
int counter = 0,index = 0;
for(int i=0; i<arr.length; i++) {
// Only one incorrect parentheses.
index = i;
if(arr[i] == '(')
counter++;
else if(arr[i] == ')')
counter--;
}
if(counter == 0)
index = -1;
return index;
}

Evaluate postfix in 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';
}

Categories