Skip to content

Commit 676ef2f

Browse files
concatenated words
1 parent 7332d36 commit 676ef2f

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
package package1;
2+
3+
import java.util.*;
4+
import java.io.*;
5+
6+
/**
7+
* There's a file called “words-for-problem.txt” which contains a sorted list of
8+
* approximately 173,000 words. The words are listed one word per line, do not contain spaces, and
9+
* are all lowercase.
10+
*
11+
* Your task is to write a program that reads the file and provides the following:
12+
* the longest concatenated word (that is,the longest word that is comprised entirely of shorter words in the
13+
* file)
14+
* the 2nd longest concatenated word
15+
* the total count of all the concatenated words in the file
16+
*
17+
* For example, if the file contained:
18+
*
19+
* cat
20+
*
21+
* cats
22+
*
23+
* catsdogcats
24+
*
25+
* dog
26+
*
27+
* dogcatsdog
28+
*
29+
* hippopotamuses
30+
*
31+
* rat
32+
*
33+
* ratcatdogcat
34+
*
35+
* the longest concatenated word would be 'ratcatdogcat' with 12 characters. ‘hippopotamuses’ is a
36+
* longer word, however it is not comprised entirely of shorter words in the list. The 2nd longest
37+
* concatenated word is ‘catsdogcats’ with 11 characters. The total number of concatenated words is 3.
38+
* Note that ‘cats’ is not a concatenated word because there is no word ‘s’ in the list.
39+
*
40+
* Your solution
41+
*
42+
* Please email your solution source code as attachments (zipped if more than 3 files). In addition,
43+
* please include the following details in the body of the email:
44+
*
45+
* the longest and 2nd longest concatenated words
46+
*
47+
* the total count of concatenated words in the file
48+
*
49+
* the programming language(s) you used to complete the challenge
50+
*/
51+
public class ConcatenatedWords {
52+
public static void main(String... args) {
53+
// String FILE_PATH = "/Users/SteveSun/Google Drive/Developer/wordsforproblem.txt";
54+
// String FILE_PATH = "/Users/SteveSun/Google Drive/Developer/first30.txt";
55+
// String FILE_PATH = "/Users/SteveSun/Google Drive/Developer/first50.txt";
56+
String FILE_PATH = "/Users/SteveSun/Google Drive/Developer/first100.txt";
57+
// String FILE_PATH = "/Users/SteveSun/Google Drive/Developer/test.txt";
58+
59+
// String OUTPUT_PATH = "/Users/SteveSun/Google Drive/Developer/output2.txt";
60+
// String OUTPUT_PATH = "/Users/SteveSun/Google Drive/Developer/output_first30.txt";
61+
// String OUTPUT_PATH = "/Users/SteveSun/Google Drive/Developer/output_first50.txt";
62+
String OUTPUT_PATH = "/Users/SteveSun/Google Drive/Developer/output_first100.txt";
63+
// String OUTPUT_PATH = "/Users/SteveSun/Google Drive/Developer/output_test.txt";
64+
ConcatenatedWords test = new ConcatenatedWords();
65+
test.doJob(FILE_PATH, OUTPUT_PATH);
66+
}
67+
68+
public void doJob(String FILE_PATH, String OUTPUT_PATH) {
69+
try {
70+
long startTime = System.currentTimeMillis();
71+
ResultType result = readFromFile(FILE_PATH);
72+
Set<String> wordDict = result.wordDict;
73+
Integer maxWordLen = result.maxWordLen;
74+
List<String> validConcatenatedWords = findAllValidConcatenatedWords(wordDict,
75+
maxWordLen);
76+
//Note: if we're only interested in the first two longest words, then we can iterate through validConcatenatedWords once
77+
//and find those two
78+
79+
//For a more verbose solution, I'm printing all words in descending order based on their lengths.
80+
81+
Collections.sort(validConcatenatedWords, new Comparator<String>() {
82+
@Override
83+
public int compare(String o1, String o2) {
84+
if (o1.length() > o2.length()) {
85+
return -1;
86+
} else if (o1.length() < o2.length()) {
87+
return 1;
88+
} else {
89+
return 0;
90+
}
91+
}
92+
});
93+
long finishTime = System.currentTimeMillis();
94+
long usedTime = finishTime - startTime;
95+
96+
File file = new File(OUTPUT_PATH);
97+
98+
if (!file.exists())
99+
file.createNewFile();
100+
101+
FileWriter fw = new FileWriter(file.getAbsoluteFile());
102+
BufferedWriter bw = new BufferedWriter(fw);
103+
bw.write("There's a total of " + validConcatenatedWords.size() + " valid concatenated words found in this file.\n");
104+
bw.write("It took " + usedTime + " ms to finish.\n");
105+
for (String word : validConcatenatedWords) {
106+
bw.write(word + "\n");
107+
}
108+
109+
bw.close();
110+
} catch (Exception e) {
111+
e.printStackTrace();
112+
}
113+
114+
}
115+
116+
private List<String> findAllValidConcatenatedWords(Set<String> wordDict, Integer maxWordLen) {
117+
List<String> validConcatenatedWords = new ArrayList();
118+
119+
for (String word : wordDict) {
120+
if (isValid(wordDict, word, maxWordLen)) {
121+
validConcatenatedWords.add(word);
122+
}
123+
}
124+
125+
return validConcatenatedWords;
126+
}
127+
128+
private boolean isValid(final Set<String> wordDict, String s, int maxWordLen) {
129+
if (s == null || s.length() == 0)
130+
return false;
131+
Set<String> wordDictCopy = new HashSet(wordDict);
132+
wordDictCopy.remove(s);// every word is comprised of every word itself, thus this word
133+
// itself needs to be removed first for checking it*/
134+
int n = s.length();
135+
boolean[] dp = new boolean[n + 1];
136+
dp[0] = true;
137+
138+
for (int i = 1; i <= n; i++) {
139+
for (int j = 1; j <= i && j <= maxWordLen; j++) {
140+
if (!dp[i - j])
141+
continue;
142+
143+
String word = s.substring(i - j, i);
144+
if (wordDictCopy.contains(word)) {
145+
dp[i] = true;
146+
break;
147+
}
148+
}
149+
}
150+
151+
return dp[n];
152+
}
153+
154+
class ResultType {
155+
Set<String> wordDict;
156+
Integer maxWordLen;
157+
158+
ResultType(Set<String> wordDict, Integer maxWordLen) {
159+
this.wordDict = wordDict;
160+
this.maxWordLen = maxWordLen;
161+
}
162+
}
163+
164+
public ResultType readFromFile(String filePath) throws Exception {
165+
Set<String> wordDict = new HashSet<>();
166+
int maxWordLen = Integer.MIN_VALUE;
167+
try {
168+
BufferedReader br = new BufferedReader(new FileReader(filePath));
169+
try {
170+
StringBuilder sb = new StringBuilder();
171+
String line = br.readLine();
172+
173+
while (line != null) {
174+
String word = new String(line);
175+
maxWordLen = (maxWordLen > word.length()) ? maxWordLen : word.length();
176+
if (word.length() != 0)
177+
wordDict.add(word.trim());
178+
line = br.readLine();
179+
}
180+
} finally {
181+
br.close();
182+
}
183+
} finally {
184+
// print out or log error information reading input files
185+
}
186+
ResultType result = new ResultType(wordDict, maxWordLen);
187+
return result;
188+
}
189+
}

0 commit comments

Comments
 (0)