8
8
import java .lang .StringBuilder ;
9
9
import java .util .ArrayList ;
10
10
import java .util .Iterator ;
11
+ import java .util .HashSet ;
11
12
import java .util .Stack ;
12
13
import edu .princeton .cs .algs4 .StdOut ;
13
14
import edu .princeton .cs .algs4 .Queue ;
14
15
import edu .princeton .cs .algs4 .In ;
15
16
import edu .princeton .cs .algs4 .TrieST ;
16
17
17
- //import java.util.HashMap;
18
18
//import java.util.Arrays;
19
19
20
20
public class BoggleSolver
21
21
{
22
22
private TrieST <String > dictionaryTrie ;
23
+ private String [] mydictionary ;
23
24
24
25
// Initializes the data structure using the given array of strings as the dictionary.
25
26
// (You can assume each word in the dictionary contains only the uppercase letters A through Z.)
26
27
public BoggleSolver (String [] dictionary ) {
27
- trace ("constructing BoggleSolver" );
28
+ mydictionary = new String [dictionary .length ];
29
+ for (int i = 0 ; i < dictionary .length ; i ++)
30
+ mydictionary [i ] = dictionary [i ];
31
+ }
32
+
33
+ private void construct_trie (BoggleBoard board ) {
34
+ StringBuilder sb = new StringBuilder ();
35
+ for (int i = 0 ; i < board .rows (); i ++) {
36
+ for (int j = 0 ; j < board .cols (); j ++) {
37
+ char c = board .getLetter (i , j );
38
+ sb .append (c );
39
+ if (c == 'Q' )
40
+ sb .append ('U' );
41
+ }
42
+ }
43
+ String validChars = sb .toString ();
44
+
28
45
dictionaryTrie = new TrieST <String >();
29
46
30
- for (String w : dictionary )
31
- dictionaryTrie .put (w , w );
47
+ // add only those words that has the chars:
48
+ boolean isAllChars ;
49
+ for (String w : mydictionary ) {
50
+ isAllChars = true ;
51
+ for (int i = 0 ; i < w .length (); i ++) {
52
+ if (validChars .indexOf (w .charAt (i )) == -1 ) {
53
+ isAllChars = false ;
54
+ break ;
55
+ }
56
+ }
57
+ if (isAllChars )
58
+ dictionaryTrie .put (w , w );
59
+ }
32
60
}
33
61
34
62
// Returns the set of all valid words in the given Boggle board, as an Iterable.
35
63
public Iterable <String > getAllValidWords (BoggleBoard board ) {
36
- trace ("gets words for board " + board .rows () + "x" + board .cols ());
37
- ArrayList <String > words = new ArrayList <String >();
64
+ construct_trie (board );
65
+
66
+ trace ("gets words for board " + board .rows () + "x" + board .cols () + " \n " );
67
+ // walk cell by cell
68
+ HashSet <String > words = new HashSet <String >();
38
69
for (int i = 0 ; i < board .rows (); i ++){
39
70
for (int j = 0 ; j < board .cols (); j ++){
40
71
Stack <Point > path = new Stack <Point >();
41
72
Point p = new Point (i , j );
42
73
path .push (p );
43
74
StringBuilder wordBuilder = new StringBuilder ();
44
75
append (wordBuilder , board , p );
45
- walk (board , path , words , wordBuilder );
76
+ walk (board , path , words , wordBuilder , null );
46
77
}
47
78
}
48
- trace ("found " + words .size () + " words" );
79
+ trace ("found " + words .size () + " words\n " );
49
80
return words ;
50
81
}
51
82
@@ -63,8 +94,12 @@ private void remove(StringBuilder sb, BoggleBoard board, Point p) {
63
94
sb .deleteCharAt (sb .length () - 1 ); // 'U' was removed
64
95
}
65
96
66
-
67
- private void walk (BoggleBoard board , Stack <Point > path , ArrayList <String > found , StringBuilder wordBuilder ) {
97
+ private void walk (
98
+ BoggleBoard board ,
99
+ Stack <Point > path ,
100
+ HashSet <String > found ,
101
+ StringBuilder wordBuilder ,
102
+ Iterable <String > keys ) {
68
103
Point v = path .peek ();
69
104
for (Point p : getAdj (board , v )) {
70
105
if (path .contains (p ))
@@ -74,21 +109,26 @@ private void walk(BoggleBoard board, Stack<Point> path, ArrayList<String> found,
74
109
append (wordBuilder , board , p );
75
110
String current = wordBuilder .toString ();
76
111
77
- if (current .length () < 3 ) {
78
- walk (board , path , found , wordBuilder );
112
+
113
+ if (path .size () < 3 && current .length () < 3 ) {
114
+ walk (board , path , found , wordBuilder , keys );
79
115
}
80
116
else {
81
- Iterable <String > keys = dictionaryTrie .keysWithPrefix (current );
117
+ if (path .size () == 3 || current .length () == 3 || keys == null ) // reinit
118
+ keys = dictionaryTrie .keysWithPrefix (current );
82
119
int left = 0 ;
120
+ trace (" walking " + current + ", keys: " );
83
121
for (String k : keys ) {
84
- if (k == current )
85
- if (!found .contains (current ))
86
- found .add (current );
87
- else
122
+ trace (k + " " );
123
+ if (k .equals (current )) {
124
+ found .add (current );
125
+ }
126
+ else if (k .startsWith (current ))
88
127
left ++;
89
128
}
129
+ trace ("; " + left + " left\n " );
90
130
if (left > 0 )
91
- walk (board , path , found , wordBuilder );
131
+ walk (board , path , found , wordBuilder , keys );
92
132
}
93
133
94
134
path .pop ();
@@ -113,16 +153,13 @@ private Iterable<Point> getAdj(BoggleBoard board, Point p) {
113
153
// Returns the score of the given word if it is in the dictionary, zero otherwise.
114
154
// (You can assume the word contains only the uppercase letters A through Z.)
115
155
public int scoreOf (String w ) {
116
- if (dictionaryTrie .contains (w )) {
117
- int l = w .length ();
118
- if (l < 3 ) return 0 ;
119
- if (l < 5 ) return 1 ;
120
- if (l == 5 ) return 2 ;
121
- if (l == 6 ) return 3 ;
122
- if (l == 7 ) return 5 ;
123
- if (l > 7 ) return 11 ;
124
- }
125
- return 0 ;
156
+ int l = w .length ();
157
+ if (l < 3 ) return 0 ;
158
+ if (l < 5 ) return 1 ;
159
+ if (l == 5 ) return 2 ;
160
+ if (l == 6 ) return 3 ;
161
+ if (l == 7 ) return 5 ;
162
+ return 11 ;
126
163
}
127
164
128
165
public static void main (String [] args )
@@ -164,6 +201,6 @@ public int hashCode() {
164
201
}
165
202
166
203
private void trace (String msg ) {
167
- //StdOut.println (msg);
204
+ //StdOut.print (msg);
168
205
}
169
206
}
0 commit comments