问题描述:

Using stack data structure(s): If the input file is not balanced, the un-balance cause and the in-file localization details will be supplied. For flexibility reasons, read the balancing pairs of symbols from a text file. Test your program by considering the following pairs of symbols: ( ), { }, [ ], /* */

I'm having trouble with the last requirement: /* */

I also can't seem to grasp how to print the in-file localization details? i.e which line number of the text file the error has occured on?

The text file looks like this:

(()(()

{}}}{}{

[[[]][][]

((}})){{]

()

[]

{}

[]{}

()()()[]

*/ /*

(a+b) = c

The code:

import java.io.BufferedReader;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

public class P1 {

private boolean match = true;

// The stack

private java.util.Stack<Character> matchStack = new java.util.Stack<Character>();

// What to do with a match

public boolean ismatch() {

return match && matchStack.isEmpty();

}

// Finding a match

public void add(char c) {

Character k = leftSide(c);

if (k == null)

;

else if (k.charValue() == c)

matchStack.push(k);

else {

if (matchStack.isEmpty() || !matchStack.pop().equals(k))

match = false;

}

}

// Add string values

public void add(String s) {

for (int i = 0; i < s.length(); i++)

add(s.charAt(i));

}

// The various symbol pairs

protected static Character leftSide(char c) {

switch (c) {

case '(':

case ')':

return new Character('(');

case '[':

case ']':

return new Character('[');

case '{':

case '}':

return new Character('{');

default:

return null;

}

}

// Main method. Welcome message, read the test file, build the array, print

// results.

public static void main(String args[]) {

List<String[]> arrays = new ArrayList<String[]>();

// Welcome message

System.out

.println("Project #1\n"

+ "Welcome! The following program ensures both elements of various paired symbols are present.\n"

+ "Test Data will appear below: \n"

+ "-------------------------------");

// Read the file

try {

BufferedReader in = new BufferedReader(new FileReader(

"testfile.txt"));

String str;

// Keep reading while there is still more data

while ((str = in.readLine()) != null) {

// Line by line read & add to array

String arr[] = str.split(" ");

if (arr.length > 0)

arrays.add(arr);

// Let the user know the match status (i.e. print the results)

P1 mp = new P1();

mp.add(str);

System.out.print(mp.ismatch() ? "\nSuccessful Match:\n"

: "\nThis match is not complete:\n");

System.out.println(str);

}

in.close();

// Catch exceptions

} catch (FileNotFoundException e) {

System.out

.println("We're sorry, we are unable to find that file: \n"

+ e.getMessage());

} catch (IOException e) {

System.out

.println("We're sorry, we are unable to read that file: \n"

+ e.getMessage());

}

}

}

网友答案:

An easy way to implement this would be using a map of stacks such as Map<String, Stack<Location>>, where Location is a class you create that holds two ints (a line number and a character number). That can be your location info. The key (String) to this map would be your left side (opener) part of your pairs. Every time you have an opener you look up the appropriate Stack in the map and push a new Location on it for that opener. Each time you encounter a closer you look up its opener, use the opener to look up the correct Stack in the map and then pop it once. The reason I say use String for your key is because not all your openers can be represented by Character namely your /* opener, so a String will have to do. Since you can't switch on Strings for your leftSide(char) (which will now be leftSide(String)) function you'll either have to use if-else or use a map (Map<String, String>) to create the closer to opener mappings.

When the end of the file is reached the only Location objects remaining in the Stack objects should be unclosed openers.

相关阅读:
Top