debugjavaMinor
Check correctness of brackets in file with stack + error detection
Viewed 0 times
fileerrorstackwithcorrectnessbracketsdetectioncheck
Problem
Task:
My implementation:
```
public class Main {
public static void main(String[] args) {
String fileName = "Brackets.txt";
Path filein = Paths.get(fileName);
ParentStack s = new ParentStack();
if (!Files.exists(filein) ||
!Files.isReadable(filein) ||
Files.isDirectory(filein)) {
System.err.println("Invalid input file !!!");
System.exit(1);
}
try (BufferedReader br = Files.newBufferedReader(filein);){
String line;
char[] arrLineChar = null;
char expected;
int lineNumber = 0;
boolean error = false;
read: while ( (line = br.readLine()) != null) {
int charNumber = 0;
lineNumber++;
arrLineChar = line.toCharArray();
for (char lineChar : arrLineChar) {
charNumber++;
if(lineChar == '(' || lineChar == '{' || lineChar == '['){
s.push(lineChar);
}
if(lineChar == ')'){
if((expected = s.pop()) == lineChar-1){
}else{
System.out.println(line);
for (int j = 0; j < charNumber-1; j++) {
System.out.print(" ");
}
if(expected == '(')expected +=1;
else expected+=2;
System.out.println("^");
System.out.println("ERROR in line " + lineNumber + ". " + lineChar
+ " found, but "+ (expected) + " expected.");
error = true;
break read;
}
}
if(lineChar == '}'){
if((expected = s.pop()) == lineChar-2){
My implementation:
```
public class Main {
public static void main(String[] args) {
String fileName = "Brackets.txt";
Path filein = Paths.get(fileName);
ParentStack s = new ParentStack();
if (!Files.exists(filein) ||
!Files.isReadable(filein) ||
Files.isDirectory(filein)) {
System.err.println("Invalid input file !!!");
System.exit(1);
}
try (BufferedReader br = Files.newBufferedReader(filein);){
String line;
char[] arrLineChar = null;
char expected;
int lineNumber = 0;
boolean error = false;
read: while ( (line = br.readLine()) != null) {
int charNumber = 0;
lineNumber++;
arrLineChar = line.toCharArray();
for (char lineChar : arrLineChar) {
charNumber++;
if(lineChar == '(' || lineChar == '{' || lineChar == '['){
s.push(lineChar);
}
if(lineChar == ')'){
if((expected = s.pop()) == lineChar-1){
}else{
System.out.println(line);
for (int j = 0; j < charNumber-1; j++) {
System.out.print(" ");
}
if(expected == '(')expected +=1;
else expected+=2;
System.out.println("^");
System.out.println("ERROR in line " + lineNumber + ". " + lineChar
+ " found, but "+ (expected) + " expected.");
error = true;
break read;
}
}
if(lineChar == '}'){
if((expected = s.pop()) == lineChar-2){
Solution
Implementation
You don't need to catch anything other than
It's often a good idea to print stack trace when logging an exception, so that you know what line the problem was on.
When checking a boolean,
Your file readability checks at the top are superfluous. Those cases will all result in an
Using labels in java is generally regarded very poorly. I would highly encourage you to avoid using them wherever possible.
Typically, solutions to this problem employ a
You should look into
Deep nesting is hard to read, and should be avoided. You can design your loops and conditionals to end early with
Try to use descriptive names that are not abbreviations. This makes code easier to read and understand without guesswork, especially for non-native speakers.
It's generally a bad idea to do a lot of work in the
If you take all these things into consideration, your class might look more like:
You don't need to catch anything other than
IOException. You're not doing math, you're not formatting numbers, and you should virtually never catch Exception.It's often a good idea to print stack trace when logging an exception, so that you know what line the problem was on.
When checking a boolean,
if (!error) is preferable to if (error == false)Your file readability checks at the top are superfluous. Those cases will all result in an
IOException. The specific type of IOException you get will tell you what went wrong.Using labels in java is generally regarded very poorly. I would highly encourage you to avoid using them wherever possible.
Typically, solutions to this problem employ a
Map, where keys are opening brackets and values are closing brackets. This has several advantages. You can check if a character is an open bracket with map.containsKey(). You can check if a character is a closing bracket with map.containsValue(). You can look up the expected value with map.get(openBracket). This lets you avoid duplicating your logic three times. Duplicate code is usually a mistake, and you should strive to avoid it without good reason.You should look into
String.format(String, Object...). It's a powerful way to inject variables into a string while keeping it easy to read.Deep nesting is hard to read, and should be avoided. You can design your loops and conditionals to end early with
continue and return.Try to use descriptive names that are not abbreviations. This makes code easier to read and understand without guesswork, especially for non-native speakers.
It's generally a bad idea to do a lot of work in the
main() method, because it's procedural, not object-oriented. In this case, you're really only writing one procedure, so it's not awful, but as designed this work is not reusable by other code. It would be preferable to have a method which does the work, and have main call that method.If you take all these things into consideration, your class might look more like:
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public final class Main {
private static final Map BRACKETS = buildBracketMap();
public static void main(final String[] args) {
final String fileName = "Brackets.txt";
final Path filein = Paths.get(fileName);
final ParentStack openBrackets = new ParentStack();
try (final BufferedReader br = Files.newBufferedReader(filein, Charset.forName("UTF-8"))) {
String line;
int lineNumber = 0;
while ((line = br.readLine()) != null) {
lineNumber++;
final char[] characters = line.toCharArray();
for (int i = 0; i buildBracketMap() {
final Map bracketMap = new HashMap<>(3);
bracketMap.put('(', ')');
bracketMap.put('{', '}');
bracketMap.put('[', ']');
return Collections.unmodifiableMap(bracketMap);
}
}Code Snippets
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public final class Main {
private static final Map<Character, Character> BRACKETS = buildBracketMap();
public static void main(final String[] args) {
final String fileName = "Brackets.txt";
final Path filein = Paths.get(fileName);
final ParentStack openBrackets = new ParentStack();
try (final BufferedReader br = Files.newBufferedReader(filein, Charset.forName("UTF-8"))) {
String line;
int lineNumber = 0;
while ((line = br.readLine()) != null) {
lineNumber++;
final char[] characters = line.toCharArray();
for (int i = 0; i < characters.length; i++) {
final char character = characters[i];
if (BRACKETS.containsKey(character)) {
openBrackets.push(character);
continue;
}
if (!BRACKETS.containsValue(character)) {
continue;
}
final char currentOpenBracket = openBrackets.pop();
final char expectedCloseBracket = BRACKETS.get(currentOpenBracket);
if (character == expectedCloseBracket) {
continue;
}
System.out.println(line);
System.out.println(String.format("%" + (i + 1) + "s", "^"));
System.out.println(
String.format("ERROR in line %d. '%c' found, but '%c' expected.",
lineNumber, character, expectedCloseBracket));
return;
}
}
System.out.println("OK");
} catch (final IOException e) {
e.printStackTrace(System.err);
System.exit(1);
}
}
private static final Map<Character, Character> buildBracketMap() {
final Map<Character, Character> bracketMap = new HashMap<>(3);
bracketMap.put('(', ')');
bracketMap.put('{', '}');
bracketMap.put('[', ']');
return Collections.unmodifiableMap(bracketMap);
}
}Context
StackExchange Code Review Q#120164, answer score: 5
Revisions (0)
No revisions yet.