Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,55 +19,33 @@ public SimpleDictionaryTest() {
@Test
public void testIsWordNullDict() {
System.out.println("isWord Null dictionary");
String w = "";
SimpleDictionary instance = new SimpleDictionary(null);
boolean expResult = false;
boolean result = instance.isWord(w);
assertEquals(expResult, result);
assertEquals(false, (new SimpleDictionary(null)).isWord(""));
}

@Test
public void testIsPrefixNullDict() {
System.out.println("isPrefix Null dictionary");
String p = "";
SimpleDictionary instance = new SimpleDictionary(null);
boolean expResult = false;
boolean result = instance.isPrefix(p);
assertEquals(expResult, result);
assertEquals(false, new SimpleDictionary(null).isPrefix(""));
}

@Test
public void testIsWordEmptyDict() {
System.out.println("isWord Empty dictionary");
String w = "";
String[] dict = new String[0];
SimpleDictionary instance = new SimpleDictionary(dict);
boolean expResult = false;
boolean result = instance.isWord(w);
assertEquals(expResult, result);
assertEquals(false, new SimpleDictionary(new String[0]).isWord(""));
}

@Test
public void testIsPrefixEmptyDict() {
System.out.println("isPrefix Empty dictionary");
String p = "";
String[] dict = new String[0];
SimpleDictionary instance = new SimpleDictionary(dict);
boolean expResult = false;
boolean result = instance.isPrefix(p);
assertEquals(expResult, result);
assertEquals(false, new SimpleDictionary(new String[0]).isPrefix(""));
}

@Test
public void testIsWordSingleWordDict_F() {
System.out.println("isWord SingleWord dictionary (F)");
String w = "";
String[] dict = new String[1];
dict[0] = "cat";
SimpleDictionary instance = new SimpleDictionary(dict);
boolean expResult = false;
boolean result = instance.isWord(w);
assertEquals(expResult, result);
assertEquals(false, new SimpleDictionary(dict).isWord(""));
}

@Test
Expand All @@ -81,17 +59,16 @@ public void testIsPrefixSingleWordDict_F() {
String[] dict = new String[1];
dict[0] = "cat";
SimpleDictionary instance = new SimpleDictionary(dict);
boolean expResult = false;
boolean result1 = instance.isPrefix(p1);
boolean result2 = instance.isPrefix(p2);
boolean result3 = instance.isPrefix(p3);
boolean result4 = instance.isPrefix(p4);
boolean result5 = instance.isPrefix(p5);
assertEquals(expResult, result1);
assertEquals(expResult, result2);
assertEquals(expResult, result3);
assertEquals(expResult, result4);
assertEquals(expResult, result5);
assertEquals(false, result1);
assertEquals(false, result2);
assertEquals(false, result3);
assertEquals(false, result4);
assertEquals(false, result5);
}

@Test
Expand All @@ -101,9 +78,8 @@ public void testIsWordSingleWordDict_T() {
String[] dict = new String[1];
dict[0] = "cat";
SimpleDictionary instance = new SimpleDictionary(dict);
boolean expResult = true;
boolean result = instance.isWord(w);
assertEquals(expResult, result);
assertEquals(true, result);
}
@Test
public void testIsPrefixSingleWordDict_T() {
Expand All @@ -115,15 +91,14 @@ public void testIsPrefixSingleWordDict_T() {
String[] dict = new String[1];
dict[0] = "cat";
SimpleDictionary instance = new SimpleDictionary(dict);
boolean expResult = true;
boolean result1 = instance.isPrefix(p1);
boolean result2 = instance.isPrefix(p2);
boolean result3 = instance.isPrefix(p3);
boolean result4 = instance.isPrefix(p4);
assertEquals(expResult, result1);
assertEquals(expResult, result2);
assertEquals(expResult, result3);
assertEquals(expResult, result4);
assertEquals(true, result1);
assertEquals(true, result2);
assertEquals(true, result3);
assertEquals(true, result4);
}

@Test
Expand All @@ -132,9 +107,8 @@ public void testIsWordSmallDict_F() {
String w = "AT";
String[] dict = {"CAR", "CARD", "CART", "CAT"};
SimpleDictionary instance = new SimpleDictionary(dict);
boolean expResult = false;
boolean result = instance.isWord(w);
assertEquals(expResult, result);
assertEquals(false, result);
}

@Test
Expand All @@ -144,11 +118,10 @@ public void testIsPrefixSmallDict_F() {
String p2 = "PAR";
String[] dict = {"CAR", "CARD", "CART", "CAT"};
SimpleDictionary instance = new SimpleDictionary(dict);
boolean expResult = false;
boolean result1 = instance.isPrefix(p1);
boolean result2 = instance.isPrefix(p2);
assertEquals(expResult, result1);
assertEquals(expResult, result2);
assertEquals(false, result1);
assertEquals(false, result2);
}

@Test
Expand All @@ -159,13 +132,12 @@ public void testIsWordSmallDict_T() {
String w3 = "CAT";
String[] dict = {"CAR", "CARD", "CART", "CAT"};
SimpleDictionary instance = new SimpleDictionary(dict);
boolean expResult = true;
boolean result1 = instance.isWord(w1);
boolean result2 = instance.isWord(w2);
boolean result3 = instance.isWord(w3);
assertEquals(expResult, result1);
assertEquals(expResult, result2);
assertEquals(expResult, result3);
assertEquals(true, result1);
assertEquals(true, result2);
assertEquals(true, result3);
}

@Test
Expand All @@ -175,10 +147,9 @@ public void testIsPrefixSmallDict_T() {
String p2 = "CAR";
String[] dict = {"CAR", "CARD", "CART", "CAT"};
SimpleDictionary instance = new SimpleDictionary(dict);
boolean expResult = true;
boolean result1 = instance.isPrefix(p1);
boolean result2 = instance.isPrefix(p2);
assertEquals(expResult, result1);
assertEquals(expResult, result2);
assertEquals(true, result1);
assertEquals(true, result2);
}
}
147 changes: 147 additions & 0 deletions CodeU_Assignement_5/src/codeu_assignement_5/KemUnknownLanguage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package codeu_assignement_5;

import java.util.ArrayList;
import java.util.List;

/**
*
* @author Karine
*/
public class KemUnknownLanguage {
/*
* Input: a alphabetionary (a list of words in lexicographic order) of all words in an unknown/invented language,
* Output: alphabet (an ordered list of characters) of that language, letters we cannot decide are appended in the end.
*/
public List<Character> getAlphabeit(String[] alienWords) {
if (alienWords == null) {
return null;
}

List<Character> alphabet = null;

/* Get the current order by prefix size, starting from 0 */
alphabet = inferAlphabetFromCommonPrefix(alienWords, 0); /* Basic Alphabeit */
/* A,R,C from the example! */

/* Add from prefix while there are letters after first letter of prefix */
addToDictByPrefixSize(alienWords, alphabet);

/* Add all the chars we cannot decide in the end - According to the comments in Slack */
for (String w : alienWords) {
for (Character c: w.toCharArray()) {
if (!alphabet.contains(c)) {
alphabet.add(c);
}
}
}

return alphabet;
}

/*
* Inputs: All words with the same prefix (all the first prefixSize chars are the same!)
* Output: Per common prefix, gets the order of the chars
*
* Process: Given an array of words that all match up to a common prefix length, infer an
* alphabetical ordering of the characters based on the order of the first differing character.
* No check is made that the common prefix really is the same across the list.
*/
private List<Character> inferAlphabetFromCommonPrefix(String[] words, int prefixSize) {
List<Character> ret = new ArrayList();
for (String w : words) {
if ((w.length() > prefixSize) && (!ret.contains(w.charAt(prefixSize)))) {
ret.add(w.charAt(prefixSize));
}
}

return ret;
}

/*
* Input: the original set of words, current word we are working on, its prefix size
* Output: the set of the words with this prefix
*/
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention of this method is actually pretty clear to me, although I'd still prefer to have it explained in words, rather than via "Input: ... Output: ...".

"Output: the set of the words with this prefix" is mildly misleading - "set" implies a lack of ordering, while in this context order is very important. "Ordered list of words with this prefix" is less ambiguous.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It helps me to remember the technical part of it. But I added the whole description as what is the algorithm or process. Thanks!

private String[] getWordsWithSamePrefix(String[] alienWords, int curr, int prefixSize) {
ArrayList<String> tempDict = new ArrayList();
tempDict.add(alienWords[curr]);

String prefix = alienWords[curr].substring(0, prefixSize);

/* Forward search */
for (int i=curr+1; i<alienWords.length; i++) {
if (!alienWords[i].startsWith(prefix)) {
break;
}
tempDict.add(alienWords[i]);
}

/* Backward search */
for (int i=curr-1; i >= 0; i--) {
if (!alienWords[i].startsWith(prefix)) {
break;
}
tempDict.add(0,alienWords[i]);
}

return tempDict.toArray(new String[tempDict.size()]);
}

/*
* Get two alphabetionary with common latters and merge them into the first alphabet,
* if none, cannot know, add all these cases later on
* E.g., we have the current alphabet, A,T,C
* and withset of rules saying A,R,T to be the new alphabet:
* A,R,T,C
*/
private void mergeDict(List<Character> alphabet1, List<Character> alphabet2) {
int from2 = 0; /* Start from location 0 in alphabet1 */

/* Pass on alphabet2 and merge it into alphabet1 */
for (int i=0; i < alphabet2.size(); i++) {
/* Adds to the alphabet only to satisfy a rule, if not adds all in the end
(no rule, or only says "it comes after that symbol",
with no restriction of "but it also comes before the other symbol") */
if (alphabet1.contains(alphabet2.get(i))) {
if ((i+1) < alphabet2.size()
&& (alphabet1.contains(alphabet2.get(i+1)))
&& (alphabet1.indexOf(alphabet2.get(i)) > alphabet1.indexOf(alphabet2.get(i+1)))) {
/* Need to fix the order */
alphabet1.remove(alphabet2.get(i));
alphabet1.add(alphabet1.indexOf(alphabet2.get(i+1)), alphabet2.get(i));
} else {
/* Find common point, merge here! */
/* Case where we have: */
alphabet1.addAll(alphabet1.indexOf(alphabet2.get(i)), alphabet2.subList(from2, i));
}
from2 = i+1; /* The next location in alphabet2 to start adding to in alphabet1 */
}
}

/* For all the symbols in alphabet2 that only needs to come after, adds it to the end of alphabet1 */
if (from2 <= (alphabet2.size()-1)) {
alphabet1.addAll(alphabet2.subList(from2, alphabet2.size())); /* Add the tail */
}
}

/*
For each length of prefix (1,2,3,4,....(i)), collects all the prefixes
and if found a new rule adds it to the dictionary
*/
private void addToDictByPrefixSize(String[] alienWords, List<Character> alphabet) {
/* For each size of prefix does the following: */
for (int i=0; i < alienWords.length; i++) { /* For each word, do: */
for (int j=1; j < alienWords[i].length(); j++) { /* For each prefix size */
int prefixSize = j;
String[] sublistWords = getWordsWithSamePrefix(alienWords, i, prefixSize);
if (sublistWords.length > 1) {
List<Character> tempDict = inferAlphabetFromCommonPrefix(sublistWords, prefixSize);
if (!tempDict.isEmpty()) {
mergeDict(alphabet,tempDict);
}
} else {
break;
}
}
}
}
}
Loading