Problem Statement
Prompt the user for the order
statistic n: 1, 2, 3,
etc.Read a file of tokens, building a map
(Map[List[Stringn]] -> List[String*])
from a list of n words to a list of the words in the text following these words: e.g., if n were 2, the
map
would contain a key for every pair of words in the text, and a value that is a list of all the words following the key (no matter where the pair occurs, with NO DUPLICATES allowed). Print all the associations, one per line, in any order (the n words followed by the list of words that follow them in the text).Prompt the user for the number of random words to generate, and then prompt for the n words to start with. Build a
list (List[String*])
using the words to start with to generate a random next word, then use the previous n words (dropping the oldest word and adding the new word generated) to generate another random word; repeat. Note: you might have to stop prematurely if you generate the last n words in the text, if these words occur nowhere else. That is because in this case, there is no random word to generate following them! Print the list.
In simple words
This is given string
a b c b a d c b a d c a a b a a d
We pre populate a map with (x,y) -> (...) map like
[a, d] -> [c] [a, b] -> [c, a] [a, a] -> [b, d] [b, c] -> [b] [b, a] -> [d, a] [c, b] -> [a] [c, a] -> [a] [d, c] -> [b, a]
We have to generate 5 length words taking first 2 input from user. We have to make other 3 letter by using above map.
Using above example
Enter # of words to generate: 10 Enter prefix word[0]: a Enter prefix word[1]: d Results = [a, d, c, a, a, b, a, d, c, a, a, d]
It is giving the correct output, but my questions are
- Can this be improved?
- Have I used collection classes efficiently?
- Is my algorithm efficient?
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
public class Application {
public static void main(String[] args)
{
String sample = "a b c b a d c b a d c a a b a a d";
StringTokenizer st = new StringTokenizer(sample);
List<String> givenList = new ArrayList<String>();
while(st.hasMoreElements())
{
givenList.add(st.nextToken());
}
/*
* generate (x,y) -> (...) map
*/
Map<List<String>,List<String>> advMap = new HashMap<List<String>, List<String>>();
String left1,left2,right = null;
for(int listIndex = 0 ;listIndex < givenList.size() - 2; listIndex++)
{
left1 = givenList.get(listIndex);
left2 = givenList.get(listIndex+1);
right = givenList.get(listIndex+2);
List<String> leftList = new ArrayList<String>();
leftList.add(left1);
leftList.add(left2);
//if key already exist, thne update right to the value list
if(advMap.containsKey(leftList))
{
advMap.get(leftList).add(right);
}
else
{
List<String> rightList = new ArrayList<String>();
rightList.add(right);
advMap.put(leftList, rightList);
}
}// end for
System.out.println(advMap);
//Ask user for length of word, he wants to generate. Here I am hard coding it
//Also, ask for first 2 letter he wants to start with
int lenghtOfWord = 5;
String x1 = "a";
String x2 = "d";
String[] genArray = new String[lenghtOfWord];
genArray[0] = x1;
genArray[1] = x2;
for(int genIndex=0; genIndex <lenghtOfWord-2 ; genIndex++)
{
List<String> leftKey = new ArrayList<String>();
leftKey.add(genArray[genIndex]);
leftKey.add(genArray[genIndex+1]);
genArray[genIndex+2] = randomWord(advMap,leftKey);
}
System.out.println("Generated Word");
for(int i=0;i<genArray.length;i++)
{
System.out.print(genArray[i]);
}
}// end main
private static String randomWord(Map<List<String>,List<String>> advMap, List<String> lKey)
{
if(advMap.containsKey(lKey))
{
List<String> lVal = advMap.get(lKey);
int rndIndx = (int) (Math.random() * lVal.size() );
return lVal.get(rndIndx);
}
else
{ //here is am expecting user will enter initial 2 letter which have mapping in the given inital advMap
return null;
}
}
}//end class
This is not an assignment to me, found over net. I'm doing it for practice.