I'm attempting to write an infix to postfix calculator. I am reading from a file that contains:
(4>3)+(3=4)+2
When i run my code, i should be getting a string containing the postfix notation of the input,
however i get absolutely nothing. my code doesnt seem to be reaching the final print statement. also when i modidy the code to get it to at least print(although the notation is incorrect) it only prints the numbers and not the operators ( +, -, &, etc). I cannot figure out why this is happening! i labeled in the code below where the print statement is:
public static void main(String[] args) {
readMathFile();
}
static String PF = "";
public static void postfix(char c, myStack s, myQueue q) {
if (c == '0' || c == '1' || c == '2' || c == '3' || c == '4' ||
c == '5' || c == '6' || c == '7' || c == '8' || c == '9') {
String cc = Character.toString(c);
PF.concat(cc);
} else if(c == '!' || c == '*' || c == '/' || c == '+' || c == '-' ||
c == '<' || c == '>' || c == '=' || c == '&' || c == '|') {
if(s.isEmpty())
s.push(c);
else {
char top = s.peek();
while ((precedence(top) > precedence(c)) && !s.isEmpty()) {
String cd = Character.toString(s.pop());
PF.concat(cd);
}
s.push(c);
}
}
}
public static myStack s;
public static myQueue q;
public static int i = 1;
// the file reading code was borrowed from:
// http://www.java2s.com/Code/Java/File-Input-Output/Readfilecharacterbycharacter.htm
public static void readMathFile() {
s = new myStack();
q = new myQueue();
File file = new File("test.txt");
if (!file.exists()) {
System.out.println(file + " does not exist.");
return;
}
if (!(file.isFile() && file.canRead())) {
System.out.println(file.getName() + " cannot be read from.");
return;
}
try {
FileInputStream fis = new FileInputStream(file);
char current;
// in this while loop is where all of the reading happens
while (fis.available() > 0) {
current = (char) fis.read();
//readMath(current, s, q);
postfix(current, s, q);
}
if(fis.available() == 0) {
char x = s.pop();
while(!s.isEmpty()) {
//q.enqueue(s.pop());
String ce = Character.toString(s.pop());
PF.concat(ce);
}
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("\n\n"+PF); // <----CODE NEVER REACHES THIS POINT! (and when i modify so it does, it will not print the operators!)
}
Related
I'm in an entry java class, and for one of my programs I am expected to create a ubbi dubbi translator, which ads a ub before every vowel and vowel cluster. I cannot figure out how to get my program to run correctly, and also am unsure how to make it exclude the extra vowel included with the cluster. I am not allowed to use Stringbuilder..
public void buttonPressed()
{
String lowerCase = "";
String userInput = input.getText();
Scanner words = new Scanner( userInput );
String ubbiDubbi = "";
//Splits up user input by line
while (words.hasNext()) {
//Converting to lower case.
lowerCase = words.next().toLowerCase();
System.out.println(lowerCase);
}
for (int i = 0; i < lowerCase.length(); i++) {
if (lowerCase.charAt(i+1) == 'a'){
ubbiDubbi = ubbiDubbi + lowerCase.charAt(i+1);
}
else if (lowerCase.charAt(i+1) == 'e') {
ubbiDubbi = ubbiDubbi + lowerCase.charAt(i+1);
}
else if (lowerCase.charAt(i+1) == 'i'){
ubbiDubbi = ubbiDubbi + lowerCase.charAt(i+1);
}
else if (lowerCase.charAt(i+1) == 'o'){
ubbiDubbi = ubbiDubbi + lowerCase.charAt(i+1);
}
else if (lowerCase.charAt(i+1) == 'u') {
ubbiDubbi = ubbiDubbi + lowerCase.charAt(i+1);
}
else {
ubbiDubbi += lowerCase.charAt(i);
}
To get this translator to work you basically just need to step through each character in the input and write it to the output. In addition if the input is a vowel you need to write "ub" out first, except where the previous character was also a vowel.
One thing which is going to be handy is to be able to identify vowels. Starting by writing a function for this is a good idea. It could look like:
private boolean isVowel(char c) {
return
c == 'a' || c == 'A' ||
c == 'e' || c == 'E' ||
c == 'i' || c == 'I' ||
c == 'o' || c == 'O' ||
c == 'u' || c == 'U';
}
Now that's in place if you look at the translation, we want to step over every character in the input and write it to the output. This could look like this:
private String translate(String raw) {
String translated = "";
for(char c:raw.toCharArray()) {
// some extra stuff needed here
translated += c;
}
return translated;
}
For the extra stuff you need to know if the current character is a vowel and whether the previous character was a vowel so we can add a little to do this:
private String translate(String raw) {
String translated = "";
boolean wasLastCharacterVowel = false; //
for(char c:raw.toCharArray()) {
if(isVowel(c)) {
wasLastCharacterVowel = true;
} else {
wasLastCharacterVowel = false;
}
translated += c;
}
return translated;
}
And finally to ad "ub" where required you can check if the character is a vowel and whether the last character was a vowel:
private String translate(String raw) {
String translated = "";
boolean wasLastCharacterVowel = false;
for(char c:raw.toCharArray()) {
if(isVowel(c)) {
if(!wasLastCharacterVowel) {
translated += "ub";
}
wasLastCharacterVowel = true;
} else {
wasLastCharacterVowel = false;
}
translated += c;
}
return translated;
}
With that in place you just need to hook up the button press action etc. So it might look a little like this:
public class UbbiDubbi {
private boolean isVowel(char c) {
return
c == 'a' || c == 'A' ||
c == 'e' || c == 'E' ||
c == 'i' || c == 'I' ||
c == 'o' || c == 'O' ||
c == 'u' || c == 'U';
}
private String translate(String raw) {
String translated = "";
boolean wasLastCharacterVowel = false;
for(char c:raw.toCharArray()) {
if(isVowel(c)) {
if(!wasLastCharacterVowel) {
translated += "ub";
}
wasLastCharacterVowel = true;
} else {
wasLastCharacterVowel = false;
}
translated += c;
}
return translated;
}
public void buttonPressed() {
String userInput = "";// = input.getText();
Scanner words = new Scanner( userInput );
while (words.hasNext()) {
String lowerCase = words.next().toLowerCase();
String translated = translate(lowerCase);
System.out.println(translated);
}
words.close();
}
public static void main(String...none) {
System.out.println(new UbbiDubbi().translate("The quick brown fox jumps over the lazy aadvark"));
}
}
adding the main method gives an easy way to test out the translation. Hope this helps.
i'm new to programming. i don't understand why one of the constructers I'm using to check for the validity of the characters of a string argument in the constructer does not work. the constructer should check if the entered string contains only characters G,C,A,T, else it throws an IllegalArgumentException.
I tried using an array of characters to check for the validity of the string by using the toCharArray() method on the entered string. the constructer works for invalid strings, but not for valid strings. but another constructer i used works. please let me know why the first one doesn't.
//this is the first constructer that doesn't work for me
public class Fragment {
private String nucleotideSequence;
public Fragment(String nucleotides) throws IllegalArgumentException {
char[] validityCheck = nucleotides.toCharArray();
int validityCounter = 0;
for (char c : validityCheck) {
if(c != 'G' || c != 'C' || c != 'A' || c != 'T') {
validityCounter++;
}
}
if (validityCounter != 0) {
throw new IllegalArgumentException("Invalid characters present");
}
nucleotideSequence = nucleotides;
}
}
// this is the second constructer that works
public class Fragment {
private String nucleotideSequence;
public Fragment(String nucleotides) throws IllegalArgumentException {
boolean k = false;
for(int i = 0; i < nucleotides.length(); i++){
char lol = nucleotides.charAt(i);
if(lol=='A'||lol=='G'||lol=='C'||lol=='T'){
k = true;
}
else{
k = false;
}
if(k == false){
throw new IllegalArgumentException("Dosent work");
}
nucleotideSequence = nucleotides;
}
}
}
Your problem in the constructor that is not working is with the following 'if' statement:
if(c != 'G' || c != 'C' || c != 'A' || c != 'T')
This statement is always true. So the following:
for (char c : validityCheck) {
if(c != 'G' || c != 'C' || c != 'A' || c != 'T') {
validityCounter++;
}
}
equals:
for (char c : validityCheck) {
validityCounter++;
}
the correct statement would be
if(c != 'G' && c != 'C' && c != 'A' && c != 'T') {
I'm trying to convert a postfix into an infix. I have some code, but I'm not able to fix it. There may be a condition I am missing. Or my structure is not quite right.
Also since I am new to Java I may need some help with "Stack<Character>".
public static String postfixToInfix(String postfix) {
Stack<Character> stack = new Stack();
Stack<Character> backup = new Stack();
StringBuilder infix = new StringBuilder(postfix.length());
infix.append('(');
for (int i = 0; i < postfix.length(); i++) {
if (!isOperator(postfix.charAt(i))) {
stack.push(postfix.charAt(i));
} else {
if (stack.size() == 1 ) { //stack is 1
backup.push(postfix.charAt(i));
}
if (stack.size() == 0 && backup.size()%5 == 0) { //stack is 0
stack.push(backup.pop());
stack.push(backup.pop());
stack.push(backup.pop());
stack.push(backup.pop());
stack.push(backup.pop());
stack.push(postfix.charAt(i));
}
if (stack.size() >= 2) { //stack is > 1
char arg2 = stack.pop();
char arg1 = stack.pop();
backup.push(')');
backup.push(arg2);
backup.push(postfix.charAt(i));
backup.push(arg1);
backup.push('(');
}
}
}
while (!backup.empty()) { //only size 3
stack.push(backup.pop());
}
while (!stack.empty()) { //only size 3
backup.push(stack.pop());
}
while (!backup.isEmpty()) {
infix.append(backup.pop());
}
infix.append(')');
return infix.toString();
}
private static boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '^' || c == '(' || c == ')';
}
public static void main(String[] args) {
String infix1 = "(3-(7*2))";
String postfix1 = "372*-";
String infix2 = "((7+1)*((3-6)*(5-2)))";
String postfix2 = "71+36-52-**";
System.out.println(" postfix1: " + postfix1);
s = postfixToInfix(postfix1);
System.out.println("postfixToInfix(postfix1): " + s);
if (s.equals(infix1)) {
System.out.println(" Korrekt!");
} else {
System.out.println(" Nicht korrekt!");
}
System.out.println();
System.out.println(" postfix2: " + postfix2);
s = postfixToInfix(postfix2);
System.out.println("postfixToInfix(postfix2): " + s);
if (s.equals(infix2)) {
System.out.println(" Korrekt!");
} else {
System.out.println(" Nicht korrekt!");
}
System.out.println();
}
}
Output
postfix1: 372*-
postfixToInfix(postfix1): (3-(7*2))
Korrekt!
postfix2: 71+36-52-**
postfixToInfix(postfix2): ((5(-*2)()**)(3-6)(7+1))
Nicht korrekt!
Process finished with exit code 0
Instead of dealing with the parenthesis and everything as separate entries in the stack, you could use strings to simplify the process:
private static boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '^';
}
public static String postfixToInfix(String postfix) {
Stack<String> s = new Stack<String>();
for (char c : postfix.toCharArray()) {
if (isOperator(c)) {
String temp = s.pop();
s.push('(' + s.pop() + c + temp + ')');
} else {
s.push(String.valueOf(c));
}
}
return s.pop();
}
Write a program for finding duplicate parenthesis in a expression.
For example :
(( a + b ) + (( c + d ))) = a + b + c + d
(( a + b ) * (( c + d ))) = (a + b) * (c + d)
One approach that I am aware of involves the following two steps:
Convert the given infix expression to postfix expression.
Convert back the postfix to infix
I don't want to do this entire process of converting from one representation to another, and then convert it back.
I want to do this using stack(s) but in a single pass. Is it possible ?
Please suggest an algorithm or share the code.
You can use a recursive descent parser. This uses the function call stack implicitly, but not explicitly a Java stack. It can be implemented as follows:
public class Main {
public static void main(String[] args) {
System.out.println(new Parser("(( a + b ) + (( c + d )))").parse());
System.out.println(new Parser("(( a + b ) * (( c + d )))").parse());
}
}
public class Parser {
private final static char EOF = ';';
private String input;
private int currPos;
public Parser(String input) {
this.input = input + EOF; // mark the end
this.currPos = -1;
}
public String parse() throws IllegalArgumentException {
nextToken();
Result result = expression();
if(currToken() != EOF) {
throw new IllegalArgumentException("Found unexpected character '" + currToken() + "' at position " + currPos);
}
return result.getText();
}
// "expression()" handles "term" or "term + term" or "term - term"
private Result expression() throws IllegalArgumentException {
Result leftArg = term();
char operator = currToken();
if (operator != '+' && operator != '-') {
return leftArg; // EXIT
}
nextToken();
Result rightArg = term();
if(operator == '-' && (rightArg.getOp() == '-' || rightArg.getOp() == '+')) {
rightArg = encloseInParentheses(rightArg);
}
return new Result(leftArg.getText() + " " + operator + " " + rightArg.getText(), operator);
}
// "term()" handles "factor" or "factor * factor" or "factor / factor"
private Result term() throws IllegalArgumentException {
Result leftArg = factor();
char operator = currToken();
if (operator != '*' && operator != '/') {
return leftArg; // EXIT
}
nextToken();
Result rightArg = factor();
if(leftArg.getOp() == '+' || leftArg.getOp() == '-') {
leftArg = encloseInParentheses(leftArg);
}
if(rightArg.getOp() == '+' || rightArg.getOp() == '-' || (operator == '/' && (rightArg.getOp() == '/' || rightArg.getOp() == '*'))) {
rightArg = encloseInParentheses(rightArg);
}
return new Result(leftArg.getText() + " " + operator + " " + rightArg.getText(), operator);
}
// "factor()" handles a "paren" or a "variable"
private Result factor() throws IllegalArgumentException {
Result result;
if(currToken() == '(') {
result = paren();
} else if(Character.isLetter(currToken())) {
result = variable();
} else {
throw new IllegalArgumentException("Expected variable or '(', found '" + currToken() + "' at position " + currPos);
}
return result;
}
// "paren()" handles an "expression" enclosed in parentheses
// Called with currToken an opening parenthesis
private Result paren() throws IllegalArgumentException {
nextToken();
Result result = expression();
if(currToken() != ')') {
throw new IllegalArgumentException("Expected ')', found '" + currToken() + "' at position " + currPos);
}
nextToken();
return result;
}
// "variable()" handles a variable
// Called with currToken a variable
private Result variable() throws IllegalArgumentException {
Result result = new Result(Character.toString(currToken()), ' ');
nextToken();
return result;
}
private char currToken() {
return input.charAt(currPos);
}
private void nextToken() {
if(currPos >= input.length() - 1) {
throw new IllegalArgumentException("Unexpected end of input");
}
do {
++currPos;
}
while(currToken() != EOF && currToken() == ' ');
}
private static Result encloseInParentheses(Result result) {
return new Result("(" + result.getText() + ")", result.getOp());
}
private static class Result {
private final String text;
private final char op;
private Result(String text, char op) {
this.text = text;
this.op = op;
}
public String getText() {
return text;
}
public char getOp() {
return op;
}
}
}
If you want to use an explicit stack, you could convert the algorithm from a recursive one to an iterative one, using a stack of something similar to the Result inner class.
In fact, the Java compiler/JVM converts each recursive algorithm to a stack based one putting the local variables onto a stack.
But recursive decent parsers are easily readable by humans, hence I would prefer the solution presented above.
If you only care about duplicate parentheses (as the question seems to imply), rather than those deemed necessary due to operator precedence (as the other answers seem to imply) you can indeed use a stack to keep track of which brackets you have encountered, and decide that any non-whitespace non-bracket characters for each pair of parentheses matters, which gives you a much simpler iterative traversal using a stack:
public class BracketFinder {
public List<BracketPair> findUnnecessaryBrackets(String input) {
List<BracketPair> unneccessaryBrackets = new LinkedList<BracketPair>();
Deque<BracketPair> bracketStack = new LinkedBlockingDeque<BracketPair>();
for (int cursor = 0; cursor < input.length(); cursor++ ) {
if (input.charAt(cursor) == '(') {
BracketPair pair = new BracketPair(cursor);
bracketStack.addLast(pair);
} else if (input.charAt(cursor) == ')') {
BracketPair lastBracketPair = bracketStack.removeLast();
lastBracketPair.end = cursor;
if (!lastBracketPair.isNecessary) {
unneccessaryBrackets.add(lastBracketPair);
}
} else if (input.charAt(cursor) != ' ') {
if (!bracketStack.isEmpty()) {
bracketStack.getLast().isNecessary = true;
}
}
}
return unneccessaryBrackets;
}
class BracketPair {
public int start = -1;
public int end = -1;
public boolean isNecessary = false;
public BracketPair(int startIndex) {
this.start = startIndex;
}
}
}
Which you can test with the following
public static void main(String... args) {
List<BracketPair> results = new BracketFinder().findUnnecessaryBrackets("(( a + b ) + (( c + d ))) = a + b + c + d");
for (BracketPair result : results) {
System.out.println("Unneccessary brackets at indices " + result.start + "," + result.end);
}
}
Did not program it, but it could be look like this:
give the operations + / - the value 1
give the operations * & / the value 2
give the operation )( the value 2 (as its the same like *)
1 go to inner parenthesis and check if the next operation is higher in its value (means the parenthesis is necessary) or equal/lower to the own operation. if equal or lower the parenthesis is not necessary.
2 go to 1
you are finished, when there are no changes between 2 steps
hope this helped..
If you got an solution let me know please.
If this didn't help, let me know too :)
Greetings
Its possible in one pass. The idea is to look for previous / next operation around each () block and apply associativity rules. Here is small table with yes/no marks when () is necessary.
// (a + b) + c NO
// (a + b) - c NO
// (a + b) / c YES
// (a + b) * c YES
// (a / b) + c NO
// (a / b) - c NO
// (a / b) / c NO
// (a / b) * c NO
// a + (b + c) NO
// a - (b + c) YES
// a / (b + c) YES
// a * (b + c) YES
// a + (b / c) NO
// a - (b / c) NO
// a / (b / c) YES
// a * (b / c) NO
// (a) ((a)) NO
Here is C++ code (im not sure if its not missing some cases - its just an idea):
string clear(string expression)
{
std::stack<int> openers;
std::stack<int> closers;
std::stack<bool> isJustClosed;
std::stack<char> prevOperations;
std::stack<bool> isComposite;
std::stack<int> toDelete;
prevOperations.push(' ');
isJustClosed.push(false);
isComposite.push(false);
string result = expression + "#";
for (int i = 0; i < result.length(); i++)
{
char ch = result[i];
if ((ch == '*') || (ch == '/') || (ch == '+') || (ch == '-') || (ch == '(') || (ch == ')') || (ch == '#'))
if (isJustClosed.size() > 0)
if (isJustClosed.top() == true) {
// pop all and decide!
int opener = openers.top(); openers.pop();
int closer = closers.top(); closers.pop();
char prev = prevOperations.top(); prevOperations.pop();
char prevOperationBefore = prevOperations.top();
isJustClosed.pop(); //isJustClosed.push(false);
bool isComp = isComposite.top(); isComposite.pop();
bool ok = true;
if (prev == ' ')
ok = false;
else
{
ok = false;
if (((isComp) || (prev == '+') || (prev == '-')) && (ch == '/')) ok = true;
if (((isComp) || (prev == '+') || (prev == '-')) && (ch == '*')) ok = true;
if (((isComp) || (prev == '+') || (prev == '-')) && (prevOperationBefore == '-')) ok = true;
if (prevOperationBefore == '/') ok = true;
if (((isComp) || (prev == '+') || (prev == '-')) && (prevOperationBefore == '*')) ok = true;
}
if (!ok)
{
toDelete.push(opener);
toDelete.push(closer);
}
}
if (ch == '(') {
openers.push(i);
prevOperations.push(' ');
isJustClosed.push(false);
isComposite.push(false);
}
if (ch == ')') {
closers.push(i);
isJustClosed.top() = true;
}
if ((ch == '*') || (ch == '/') || (ch == '+') || (ch == '-')) {
if (!isComposite.top())
{
char prev = prevOperations.top();
if ((ch == '+') || (ch == '-'))
if ((prev == '*') || (prev == '/'))
isComposite.top() = true;
if ((ch == '*') || (ch == '/'))
if ((prev == '+') || (prev == '-'))
isComposite.top() = true;
}
prevOperations.top() = ch;
isJustClosed.top() = false;
}
}
while (toDelete.size() > 0)
{
int pos = toDelete.top();
toDelete.pop();
result[pos] = ' ';
}
result.erase(result.size() - 1, 1);
return result;
}
Inside each block we track last operation and also track if content is composite like (a+b*c).
Test:
void test()
{
LOG << clear("((a + (a + b))) - ((c)*(c) + d) * (b + d)") << NL;
LOG << clear("a + (a + b) - ((c) + d) * (b + d)") << NL;
LOG << clear("(a/b)*(c/d)") << NL;
LOG << clear("(a/b)*((((c)/d)))") << NL;
LOG << clear("((a + b) - (c - d))") << NL;
LOG << clear("((a + b)*((c - d)))+c/d*((a*b))") << NL;
LOG << clear("a+a*b*(a/b)") << NL;
LOG << clear("a+a*b*(a+b)") << NL;
}
Result:
a + a + b - ( c * c + d) * b + d
a + a + b - ( c + d) * b + d
a/b * c/d
a/b * c /d
a + b - (c - d)
(a + b)* c - d +c/d* a*b
a+a*b* a/b
a+a*b*(a+b)
Personally I think there are at least 2 ways:
using a tree
using arithmetical polish notation
Tree
A tree can be created from the input expression. After the tree is created it can be flattened without the useless parentheses
Binary_expression_tree
parsing-an-arithmetic-expression-and-building-a-tree
Polish notation
(( a + b ) + (( c + d ))) will become (+ (+ a b) (+ c d))
(( a + b ) * (( c + d ))) will become (* (+ a b) (+ c d))
From here you could compare the each operand and the factors to see if they have the same priority in solving the arithmetical equation
I would go with the tree.
i have no idea why i am not getting the expected results! I have written the expected result in the end. Alright, i have two classes: CalculatorEngine and CalculatorInput, the former calculates while the latter gives a line mode interface. The code for CalculatorEngine goes like this, nothing fancy:
public class CalculatorEngine {
int value;
int keep;
int toDo;
void binaryOperation(char op){
keep = value;
value = 0;
toDo = op;
}
void add() {binaryOperation('+');}
void subtract() {binaryOperation('-');}
void multiply() {binaryOperation('*');}
void divide() {binaryOperation('/');}
void compute() {
if (toDo == '+')
value = keep + value;
else if (toDo == '-')
value = keep - value;
else if (toDo == '*')
value = keep * value;
else if (toDo == '/')
value = keep/value;
keep = 0;
}
void clear(){
value = 0;
keep = 0;
}
void digit(int x){
value = value*10 + x;
}
int display(){
return (value);
}
CalculatorEngine() {clear();} //CONSTRUCTOR METHOD!
}
And the code for CalculatorInput goes like this:
import java.io.*;
public class CalculatorInput {
BufferedReader stream;
CalculatorEngine engine;
CalculatorInput(CalculatorEngine e) {
InputStreamReader input = new InputStreamReader(System.in);
stream = new BufferedReader(input);
engine = e;
}
void run() throws Exception {
for (;;) {
System.out.print("[" +engine.display()+ "]");
String m = stream.readLine();
if (m==null) break;
if (m.length() > 0) {
char c = m.charAt(0);
if (c == '+') engine.add();
else if (c == '*') engine.multiply();
else if (c == '/') engine.divide();
else if (c == '-') engine.subtract();
else if (c == '=') engine.compute();
else if (c == '0' && c <= '9') engine.digit(c - '0');
else if (c == 'c' || c == 'C') engine.clear();
}
}
}
public static void main(String arg[]) throws Exception{
CalculatorEngine e = new CalculatorEngine();
CalculatorInput x = new CalculatorInput(e);
x.run();
}
}
I expect the answer to be like this:
[0]1
[1]3
[13]+
[0]1
[1]1
[11]=
[24]
BUT i am getting this:
[0]1
[0]3
[0]+
[0]1
[0]1
[0]+
[0]
Seems like digit function isn't working properly. Help!
Change this:
if (c == '0' && c <= '9')
To this:
if (c >= '0' && c <= '9')
Otherwise, it will only be true when c is '0'.
else if (c == '0' && c <= '9') engine.digit(c - '0');
if c not equals 0 its false..