3
\$\begingroup\$

Task:

Task:

Example of output:

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){

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

                        }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(error == false)System.out.println("OK");


        } catch(IOException e) {
            System.err.println("IOException");
            System.exit(1);
        }catch(ArithmeticException  e) {
            System.err.println("ArithmeticException");
            System.exit(1);
        }catch(NumberFormatException  e) {
            System.err.println("NumberFormatException");
            System.exit(1);
        }catch(Exception e){
            System.err.println("Error");
        }
    }

}

public class ParentStack {
    private Node top;

    public void push(char p){
        top = new Node(p, top);
    }
    public char pop(){
        char buf = top.getVal(); 
        top = top.getNext();
        return buf; 
    }
    public boolean empty(){
        return top == null;
    }
}

public class Node {
    private char val;
    private Node next;

    public char getVal() {
        return val;
    }
    public Node getNext() {
        return next;
    }

    public Node(char val, Node next){
        this.val=val;
        this.next=next;
    }
}

Bracets.txt

Warsaw(){
London[xxxx} ( 
Madrid Paris)}
Berlin

I realise that this is awful but it's what i can come up right now that is actually working. I tried other way but my knowledge is not enough to do it. So what can i do better so far?

\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

Implementation

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

}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.