For the purposes of this assignment, a map is a two-dimensional array in which each location holds a value of type char. Two locations are considered to be neighbors if one is immediately to the "east", "west", "north", or "south" of the other (i.e., either their row numbers or column numbers differ by one, but not both). A path on a map is a sequence of locations such that consecutive locations in the sequence are neighbors of one another.
A region on a map is a maximal set of locations such that they all contain the same value and such that every pair of locations in the set is connected by a path that includes only locations within the set.
Provided are the following Java artifacts and sample data file:
Enter input file name: map1.txt The map: A A A C C B A A A C C C B B A C A A C C C B A C C B B B B A A C A C B B A A A B A B B C C C C B Region IDs: 1 1 1 2 2 3 4 4 1 2 2 2 3 3 4 5 1 1 2 2 2 3 4 5 6 7 7 7 7 4 4 5 8 9 7 7 4 4 4 10 8 7 7 11 11 11 11 10 |
The program reads the map from the input file, passes that map to the constructor of MapRegionFinder class, and then uses the resulting object's methods to display the original map followed by an "overlay" that shows, for each map location, in which region it lies. Each region is identified by a positive integer; region numbers form a consecutive range of postive integers starting at one and ending with the number of distinct regions.
You will notice a stubbed method, computeRegions(), in the MapRegionFinder class. (It is a private method, and thus you can rename it if you like.) What it should do is to iterate over every location in the map, and, for each location L that has yet to be identified with a region ID, it should "explore" from that location by calling a recursive method. The result of that call should be that every location in the same region as L has been marked as being so. (Which is to say that all the elements of the instance variable regionID[][] corresponding to locations in that region have had the same value placed into them.)
The recursive method just mentioned, for which exploreRegion() is an appropriate name, could work as follows. First, either via parameters passed to it or values of instance variables, it would have to "know" which location it was "exploring from", which char value it was "hoping" to find there, and what region ID to assign to that location, if appropriate.
The base case of the method would apply when the location it was exploring from
In this case, the method should do nothing. Otherwise (the recursive case), it should mark the location by the approprate region ID and then recursively explore from each of its four neighbor locations (to the north, east, south, and west).
Enter input file name: map1.txt The map: A A A C C B A A A C C C B B A C A A C C C B A C C B B B B A A C A C B B A A A B A B B C C C C B Region IDs: 1 1 1 2 2 3 4 4 1 2 2 2 3 3 4 5 1 1 2 2 2 3 4 5 6 7 7 7 7 4 4 5 8 9 7 7 4 4 4 10 8 7 7 11 11 11 11 10 Region IDs (wraparound): 1 1 1 2 2 3 1 1 1 2 2 2 3 3 1 4 1 1 2 2 2 3 1 4 4 5 5 5 5 1 1 4 1 6 5 5 1 1 1 7 1 5 5 2 2 2 2 7 |
You will notice that the first constructor in the MapRegionFinder class has a second parameter, of type boolean. Its purpose is to tell the constructor whether or not the new object should interpret the map that is given to it as having a wraparound nature. In a wraparound map, corresponding locations in the "topmost" and "bottommost" rows are considered to be neighbors, and likewise corresponding elements in the "leftmost" and "rightmost" columns. Under this interpretation, every location on a map has exactly four neighbors. Of course, when a map is interpreted in a wraparound fashion, it is likely to have fewer distinct regions than one interpreted in the "normal" way.
To test this feature, you should "uncomment" the last section of code in the main() method of the MapRegionFinderApp. With these statments not commented out, the program would produce as output (when given the map1.txt file as input) that shown to the right.
Notice that, when the map is interprted in the wraparound mode, what had been regions 1, 4, and 8 become a single region, as do regions 2 and 11, as do regions 5 and 6, which explains why there were eleven regions when interpreting the map in the normal way but only seven when interpreting it in the wraparound fashion.