I will attach the code I have below. It is almost entirely done but i am getting a NullPointerException that is driving me nuts, and I can't figure out were it is coming from.
Help is greatly appreciated.
First code:
Second code:
Third code:
The Error:
I will attempt to explain what this does in as few words as possible. For a breakdown of the lab go here. If you don't feel like reading that: THe program reads in some command line arguments. From there it reads from the file provided in the command line and creates "keys" from the specified length. From there I need to create a phrase of the specified length. If i am supposed to create more then one then i do. That is pretty much it. I can't figure out where (really why) the NullPointerException error is coming from.
Help is appreciated!!
Help is greatly appreciated.
First code:
Code:
import java.util.Scanner;
import java.io.*;
import java.util.Random;
import java.util.Collection;
public class DistributionPlagiarist
{
public static void main(String[] args) throws IOException
{
Scanner keyboard = new Scanner(System.in);
int keyLength=0, phraseLength=0, numberOfPhrases=0;
String inputFileName="", keepReadingFromFile="", theFile="";
FrequencyLibrary text = new DenseFrequencyLibrary();
if(args.length != 4)
{
System.out.println("The command line arguments you entered do not match what is needed. Please try again.");
System.exit(0);
}
for(int count=0; count<args.length; count++)
{
keyLength = Integer.parseInt(args[0]);
phraseLength = Integer.parseInt(args[1]);
numberOfPhrases = Integer.parseInt(args[2]);
inputFileName = args[3];
}
if(keyLength < 0)
{
while(keyLength < 0)
{
System.out.print("The length of the key (" + keyLength + ")" + " you entered is less than zero.\nPlease enter another key length: ");
keyLength = keyboard.nextInt();
System.out.println();
}
}
if(phraseLength < 0)
{
while(phraseLength < 0)
{
System.out.print("The desired length of the phrase (" + phraseLength + ")" + " you entered is less than zero.\nPlease enter another phrase length: ");
keyLength = keyboard.nextInt();
System.out.println();
}
}
if(numberOfPhrases <= 0)
{
while(numberOfPhrases <= 0)
{
System.out.print("The desired number of phrases (" + keyLength + ")" + " you entered is not applicable.\nPlease choose another number: ");
keyLength = keyboard.nextInt();
System.out.println();
}
}
File file=new File(inputFileName);
boolean exists = file.exists();
if (exists == false)
{
while(exists == false)
{
System.out.println("The file you are searching for does not exist. Please place it in this programs directory.");
System.out.print("Please re-enter the file name: ");
inputFileName = keyboard.nextLine();
file=new File(inputFileName);
exists = file.exists();
}
}
int count=keyLength, start=0, stop=0;
FileReader freader = new FileReader(inputFileName);
BufferedReader inputFile = new BufferedReader(freader);
while(keepReadingFromFile != null)
{
keepReadingFromFile = inputFile.readLine();
if(keepReadingFromFile == null)
{
break;
}
else
{
theFile = theFile + keepReadingFromFile;
}
}
while(count < theFile.length())
{
String name = theFile.substring(start, keyLength+stop);
char singleCharacter = theFile.charAt(count);
text.add(name, singleCharacter);
start++;
stop++;
count++;
}
int countNumberOfPhrases=0;
while(numberOfPhrases > 0)
{
countNumberOfPhrases++;
String phrase = randomphrase(text, phraseLength, keyLength);
System.out.println("Phrase " + countNumberOfPhrases + ":\n" + phrase);
numberOfPhrases--;
}
}
private static String randomphrase(FrequencyLibrary textLibrary, int phraseLengthToMake, int startLength)
{
String startString="";
char characterToAdd=' ';
startLength++;
Random generator = new Random();
int sizeOfLibrary=textLibrary.size()/2, randomInt = generator.nextInt(sizeOfLibrary+1), value=0;
Collection<String> stringNames = textLibrary.makeStringCollection();
for(String stringFromCollection : stringNames)
{
if(randomInt == value)
{
startString = stringFromCollection;
}
value++;
}
String thePhrase = new String(startString);
System.out.println("INITIAL START:" + startString + "TTTT");
int substringStart=1;
while(startLength < phraseLengthToMake)
{
characterToAdd = textLibrary.randomUniformChoose(startString);
thePhrase = thePhrase + characterToAdd;
System.out.println("CHARACTER:" + characterToAdd + "TTTT");
System.out.println("PHRASE:" + thePhrase + "TTTT");
startString = thePhrase.substring(substringStart, thePhrase.length());
boolean answer = textLibrary.contains(startString);
System.out.println(answer);
System.out.println("NEW STRING:" + startString + "TTTT");
startLength++;
substringStart++;
}
return thePhrase;
}
}
Second code:
Code:
import java.util.Collection;
import java.util.HashMap;
public class DenseFrequencyLibrary implements FrequencyLibrary
{
private HashMap<String, MultiSetOfChar> bookTitleAndCharacterAndIntegerHashMap = new HashMap<String, MultiSetOfChar>();
private MultiSetOfChar keyAndValuePairs = new DenseMultiSetOfChar();
/**
* Creates a new DenseFrequencyLibrary with all the essential things clear;
*/
DenseFrequencyLibrary()
{
bookTitleAndCharacterAndIntegerHashMap.clear();
}
/**
* Input the value from the creation of the DensneMultiSetOfChar into a HashMap. If the key
* already exists then the value associated with it is updated by one.
*
* @param character a char to be used in forming the HashMap
* @return characterMap
*/
private HashMap<String, MultiSetOfChar> inputIntoMap(String name, char character)
{
if(!bookTitleAndCharacterAndIntegerHashMap.containsKey(name))
{
keyAndValuePairs = new DenseMultiSetOfChar(character);
}
else
{
keyAndValuePairs.add(character);
}
this.bookTitleAndCharacterAndIntegerHashMap.put(name, keyAndValuePairs); //input character and value
return bookTitleAndCharacterAndIntegerHashMap; //return the new HashMap
}
/**
* Returns the number of books in the library.
*
* @return |b|, ie the number of books in b
*/
public int size()
{
int numberOfBooks=bookTitleAndCharacterAndIntegerHashMap.size();
return numberOfBooks;
}
/**
* Searches the library for an occurrence of a given book
*
* @param target the name of a book to be searched for in the library
* @return true if and only if the argument is already a book title in the library.
*/
public boolean contains(String target)
{
boolean bookIsInLibrary=false;
if(bookTitleAndCharacterAndIntegerHashMap.containsKey(target))
{
bookIsInLibrary = true;
}
return bookIsInLibrary;
}
/**
* Returns the MultiSetOfChar that represents the occurrences of the individual characters
* in the text of the book indicated by the argument.
*
* @param target
* @return MultiSetOfChar
*/
public MultiSetOfChar getFrequencies(String target)
{
MultiSetOfChar frequencyMultiSetOfChar = bookTitleAndCharacterAndIntegerHashMap.get(target);
return frequencyMultiSetOfChar;
}
/**
* Modifies the character occurrences associated with name to include one more occurrence of element.
*
* @param name string of the name of the book
* @param element character to add to the specified book
*/
public void add(String name, char element)
{
bookTitleAndCharacterAndIntegerHashMap = inputIntoMap(name, element);
}
/**
* Modifies the character occurrences associated with name to include one less occurrence of element.
*
* @param name string of the name of the book
* @param element character to be removed from the specified book
* @return true if and only if the book is modified.
*/
public boolean remove(String name, char element)
{
boolean characterWasRemovedFromBook=false;
//if the target character is in the map then remove it
if(bookTitleAndCharacterAndIntegerHashMap.containsKey(name))
{
MultiSetOfChar keyAndValuePairs = bookTitleAndCharacterAndIntegerHashMap.get(name);
keyAndValuePairs.remove(element);
characterWasRemovedFromBook = true; //set answer to true because the HashMap was changed
}
else //target does not exist in the HashMap
{
characterWasRemovedFromBook = false; //set answer to false because the HashMap was not changed
}
return characterWasRemovedFromBook;
}
/**
* Returns a random character, chosen from the same distribution as the characters appear in the book.
* For example, if 5% of the characters in "Alice in Wonderland" are an 'A', then this method should
* return an 'A' about 5% of the time.
*
* @param name string of the name of the book to search through and remove a character
* @return true if and only if the argument is already a book title in the library.
*/
public char randomUniformChoose(String name)
{
MultiSetOfChar keyAndValuePairs = bookTitleAndCharacterAndIntegerHashMap.get(name);
char randomCharacter = keyAndValuePairs.randomUniformChoose();
return randomCharacter; //return the random character pulled out
}
public Collection<String> makeStringCollection()
{
Collection<String> stringCollection = bookTitleAndCharacterAndIntegerHashMap.keySet();
return stringCollection;
}
}
Third code:
Code:
import java.util.HashMap;
import java.util.Set;
import java.util.Collection;
import java.util.Random;
/**
* DenseMultiSetOfChar implements MultiSetOfChar.
* @mathmodel b is a finite multiset
*
* @mathdef
* |b| is the cardinality of b
* ||c,b|| is the number of occurrences of element c in b
*
* @author Kyle Hiltner
*
*/
public class DenseMultiSetOfChar implements MultiSetOfChar
{
private char characterInput=' ';
private HashMap<Character, Integer> characterMap = new HashMap<Character, Integer>();
/**
* Create a new DenseMultiSetOfChar with zero argument
*/
DenseMultiSetOfChar()
{
characterMap.clear(); //clear static HashMap
}
/**
* Create a new DenseMultiSetOfChar with the passed in value.
*
* @param newChar character input to be added to the HashMap
*/
DenseMultiSetOfChar(char newChar)
{
this.characterInput = newChar; //set characterInput to the value passed in
characterMap = inputIntoMap(this.characterInput); //call private procedure to add characterInput to HashMap
}
/**
* Input the value from the creation of the DensneMultiSetOfChar into a HashMap. If the key
* already exists then the value associated with it is updated by one.
*
* @param character a char to be used in forming the HashMap
* @return characterMap
*/
private HashMap<Character, Integer> inputIntoMap(char character)
{
//if the character is not in the HashMap then add it with the starting value of 1
if(!characterMap.containsKey(character))
{
characterMap.put(character, 1); //input character and value
}
else //character does exist
{
int value = characterMap.get(character); //get the value for the specified key
value++; //increase the value so as to show that another character was added
characterMap.put(character, value); //place the character and new value in the HashMap
}
return characterMap; //return the new HashMap
}
/**
* Returns the number of elements in this multiset (ie its cardinality).
* Note that since multisets can include duplicates, the cardinality may be
* larger than the number of distinct elements. Also, the total number of
* items in the multiset is bounded above by Integer.MAX_VALUE.
*
* @return |b|, ie the cardinality of b
*/
public int getCardinality()
{
int totalElementsInMap=0;
Collection<Integer> integerCollection = characterMap.values(); //create a collection for easy iteration
//iterate through each value in the HashMap and compute the total number of elements in the HashMap
for(Integer valueFromCollection : integerCollection)
{
totalElementsInMap = totalElementsInMap + valueFromCollection; //compute new value of total values
}
return totalElementsInMap; //return the final total value
}
/**
* Returns the number of occurrences of a given element in the multiset. A
* simple identity relating getElementCount and getCardinality is that the
* sum of getElementCount for each char is equal to the cardinality of the
* set.
*
* @param target
* char to be counted in the multiset
* @return ||target,b||, ie the number of occurrences of target in b
*/
public int getElementCount(char target)
{
int numberOfGivenCharacters=0; //set initial value
//if the HashMap contains the target character then numberOfGivenCharacters is set to the value
if(characterMap.containsKey(target))
{
numberOfGivenCharacters = characterMap.get(target); //set numberOfGivenCharacters to the value assigned to the target character
}
return numberOfGivenCharacters; //return the value for the target character
}
/**
* Returns a set such that every element in the multiset is in the set (but
* no duplicates). The cardinality of the returned set must be less than or
* equal to |b|. The cardinality of the two are equal if and only if b
* contains no duplicate elements.
*
* @return a set of Character, s, such that: <br />
* (for all (Character)i in s : (char)i in b) and <br />
* (for all (char)i in b : (Character)i in s)
*/
public Set<Character> getElementSet()
{
Set<Character> characterSet = characterMap.keySet(); //create a Set from the keys of characters in the HashMap
return characterSet; //return the character Set
}
/**
* Adds a single element to the multiset. This operation always increases
* the cardinality of the multiset by 1, assuming that the maximum capacity
* of Integer.MAX_VALUE has not been reached.
*
* @param item
* the char to be added to b
* @requires |b| < Integer.MAX_VALUE
* @alters b
* @ensures b = #b union {item}
*/
public void add(char item)
{
characterMap = inputIntoMap(item); //call the private method to add new character (item) to the HashMap
}
/**
* Removes the target, if it is present in the multiset. The method returns
* true if and only if it changes the multiset.
*
* @param target
* the char to be removed
* @alters b
* @ensures (target not in #b) ==> (b = #b) <br />
* (target in #b) ==> (b union {target} = #b)
* @return target in #b
*/
public boolean remove(char target)
{
boolean answer=false; //set initial value to false
//if the target character is in the map then remove it
if(characterMap.containsKey(target))
{
int value = characterMap.get(target); //find the value associated with the target character
//if the value is 1 call remove from the HashMap and remove key and value
if(value == 1)
{
characterMap.remove(target); //remove key and value from the HashMap
}
else //value is greater than 1
{
value--; //decrease value to show removal
characterMap.put(target, value); //replace target character with new value back into the HashMap
}
answer = true; //set answer to true because the HashMap was changed
}
else //target does not exist in the HashMap
{
answer = false; //set answer to false because the HashMap was not changed
}
return answer; //return answer
}
/**
* Returns a char chosen randomly based on the contents of the multiset.
* This operation does not remove the char from the multiset or change the
* multiset in any way. In particular, the cardinality of the multiset is
* the same before and after this method.
*
* <p>
* Characters should be returned with a random distribution equal to the
* distribution of characters in the multiset. That is, for a character that
* appears N times in a multiset of cardinality M, the probability of that
* character being returned is N / M. For example, a multiset that contains
* only the character 'a', possibly many times, would always result in an
* 'a' being generated. On the other hand, a multiset with an equal number
* of 'a' and 'b' elements would return an 'a' approximately half the time
* and a 'b' the other half.
*
* @requires |b| >= 1
* @return char c with probability p, where: <br />
* p = ||c,b|| / |b|
*/
public char randomUniformChoose()
{
char randomCharacter=' ';
Random generator = new Random();
int totalElementsInMap=0;
Collection<Integer> integerCollection = characterMap.values(); //create a collection for easy iteration
//iterate through each value in the HashMap and compute the total number of elements in the HashMap.
//Do this in case a remove call was made
for(Integer valueFromCollection : integerCollection)
{
totalElementsInMap = totalElementsInMap + valueFromCollection; //compute new value of total values
}
int randomInt = generator.nextInt(totalElementsInMap+1), lowerValue=0, upperValue=0;
Collection<Character> keyCollection = characterMap.keySet();
//iterate through each value in the HashMap and compute the total number of elements in the HashMap
for(Character keyFromCollection : keyCollection)
{
upperValue = upperValue + characterMap.get(keyFromCollection);
if(randomInt == upperValue)
{
randomCharacter = keyFromCollection;
}
if(randomInt >= lowerValue && randomInt <= upperValue)
{
randomCharacter = keyFromCollection;
}
lowerValue = upperValue + 1;
}
return randomCharacter; //return the random character pulled out
}
}
The Error:
Code:
Exception in thread "main" java.lang.NullPointerException
at DenseFrequencyLibrary.randomUniformChoose(DenseFrequencyLibrary.java:137)
at DistributionPlagiarist.randomphrase(DistributionPlagiarist.java:146)
at DistributionPlagiarist.main(DistributionPlagiarist.java:112)
I will attempt to explain what this does in as few words as possible. For a breakdown of the lab go here. If you don't feel like reading that: THe program reads in some command line arguments. From there it reads from the file provided in the command line and creates "keys" from the specified length. From there I need to create a phrase of the specified length. If i am supposed to create more then one then i do. That is pretty much it. I can't figure out where (really why) the NullPointerException error is coming from.
Help is appreciated!!