The problem states that you need to match up the tokens (like a pair []. Ex: ([)] is incorrect, ([]) is correct, ()(} is incorrect, """" is correct, """ is incorrect. I think the logical error might be in the if statements, in the for-loop. Tokens are identified for this problem as: "(quotes),[,],{,},(,).
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
import java.util.Scanner;
import java.util.Arrays;
import java.util.ArrayList;
public class matchingtokens {
public static void main(String[] args) throws IOException {
Scanner in=new Scanner(new File("File.txt"));
while (in.hasNext()) {
String input= in.nextLine();
System.out.println("" + input);
String[]a = input.trim().split("");
ArrayList<Character>listOfQuotes =new ArrayList<Character>();
ArrayList<Character>parenPart =new ArrayList<Character>();
for (int i = 0; i < input.length();i++) {
if (input.charAt(i) == '['|| input.charAt(i) == ']' || input.charAt(i) == '{' || input.charAt(i) == '}' || input.charAt(i) == '(' || input.charAt(i) == ')') {
parenPart.add(input.charAt(i));
} else if (input.charAt(i) == '\"') {
listOfQuotes.add(input.charAt(i));
} else {
// i++;
}
}
System.out.println("quotes: " + listOfQuotes);
System.out.println("others: " + parenPart);
if (listOfQuotes.size() % 2 == 0) {
if (parenPart.size() % 2 == 0) {
if (parenPart.get(0) == ']' || parenPart.get(0) == '}' || parenPart.get(0) == ')') {
System.out.println("INCORRECT:: CANNOT BEGIN WITH CLOSING");
break;
} else {
for (int i = 0; i < parenPart.size() - 1; i++) {
if (parenPart.get(i) == '}' && parenPart.get(i-1) == '{') {
parenPart.remove(i);
parenPart.remove(i-1);
i = i - 2;
} else if (parenPart.get(i) == ']' && parenPart.get(i-1) == '[') {
parenPart.remove(i);
parenPart.remove(i-1);
i = i - 2;
continue;
} else if (parenPart.get(i) == ')' && parenPart.get(i-1) == '(') {
parenPart.remove(i);
parenPart.remove(i-1);
i = i - 2;
continue;
} else {
if(parenPart.size()== 0) {
System.out.println("CORRECT");
}else {
System.out.println("INCORRECT:: TOKENS DON'T MATCH UP");
}
}
}
} }else {
System.out.println("INCORRECT:: BRACKETS DON'T MATCH");
break;
}
} else {
System.out.println("INCORRECT:: \" DOES NOT MATCH \"");
break;
}
}
}
}
I'm not sure I understood what you mean but try
for (int i = 0; i < parenPart.size(); i++) {
//parenPart.size() not parenPart.size()-1
if (parenPart.get(i) == '}' && parenPart.get(i-1) == '{') {
parenPart.remove(i);
parenPart.remove(i-1);
i = i - 2;
} else if (parenPart.get(i) == ']' && parenPart.get(i-1) == '[') {
parenPart.remove(i);
parenPart.remove(i-1);
i = i - 2;
continue;
} else if (parenPart.get(i) == ')' && parenPart.get(i-1) == '(') {
parenPart.remove(i);
parenPart.remove(i-1);
i = i - 2;
continue;
} else {
}
}
//out of the for loop
if(parenPart.size()== 0) {
System.out.println("CORRECT");
}else {
System.out.println("INCORRECT:: TOKENS DON'T MATCH UP");
}
Related
So basically before people start questioning why I'm not using a stack to save time over using counters and stuff.
This is a homework problem working with space complexity, so ignoring time complexity, we are attempting to reduce space complexity.
To do so, I have to use counters to keep track of the brackets.
Possible bracket types: '(' ')' '[' ']'
I've tried some coding but I seem to be having a problem with one of the test strings, and I just can't pinpoint where the problem is happening.
Boolean isWF(String w) {
// maxLevel is found and any variables I'm using has been initialized
for(int i = 0; i < maxLevel; i++) {
x = w.charAt(i);
currentLevel = i;
if(x == '(' || x == '[') {
holder = x; // Store bracket here to check match
savedLevel++;
counter++;
currentLevel++;
for(int j = i+1; j < w.length(); j++) {
x = w.charAt(j);
if(x == '(' || x == '[') {
currentLevel++;
if(currentLevel == savedLevel) {
holder = x;
counter++;
}
}
else if(x == ')' || x == ']') {
if(currentLevel == savedLevel) {
if((holder == '(' && x == ')') || (holder == '[' && x == ']')) {
currentLevel--;
counter--;
}
else
return false;
}
else {
currentLevel--;
}
}
}
}
else if(x == ')' || x == ']') {
counter--;
if(counter < 0) {
return false;
}
}
}
if(counter != 0) {
return false;
}
return true;
}
}
The strings I'm testing:
()[] - expected to be true, actual is true
([)] - expected to be false, actual is false
[([([()])])] - expected to be true, actual is true
([()([])()][()(())]()) - expected to be true, actual is false
([()([])())[()(())]()) - expected to be false, actual is false
Not a direct answer to where is the bug in your approach but the following approach seems to solve your input cases and is much simpler.
Basically you go over the string checking if the next symbol is one you can accept e.g. you can't accept a ) right after a [ and you keep a count of the open/close of brackets. If they ever go negative it means you are missing something.
public static boolean isBalanced(String s) {
int sOpen = 0;
int rOpen = 0;
for(int i = 0; i < s.length() - 1; ++i) {
final char current = s.charAt(i);
final char next = s.charAt(i + 1);
if(!isValidSymbol(current, next)) {
return false;
}
if(current == '(') rOpen++;
else if(current == '[') sOpen++;
else if(current == ')') rOpen--;
else if(current == ']') sOpen--;
if(rOpen < 0 || sOpen < 0) return false;
}
final char lastChar = s.charAt(s.length() - 1);
if(lastChar == '(') rOpen++;
else if(lastChar == '[') sOpen++;
else if(lastChar == ')') rOpen--;
else if(lastChar == ']') sOpen--;
return s.length() > 1 && rOpen == 0 && sOpen == 0;
}
private static boolean isValidSymbol(char from, char to) {
if(from == '(') {
return to == ')' || to == '[' || to == '(' ;
}
else if(from == '[') {
return to == ']' || to == '(' || to == '[';
}
return true;
}
public static void main(String[] args) {
String testInput = "()[]";
assert isBalanced(testInput) : "expected true";
testInput = "([)]";
assert isBalanced(testInput) == false : "expected false";
testInput = "[([([()])])]";
assert isBalanced(testInput) : "expected true";
testInput = "([()([])()][()(())]())";
assert isBalanced(testInput) : "expected true";
testInput = "([()([])())[()(())]()) ";
assert isBalanced(testInput) == false : "expected false";
}
I can run this code just printing to the console and everything prints fine, and then when I change all the System.out.println's to outputStream.write
("some string") nothing writes to the output file at all. It is just blank. The first file is the main file. Then my other classes are MyStack and PostfixError. I'll include them below this one. The code takes in input from an input file entered in the command line and then outputs it to a file also specified by the command line. The input file is supposed to be in Postfix format such as ABC+- or AB+C. If it is not in that format it will produce an error. If the input is in that format the code will take that input and write the instructions that would be needed to evaluate the postfix expression if we were using a computer with only one register.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileWriter;
public class PostfixEvaluation{
public static void main(String[] args) throws PostfixError, IOException{
FileReader inputStream = null;
FileReader inputStream2 = null;
FileWriter outputStream = null;
BufferedReader str = null;
int c, j=1,letter;
int stringSize = 100;
String message, letterA, letterB;
try {
inputStream = new FileReader(args[0]); // input file
inputStream2 = new FileReader(args[0]);
outputStream = new FileWriter(args[1]); // output file
str = new BufferedReader(inputStream);
String nextLine; //= str.readLine();
while ((nextLine = str.readLine()) != null) {
outputStream.write("");
outputStream.write("Current expression being evaluated is " + nextLine);
MyStack letterStack = new MyStack(stringSize);
try {
while ((c = inputStream2.read()) != 10){
//letterStack = EvaluateInstructions(c, letterStack,j);
letter = c;
if (letter == 65){ // use an or to account for lower case letters
letterStack.push("A");
}else if (letter == 66) {
letterStack.push("B");
}else if (letter == 67) {
letterStack.push("C");
}else if (letter == 68) {
letterStack.push("D");
}else if (letter == 69) {
letterStack.push("E");
}else if (letter == 70) {
letterStack.push("F");
}else if (letter == 71) {
letterStack.push("G");
}else if (letter == 72) {
letterStack.push("H");
}else if (letter == 73) {
letterStack.push("I");
}else if (letter == 74) {
letterStack.push("J");
}else if (letter == 75) {
letterStack.push("K");
}else if (letter == 76) {
letterStack.push("L");
}else if (letter == 77) {
letterStack.push("M");
}else if (letter == 78) {
letterStack.push("N");
}else if (letter == 79) {
letterStack.push("O");
}else if (letter == 80) {
letterStack.push("P");
}else if (letter == 81) {
letterStack.push("Q");
}else if (letter == 82) {
letterStack.push("R");
}else if ( letter == 83) {
letterStack.push("S");
}else if (letter == 84) {
letterStack.push("T");
}else if (letter == 85) {
letterStack.push("U");
}else if (letter == 86) {
letterStack.push("V");
}else if (letter == 87) {
letterStack.push("W");
}else if (letter == 88){
letterStack.push("X");
}else if (letter == 89) {
letterStack.push("Y");
}else if (letter == 90) {
letterStack.push("Z");
}else if (letter == 42){ //letter == '*'
if (letterStack.isEmpty()|letterStack.length() <= 1) {
j=1;
throw new PostfixError("There are more operators than operands; This is not a valid expression.");
}else {
letterA = letterStack.pop();
letterB = letterStack.pop();
outputStream.write("LD " + letterB);
outputStream.write("ML " + letterA);
outputStream.write("ST TEMP"+j);
letterStack.push("TEMP"+j);
//throw new PrintToOutput("hello");
//j++;
}
}else if (letter == 47) { //letter == '/'
if (letterStack.isEmpty()|letterStack.length() <= 1) {
j=1;
throw new PostfixError("There are more operators than operands; This is not a valid expression.");
}else {
letterA = letterStack.pop();
letterB = letterStack.pop();
outputStream.write("LD " + letterB);
outputStream.write("DV " + letterA);
outputStream.write("ST TEMP"+j);
letterStack.push("TEMP"+j);
//j++;
}
}else if (letter == 43) { //letter == '+'
if (letterStack.isEmpty()|letterStack.length() <= 1) {
j=1;
throw new PostfixError("There are more operators than operands; This is not a valid expression.");
}else {
letterA = letterStack.pop();
letterB = letterStack.pop();
outputStream.write("LD " + letterB);
outputStream.write("AD " + letterA);
outputStream.write("ST TEMP"+j);
letterStack.push("TEMP"+j);
//j++;
}
}else if (letter == 45) { //letter == '-'
if (letterStack.isEmpty()|letterStack.length() <= 1) {
j=1;
throw new PostfixError("There are more operators than operands. This is not a valid expression.");
}else {
letterA = letterStack.pop();
letterB = letterStack.pop();
outputStream.write("LD " + letterB);
outputStream.write("SB " + letterA);
outputStream.write("ST TEMP"+j);
letterStack.push("TEMP"+j);
//j++;
}
}else if (letter == 13) {
//do nothing
}else if (letter == -1) {
outputStream.write("");
outputStream.write("Success! File is finished being read.");
System.exit(0);
}else {
j=1;
//need to empty stack
throw new PostfixError( "This input has an incorrect character or combination of characters.");
}
if (c == 47 | c == 42 | c == 45 |c == 43) {
j++;
}else if (c == 13) {
j=1;
}
}
}catch (PostfixError e) {
outputStream.write(e.getMessage());
//read input stream until it equals 10
do {
c=inputStream2.read();
}while (c !=10);
}
}
} finally {
if (inputStream != null) inputStream.close();
if (inputStream2 !=null) inputStream2.close();
if (outputStream != null) outputStream.close();
str.close();
}
}
}
MyStack Class
public class MyStack {
private String[] theStack;
private int size;
private int top;
private int totalLength;
public MyStack() {
size = 100;
theStack = new String[size];
top = -1;
}
public MyStack(int stringSize) {
size = 100;
theStack = new String[stringSize];
top = 0;
}
public void push(String symbol) {
theStack[top] = symbol;
top++;
}
public String pop() {
return theStack[--top];
}
public boolean isEmpty() {
if (top == -1) {
return true;
}else {
return false;
}
}
public int length() {
return totalLength = top;
}
public void print() {
for(int i=0;i<=top;i++){
System.out.print(theStack[i]+ " ");
}
System.out.println();
}
}
PostfixError Class
public class PostfixError extends Exception{
public PostfixError(String message) {
super(message);
}
}
You call System.exit; this immediately exits; your 'finally' block is NOT run. As a consequence, your BufferedWriter is just abandoned; neither flush() nor close() is invoked on it which means it won't flush its buffer into the file.
SOLUTION: Don't call System.exit there.
import java.util.Stack;
import java.util.Scanner;
public class CheckValidLocationofParenthensies {
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter five data");
String input1 = scanner.next();
balancedParenthensies(input1);
}
public static boolean balancedParenthensies(String s) {
Stack<Character> stack = new Stack<Character>();
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if(c == '[' || c == '(' || c == '{' ) {
stack.push(c);
if(c == '[') {
newvalueforforward(s,']', i);
}
if(c == '{') {
newvalueforforward(s,'}', i);
}
if(c == '(') {
newvalueforforward(s,')', i);
}
} else if(c == ']') {
if(stack.isEmpty() || stack.pop() != '[') {
newvalue(s,'[', i);
return false;
}
} else if(c == ')') {
if(stack.isEmpty() || stack.pop() != '(') {
newvalue(s,'(', i);
return false;
}
} else if(c == '}') {
if(stack.isEmpty() || stack.pop() != '{') {
newvalue(s,'{', i);
return false;
}
}
}
return stack.isEmpty();
}
public static void newvalueforforward(String userval,char value,int decremntval) {
for(int i = 0; i < userval.length(); i++){
StringBuilder newvalue = new StringBuilder(userval);
int location=i;
newvalue.insert(i, value);
boolean valid= checkingnewvalueisValidorNot(newvalue, location);
location=i+1;
if(valid) {
System.out.println(newvalue+" "+""+location);
}
}
}
public static void newvalue(String userval,char value,int decremntval) {
for(int i = decremntval; i >= 0; i--){
StringBuilder newvalue = new StringBuilder(userval);
int location=decremntval - i;
newvalue.insert(decremntval - i, value);
boolean valid= checkingnewvalueisValidorNot(newvalue, location);
if(valid) {
System.out.println(newvalue+" "+""+location);
}
}
}
public static boolean checkingnewvalueisValidorNot(StringBuilder userval,int validpath) {
Stack<Character> stack = new Stack<Character>();
for(int i = 0; i < userval.length(); i++) {
char c = userval.charAt(i);
if(c == '[' || c == '(' || c == '{' ) {
stack.push(c);
} else if(c == ']') {
if(stack.isEmpty() || stack.pop() != '[') {
return false;
}
} else if(c == ')') {
if(stack.isEmpty() || stack.pop() != '(') {
return false;
}
} else if(c == '}') {
if(stack.isEmpty() || stack.pop() != '{') {
return false;
}
}
}
return stack.isEmpty();
}
}
Above is the code i have written to check whether input string contains all balanced brackets if it is not balanced then get missing bracket and place bracket in all index then again check whether string is balanced or not.
I got valid output but problem is between i bracket there should be a intergers
here is input and outputs
input missing outputs
{[(2+3)*6/10} ] {[](2+3)*6/10} 3 not valid(no numbres btn bracket)
{[(2+3)]*6/10} 8 valid
{[(2+3)*]6/10} 9 not valid(after * no number)
{[(2+3)*6]/10} 10 valid
{[(2+3)*6/]10} 11 not valid( / before bracket)
{[(2+3)*6/1]0} 12 not valid( / btn num bracket)
{[(2+3)*6/10]} 13 valid
i am failing to do proper validation to my output.
Before the bracket there may be:
number
closing bracket
After the bracket there may be:
operator
closing bracket
end of expression
(ignoring any whitespace)
This is code for checking balance symbol.
However, when I try to fit in a Tester,
It does not show the anwer correctly.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class BalanceCheck {
private static Scanner in;
public static void main(String[] args){
if(args.length > 0){
System.out.println(args[0]);
try {
in = new Scanner(new File(args[0]));
MyStack<Character> stack = new MyStack<>();
String str;
char ch;
while(in.hasNext()){
str = in.next();
for(int i = 0; i < str.length(); ++i){
ch = str.charAt(i);
if(ch == '(' || ch == '[' || ch == '{' ||
(ch == '/' && i < str.length() - 1 && str.charAt(i+1) == '*')){
stack.push(ch);
}
else if(ch == ')'){
if(stack.isEmpty() || stack.pop() != ch){
System.out.println(") is mismatched");
return;
}
}
else if(ch == ']'){
if(stack.isEmpty() || stack.pop() != ch){
System.out.println("] is mismatched");
return;
}
}
else if(ch == '}'){
if(stack.isEmpty() || stack.pop() != ch){
System.out.println("} is mismatched");
return;
}
}
else if(ch == '*' && i < str.length() - 1 && str.charAt(i+1) == '/'){
if(stack.isEmpty() || stack.pop() != '/'){
System.out.println("*/ is mismatched");
return;
}
}
else if(ch == '"'){
if(stack.isEmpty() || stack.top() == '"'){
if(!stack.isEmpty())
stack.pop();
}
else{
stack.push(ch);
}
}
}
}
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
else{
System.out.println("Command line argument is not provided..");
}
}
}
For instance, if I compile this tester,
/*this tests an unbalanced [ operator*/
public class Test1 {
/* this is the main method */
public static void main(String[ ) args) {
String ghana = "hello";
int test = testing();
}
public int testing() {
/*checking this too */
/* and this */
return 1;
}
}
It should show [ is mismatched. But, it shows /* is mismatched.
Please let me know solution.
And I have to create a Tester file for this code above.
How can I code a tester for this?
Thanks,
Think about what happens with the very first line:
/*this tests an unbalanced [ operator*/
When you hit the '*/', there is a '[' on the top of the stack.
You need to track when you are inside a comment so that you can ignore everything until the end.
Whenever you have an issue like this, you need to use a debugger.
Basically I've got an input string, my test string is '5 + 4' and I want to check character by character to create a list in the form [5,+,4], ie white spaces are ignored. Also, if my test string was '567+5-1' it would output [567,+,5,-,1] by concatenating the numbers together. Unfortunately, it won't let me do .add(inputChar) to my returnValue, saying symbol not found... any ideas?
import java.util.*;
public class CharacterArray {
public List<String> splitToChar(String s) {
List<String> returnValue = new LinkedList<String>();
char[] chars = s.toCharArray();
System.out.println(chars);
int currentNumber;
for (char inputChar : chars) {
if (Character.isDigit(inputChar) == true) {
currentNumber += inputChar;
} else if (inputChar == '.') {
currentNumber += inputChar;
} else if (inputChar == '+') {
returnValue.add(inputChar);
} else if (inputChar == '-') {
returnValue.add(inputChar);
} else if (inputChar == '/') {
returnValue.add(inputChar);
} else if (inputChar == '*') {
returnValue.add(inputChar);
} else if (inputChar == '(') {
returnValue.add(inputChar);
} else if (inputChar == ')') {
returnValue.add(inputChar);
} else {
System.out.println("Incorrect input symbol");
}
}
return returnValue;
}
}
import java.util.*;
public class CharacterArray {
public List<String> splitToChar(String s) {
List<String> returnValue = new LinkedList<String>();
char[] chars = s.toCharArray();
System.out.println(chars);
String currentNumber = "";
for (char inputChar : chars) {
if (Character.isDigit(inputChar) == true) {
currentNumber += inputChar;
} else if (inputChar == '.' ||
inputChar == '+' ||
inputChar == '-' ||
inputChar == '/' ||
inputChar == '*' ||
inputChar == '(' ||
inputChar == ')') {
if (currentNumber.length() > 0){
returnValue.add(currentNumber);
}
currentNumber = "";
returnValue.add(""+inputChar);
} else {
System.out.println("Incorrect input symbol");
}
}
if (currentNumber.length() > 0){
returnValue.add(currentNumber);
}
return returnValue;
}
}
By the way, your currentNumber should be a String
how about .add(String.valueOf(inputChar)) ?
You can't add a char to a List<String> perhaps what you are trying to do is like
String currentNumber = "";
for (char inputChar : chars) {
if (Character.isDigit(inputChar) || inputChar == '.') {
currentNumber += inputChar;
} else if ("+-/*()".indexOf(inputChar) >= 0) {
if (currentNumber.length() > 0) returnValue.add(currentNumber);
currentNumber = "";
returnValue.add("" + inputChar);
} else if (inputChar != ' ') {
System.out.println("Incorrect input symbol '"+inputChar+"'");
}
}
if (currentNumber.length() > 0) returnValue.add(currentNumber);
Your returnValue is a List<String> but you are trying to add a char to the list. You can fix this by converting inputChar to a String when adding it to the list by using String.valueOf(inputChar).