In: Computer Science
You will write a program that prompts the user to enter a 7-digit phone numbers, and finds the 3- and 4-letter words that map to the phone number, according to the restrictions outlined earlier. A sample run:
unixlab% java MapNumbers
Enter name of dictionary file: words10683
Enter a test word (3 letters): cat
Test word maps to 228
Enter telephone number (7 digits, no 0's or 1's, negative to quit): 2282273
Options for first 3 digits:
act
cat
bat
Options for next 4 digits:
base
card
care
case
bare
Enter telephone number (7 digits, no 0's or 1's, negative to quit): 2232243
Options for first 3 digits:
bad
ace
Options for next 4 digits:
acid
cage
Enter telephone number (7 digits, no 0's or 1's, negative to quit): -1
unixlab%
More formally, your program should do this:
Prompt the user for the name of a dictionary file
Set up the PhoneMapper class and methods (see details below)
Prompt the user to enter a 3-letter test word (mostly for testing early versions)
Display the number that maps to that word
Prompt the user to enter a 7-digit telephone number
(quit when negative number is read)
Use the PhoneMapper class to map 3-letter and 4-letter words to the number
Display all 3-letter words that map to the first 3 digits of the number
Display all 4-letter words that map to the last 4 digits of the number
Prompt the user to enter another 7-digit telephone number
(quit when negative number is read)
PROVIDED SKELETON PROGRAM: *****************************************************************
import java.util.Scanner; public class MapNumbersSkeleton { public static void main(String [] args) throws Exception { Scanner input = new Scanner(System.in); // prompt user for dictionary file System.out.print("Enter name of dictionary file: "); String fName = input.nextLine(); // instantiate PhoneMapper for 3-letter words from dictionary file PhoneMapper myMap3 = new PhoneMapper(fName, 3); // initial test code System.out.print("Enter a test word (3 letters): "); String s = input.nextLine(); int testNum = myMap3.findTelNum(s); System.out.println("Test word maps to " + testNum); // instantiate PhoneMapper for 4-letter words from dictionary file // prompt user for phone number System.out.print("Enter telephone number "); System.out.print("(7 digits, no 0's or 1's, negative to quit): "); int telNum = input.nextInt(); while (telNum >= 0) { // process each non-negative number // extract first 3 digits int firstPart = telNum / 10000; // get words for first 3 digits and display String [] results = myMap3.findWords(firstPart); System.out.println("Options for first 3 digits:"); for (int i=0; i<results.length; i++) { System.out.println(results[i]); } // extract last 4 digits // get words for last 4 digits and display // prompt user for phone number System.out.print("Enter telephone number "); System.out.print("(7 digits, no 0's or 1's, negative to quit): "); telNum = input.nextInt(); } // end while (telNum >=0) } } class PhoneMapper { final int MAXWORDS = 20000; // max number of words from dictionary String [] wordList = new String [MAXWORDS]; // list of dictionary words int numWords = 0; // number of words of correct length // extracted from dictionary PhoneMapper(String fileName, int wordLength) throws Exception { // fileName: name of dictionary file // wordLength: length of words to extract // read dictionary file and // add each word of length wordLength to wordList[] } // return array of words mapped to num String [] findWords(int num) { String [] nString = new String[0]; return nString; } // returns telephone number that inStr maps to int findTelNum(String inStr) { return 0; } }
********************************************************
Step 1: Fill in the constructor for the PhoneMapper class. There’s only one constructor:
PhoneMapper(String fileName, int wordLength) throws Exception
filename is the name of the dictionary file to be used, wordLength is the length of the words to be extracted from the dictionary file. All words of length wordLength are added to the wordList[] array of Strings. (Note: this part uses code from Part A!)
An example: suppose we instantiate a PhoneMapper object:
PhoneMapper smallMap = new PhoneMapper(“words5”, 3);
words5 is the short test file we looked at in Part A. After the PhoneMapper constructor returns, smallMap.wordList[0] = “cat”, smallMap.wordList[1] = “dog”, and smallMap.numWords = 2.
Step 2: Fill in the method findTelNum():
int findTelNum(String inStr)
findTelNum() maps each character of inStr to a numeric digit according to the rule described earlier for telephone numbers, assembles the digits into a 3 or 4-digit integer, and returns the integer corresponding to the string.
An example:
String str = “bad”;
int x = findTelNum(str); // x = 223
Note that there’s some code in the main method of the public class for testing findTelNum().
Step 3: Fill in the method findWords():
String [] findWords(int num)
num is the 3 or 4-digit integer from the telephone number. findWords() checks every word in wordList[], by calling findTelNum(); if a word in wordList[] maps to num, that word is added to a list of mapped words. After all words in wordList[] that map to num have been copied to the list of mapped words, the list of mapped words is returned. Make sure the array returned has the correct length. (Hint: add the mapped words to a very large array first. After you are done adding mapped words, copy the very large array to a smaller array, with the correct length.)
An example: suppose we use words10683 as the dictionary file. The number 223 maps to two words in the file: bad and ace. When we run these lines of code:
PhoneMapper bigMap = new PhoneMapper(“words10683”, 3);
String [] s = bigMap.findWords(223);
s[0] = “bad”, s[1] = “ace”, and s.length = 2.
Step 4: Fill in the rest of the main loop in the main method in the public class, to find and report the 4-letter words that map to the last 4 digits of the telephone number entered by the user.
Program:
My lines are in bold
import java.util.Scanner;
import java.io.*;
import java.lang.*;
public class MapNumbersSkeleton
{
public static void main(String [] args) throws Exception
{
Scanner input = new Scanner(System.in);
// prompt user for dictionary file
System.out.print("Enter name of dictionary file: ");
String fName = input.nextLine();
// instantiate PhoneMapper for 3-letter words from dictionary
file
PhoneMapper myMap3 = new PhoneMapper(fName, 3);
// initial test code
System.out.print("Enter a test word (3 letters): ");
String s = input.nextLine();
int testNum = myMap3.findTelNum(s);
System.out.println("Test word maps to " + testNum);
// instantiate PhoneMapper for 4-letter words from dictionary
file
PhoneMapper myMap4 = new
PhoneMapper(fName, 4);
// prompt user for phone number
System.out.print("Enter telephone number ");
System.out.print("(7 digits, no 0's or 1's, negative to quit):
");
int telNum = input.nextInt();
while (telNum >= 0) { // process each non-negative number
// extract first 3 digits
int firstPart = telNum / 10000;
// get words for first 3 digits and display
String [] results = myMap3.findWords(firstPart);
System.out.println("Options for first 3 digits:");
for (int i=0; i<results.length; i++) {
System.out.println(results[i]);
}
// extract last 4 digits
int secondPart = telNum % 10000;
// get words for first 4 digits and display
results = myMap4.findWords(secondPart);
System.out.println("Options for last 4 digits:");
for (int i=0; i<results.length; i++) {
System.out.println(results[i]);
}
// prompt user for phone number
System.out.print("Enter telephone number ");
System.out.print("(7 digits, no 0's or 1's, negative to quit):
");
telNum = input.nextInt();
} // end while (telNum >=0)
}
}
class PhoneMapper {
final int MAXWORDS = 20000; // max number of words from
dictionary
String [] wordList = new String [MAXWORDS]; // list of dictionary
words
int numWords = 0; // number of words of correct length
// extracted from dictionary
PhoneMapper(String fileName, int wordLength) throws Exception
{
// fileName: name of dictionary file
// wordLength: length of words to extract
String line;
BufferedReader br = new
BufferedReader(new FileReader(fileName));
// read dictionary file and
// add each word of length
wordLength to wordList[]
while ((line =
br.readLine()) != null)
{
// if length of
line is equal to wordLength, add it to List
if(line.length()
== wordLength)
wordList[numWords++] = line;
}
}
// return array of words mapped to num
String [] findWords(int num) {
// declare array with
MAXWORDS size
String [] temp = new String[MAXWORDS];
// initialize count to 0
int count = 0;
// loop for each word in
wordList
for(int i = 0; i < numWords;
i++)
{
// if telNu, of
the word is equal to given num, add the word to array
if(findTelNum(wordList[i])==num)
temp[count++] = wordList[i];
}
// create a string array of size
equal to count
String[] nString = new
String[count];
// copy all words from large temp
array to small nString array
for(int i = 0; i < count;
i++)
{
nString[i] =
temp[i];
}
// return array
return nString;
}
// returns telephone number that inStr maps to
int findTelNum(String inStr)
{
// initialize number to 0
int number = 0;
// loop over each character of the
string
for(int i = 0; i <
inStr.length(); i++)
{
// multiple
number by 10 for each character of string
number *=
10;
// add
corresponding digit to the number
switch(Character.toLowerCase(inStr.charAt(i)))
{
case 'a':
case 'b':
case 'c':
number += 2;
break;
case 'd':
case 'e':
case 'f':
number += 3;
break;
case 'g':
case 'h':
case 'i':
number += 4;
break;
case 'j':
case 'k':
case 'l':
number += 5;
break;
case 'm':
case 'n':
case 'o':
number += 6;
break;
case 'p':
case 'q':
case 'r':
case 's':
number += 7;
break;
case 't':
case 'u':
case 'v':
number += 8;
break;
case 'w':
case 'x':
case 'y':
case 'z':
number += 9;
break;
}
}
// return number
return number;
}
}