Strings - SSA Computer Science

advertisement
AP Computer Science
Mr. Haytock
Unit 3: Strings
Topics:
I. Strings
II. Object references
III. String methods
Materials:
I. String overview
II. String exercises #1
III. String exercises #2
IV. Morphology Specifications
V. Mad Libs Specifications
1
String Overview
A proper implementation of how computers manipulate text data requires us to have an in-depth
understanding of how computers manage “strings.” You can think about a string as a series of
characters. Characters include letters, numbers, spaces and punctuation. Strings are a predefined class of the Java language. Do not confuse them with the primitive types (int,
double, boolean, etc). Strings are objects. Objects contain data (like the characters in a
string) but they also include methods (ways to manipulate the data in the string). The idea of
associating data with the methods that work upon it is called encapsulation.
A. Declaring an object of type String
When you declare a String by using the type and identifier, if you don’t assign it a value right
away, no memory is allocated to the String at that time. The identifier is just a reference to a
string that does not yet exist. Essentially, you are naming something before constructing it.
//Empty strings
String name1;
String schoolName, movieTitle;
However, you can give a String a value later in your program. When the String is initialized,
memory is allocated for it. The amount of memory assigned to a String depends on how many
characters are in it.
name1 = “Harry Potter”;
schoolName = “Hogwarts”;
movieTitle = “Harry Potter and the Big Ugly Spider”;
You can declare and construct a String in the same step if you wish. Using this technique, the
memory to hold “Jane Jones” is allocated at the same time name2 is created. This is not always
possible, however, particularly in the case when a String is to be input by the user.
String name2 = new String(“Jane Jones”);
//More examples of declaring and assigning a value
String restaurant = new String(“Pepe Pizza”);
String favPizza = new String(“Extra Cheese”);
You may also use the following shortcut to declare and construct Strings:
String name2 = “Jane Jones”;
String restaurant = “Pepe Pizza”;
String favPizza = “Roasted garlic and tomato”;
2
B. References to a String
You can assign a new value to a String after it is initialized. Java will find a new place in
memory to store the new String contents. String literals (values) can contain any
combination of characters such as letters, numbers, punctuation and special characters such as \n
and \t. Remember that String values must always be placed in “quotes” just like characters
are always placed in ‘apostrophes’. Assuming you already declared food1 and food2, you can
enter their values in quotes:
food1 = “sushi”;
food2 = “waffles”;
However, avoid assigning one String to another, for it doesn’t work the way you think.
food2 = food1;
Remember, the String identifier is a reference to the string data. The identifier points to the
place where the String is stored in memory. In the example above, food2 will now point to the
part of memory where “sushi” is stored. “waffles” is no longer pointed to by any identifier so
consider it gone.
Strings are immutable, meaning they cannot be changed. When a series of characters is stored
in a block of memory (when a String gets its initial value), that block of memory cannot be
changed. If you add onto a String or change it, the computer finds a new place in memory for
the changed String. Then, the identifier points to the new place in memory instead of the
original place.
C. Concatenation and Promotion
Here’s a little reminder as to how concatenation with the + operator works:
String first_name = new String(“Howdy”);
String last_name = new String(“Doody”);
String whole_name;
whole_name = first_name + “ ” + last_name;
Any primitive or object type can be promoted to a String. So Java makes it easy to use the print
methods with Strings and other data types. Because of this, you can create complex print
statements by concatenating different types. Note the example below.
public static void main(String[] args)
{
String s = "The values of n and x are";
int n = 10;
double x = 15.0;
System.out.println(s + " " + n + " and " + x);
}
3
D. Methods of the String Class
There are many useful member methods of the String class. Remember, since a String is an
object, you will use dot notation to call its methods.
.length() This method returns an integer that indicates the length of the String. The length
is how many characters are in the String. This includes spaces. To calculate the length,
just count the number of characters. In the following example, what is the value of len?
String address1 = new String(“423 Fox Chapel Road”);
int len = address1.length();
1
2
3
4
2
3
4
5
6
7
F
o
x
8
9
10
11
12
13
14
C
H
a
p
e
l
15
16
17
18
19
R
o
a
d
charAt(int index) The .charAt method returns whatever character is stored in the index
you specify in the parameter. You already know that the characters in a String are
indexed starting at 0. Let’s say you want to examine the 4th character in a String. You
could write:
String cityA = “New York”;
String cityB = “New London”;
if(cityA.charAt(4) == ‘Y’)
System.out.println(“The city is New York!”);
else
System.out.println(“The city is New London.”);
Note that .charAt returns a primitive char value, not a String.
toUpperCase() and toLowerCase() These methods will provide all the alphabetic
characters in a String to upper case or lower case as specified. The function returns the
converted String leaving the original unchanged. See below.
String mixed = “AbcDEfgHIj”;
String fixed;
fixed = mixed.toLowerCase(); //The value of fixed is “abcdefghij”
fixed = mixed.toUpperCase(); //The value of fixed is “ABCDEFGHIJ”
4
.substring(int firstIndex, int lastIndex) or
.substring(int firstIndex)
The substring method is overloaded, in that it has more than one meaning. You can
either get a piece of a String, starting at a certain index and ending at a different index
or you can get the tail-end of a String starting at whatever index and going until the end
of the String. Note, if you try to access an index that is out of range (ie. Outside the
String), you will get an error. The generic method syntax is as follows:
identifier.substring(start, stop);
Where start is the index to start at and stop is the index of the character immediately
AFTER the last character you want to collect. Here is a more concrete example:
address1.substring(0,3);
0
1
2 3
4 2 3
4 5
6 7
F o x
8 9
10
11
12
13
C h a
p
e
l
14
15
16
17
18
R
o
a
d
The method would return the sub-string “423”. This sub-string consists of the first three
characters in the string (at indices 0, 1 and 2). If you wanted the word “Chapel” to be
returned, you would have to call the method: address1.substring(8, 14). The
stop parameter is 14 because that is one index after the last character that you want.
Questions: What will the following methods return?
address1.substring(8);
address1.substring(10, 11);
address1.substring(14);
address1.substring(0, 7);
.equals(String other) You cannot use the comparison operator “==” to determine if two
Strings are identical. Instead, you must use the .equals method. This is a boolean
function that returns true if the String you are testing is equal to the other String.
Equality means it is the exact same sequence of characters (same case, spaces and special
characters, too). So, “Dog” is equal to “Dog” but “dog” is not equal to “Dog”. Which
result will be displayed in this example?
snack1 = “cookies”;
snack2 = “oreos”;
if(snack1.equals(snack2))
System.out.println(“Exactly the same snack.”);
else
System.out.println(“Not exactly the same snack.”);
5
compareTo(String other) This method tests which string comes after the other in order.
Think about the dictionary—words that appear in the front (starting with a, b, or c) are
“less than” the words that appear at the end (starting with x, y, z). Thus the word
“person” is greater than the word “people.” You may want to think about this as testing
alphabetical order, but there is a bit more to it. All uppercase letters are less than all
lowercase letters. And all numeric digits are less than all letters. Java puts letters and
numbers in order like this:
<- Least
0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ
Greatest ->
abcdefghijklmnopqrstuvwxyz
You may think this is a random way to order things, but it is based on the ASCII
(American Standard Code for Information Interchange) character set which contains 128
characters in all—this includes punctuation and special characters (like the return key on
the keyboard). The ASCII code is a subset of the Unicode character set, which Java uses.
Other programming languages like C and C++ just use ASCII but since Java was
designed with a broader usage in mind, it uses Unicode. Unicode has 65,536 different
characters and is therefore able to represent the characters of many foreign languages.
Here’s an example:
String firstString = “Leg warmers”;
String otherString = “Leg of lamb”;
int result = firstString.compareTo(otherString);
The method returns a negative integer if the first String is less than the other String.
It returns positive if the first String is greater than the other String. Which String is
greater? At the fourth index of each String, we find a different character. Which is
less, an ‘o’ or a ‘w’? “Leg of lamb” is less, so this returns a negative number.
This may seem confusing so here are some additional examples. To compare stringA and
stringB, the following would occur. Note, in this example a number in [brackets]
indicates the index number.
stringA[0] is compared to stringB[0]
stringA[1] is compared to stringB[1]
stringA[2] is compared to stringB[2]
. . . and so on and so forth until a dissimilar character is found. At the time that it finds a
dissimilar character, it stops comparing. So “turkey” is less than “turnip” because ‘k’ is
less than ‘n’. Also note that the word “turk” is less than “turkey”.
The value of each character is determined by the ASCII code (each character is
represented by an integer). So, in reality, you are comparing their numerical values.
Also recall that all capital letters appear before all lowercase letters in the ASCII code.
So, an upper case letter will always be less than a lowercase letter. Therefore, “Peanut”
is always less than “peanut”. “Peanut butter” is less than “peanut”. Finally, “peanut
butter” will always be greater than “peanut”. Finally, if two strings are identical, such as
“peanut” and “peanut”, the .compareTo function will return a 0.
6
It is not important what the exact value of the positive or negative integer is; the
significance is that you can use this in a conditional statement in your program. If the
two compared Strings are equal, the .compareTo function will return a 0. For
example:
public static void main (String[] args)
{
String animal1 = "dinosaur";
String animal2 = "Dinosaur";
int result = animal1.compareTo(animal2);
if(result > 0)
System.out.println(animal1 +“ is greater than ” +animal2);
else
System.out.println( animal2 +“ is greater than ” +animal1);
}
.indexOf(String target) Every String is indexed such that each character has an index
number. The index starts at 0, so the first index is 0. Do not confuse this with the length of
the string that starts counting at 1. Again, we start with the String object: String
address1 = new String(“423 Fox Chapel Road”);
1
2
3
4
2
3
4
5
6
7
F
o
x
8
9
10
11
12
13
14
C
h
a
p
e
l
15
16
17
18
19
R
o
a
d
This method is used to find the index of a certain substring within a string. It returns an
integer. In the example below, the method returns the number 4.
int i = address1.indexOf(“Fox”); //Finds the index of the first
//occurrence of “Fox”
Let’s say that you would like to find the location of a certain character. You can also use
the .indexOf method. For example, to find where the first instance of the letter ‘R’ is
located in the string, you would write the following code. What index value will this
method return?
int i = address1.indexOf(“R”);
If when using the .indexOf function, the desired substring is not found, a “–1” is returned. -1
is a good choice for the return value because it can never be the index of a string since they
are indexed starting at 0.
7
E. String-Returning Methods
You will of course have noticed that many string methods produce a result. For instance: int
value = myString.length(); invokes a method that counts the number of characters and
assigns the result into the desired variable. It is possible for you to program your own methods
that act similarly. These are called value-returning methods. The idea is that a method
performs an action, but also responds with certain data. The methods that you have written so
far have been headed with the keyword “void”, meaning that they perform an action but do not
evaluate to any data. Replacing the keyword “void” with a data type allows you to utilize the
method in the context of an assignment statement. Since strings are immutable, these types of
methods are commonly used to generate new strings based off an existing one.
Let’s suppose that you wanted a method that counted the number of spaces in a string. You
could write a loop that looks at each character, using .charAt(), and increment an integer
variable each time a space was encountered. Here’s how such a method will look in its entirety.
static public int countSpaces(String text)
// check each character to see if it is a space
{
int count = 0;
for (int i = 0; i < text.length(); i++)
{
if (text.charAt(count) == " ")
{
count++;
}
}
return count;
}
The “return” statement tells Java what value should be filled in for the calling code. The return
statement ends the method, so it should always appear at the end of the method. A sample
method call might be:
System.out.println(countSpaces(“The quick brown fox”));
This invokes the “countSpaces” method, substituting as a parameter the string “The quick brown
fox”. The method then processes the loop, counting the spaces. When the method reaches the
return statement, the value of “count,” in this case 3, is substituted for the method call. Valuereturning methods are used in the context of the data type that they return. Here is another
application that uses the countSpaces method.
String phrase1 = “open ses a me”;
String phrase2 = “ o p ense a me”;
if (phrase1.countSpaces() > phrase2.countSpaces())
System.out.println(“First one has more spaces”);
else
System.out.println(“Second one has more spaces”);
8
You may also want to think of value-returning methods as providing something like a reverseparameter. Parameters serve as input to the method, and the value returning is the output. There
can only be one return value, however, while there can be many parameters. Here is a method
that will receive a number and produce a String containing as many underscores as the number.
It will put a space between each underscore.
static public String toUnderscores(int size)
// size determines the number of underscores to produce
{
String text = “”;
for (int i = 0; i < size; i++)
{
text += “_ ”;
}
return text;
}
The method call System.out.println(toUnderscores(5)); will display:
“_ _ _ _ _ ” on the console.
Try one now for yourself. Write a String-returning method that will produce the reverse of a
given String. Thus “reverse” produces “esrever”.
public static String reverse(String s)
{ // design this yourself
}
Now write a method that, given a string, returns the same string except with any blank spaces
removed. Thus “op ens esa me” produces “opensesame”.
public static String eliminateSpaces(String s)
{ // design this yourself
}
9
F. Random Number Generators
Using a value-returning method, we can now create a way of producing a different word each
time our program is run. Using the random number generator is quite simple. Java has some
utilities that assist us with this. The Math class contains a Math.random() function that
produces a floating point number in the range [0.0 . . 0.999). Let’s suppose, in a simple scenario,
that we have five possible choices for a word: “academy,” “mischief,” “rewind,” “blatant,” and
“onyx.” The following method will select one of these words at random.
public static String getRandomWord()
{ // selects one of five words at random
double dNum;
int selection;
String value = “”;
dNum = Math.random() * 5; // number of possibilities
selection = (int) dNum;
// type cast
if (selection == 0)
value = “academy”;
else if (selection == 1)
value = “mischief”;
else if (selection == 2)
value = “rewind”;
else if (selection == 3)
value = “blatant”;
else if (selection == 4)
value = “onyx”;
return value;
}
Since there are a lot of if / else statements, perhaps you may want to try a “switch” structure.
The “switch” structure acts in the same way as a series of if / else when you are evaluating one
variable. Note that when evaluating each case, there is a “break” command that indicates when
that case is finished. The “break” indicates that flow of control should pass on to whatever
follows the switch structure.
public static String getRandomWord()
{ // selects one of five words at random
double dNum;
int selection;
String value = “”;
dNum = Math.random() * 5; // number of possibilities
selection = (int) dNum;
// type cast
switch (selection)
{
case 0: value = “academy”; break;
case 1: value = “mischief”; break;
case 2: value = “rewind”; break;
case 3: value = “blatant”; break;
case 4: value = “onyx”; break;
}
return value;
}
10
G. File I/O
If you want to get really elaborate, you may want to have Java read a word from a dictionary file,
thus making many possibilities. Let’s assume that we have a dictionary file on hand, called
“words.txt.” This file contains 26,870 words. The first task for the computer might be to
generate a random number from 1 to 26,870. Since each word is on a different line, we can set
up a loop that will find the correct word. All we have to do is learn commands to have the
computer look in the file.
File I/O (I/O stands for input/output) is the process of reading from (input) and writing to
(output) files. You have already worked with console I/O when you have written to the screen
and collected user input via the keyboard. There are a number of file I/O classes in Java. To
simplify them, there are a couple of classes in the “cs” package. In this course, we will use the
Infile and Outfile classes. To access them, include the following at the top of your
program:
import cs.ssa.*;
Before getting too nitty gritty with the details, ask yourself these questions: What are the possible
uses of file I/O in applications, apart from our use here? Certainly, there are times when you
want to save your data to a file, particularly in an application where a person may want to leave
off where they were and come back. What are the possible benefits of file I/O for testing and
debugging?
The notion of data flowing from a file to a program and back again is called a stream. Streams
only go one way so you can have a stream of one of the following types: input stream or output
stream. Input streams go from a file to your program (into your program) whereas an output
stream goes from your program to a file (out of your program). In order to read or write to a file,
you must open an appropriate stream to that file. Think of a stream as the pipe, which sends
information from your program to a file or vice versa.
The files that you will work with should be stored within the same directory as your programs.
Your files could be made using Textpad or Notepad. They can have names such as name.txt
(with .txt as the extension) or name.dat (with .dat as the extension—stands for data). If you are
reading data from a file, then you must create it before trying to use it. If you are writing to a
file, then the file will be created by your program and you do not need to set it up before hand.
To open a new file for reading, use the following syntax: InFile inputFile = new
Infile(“info.txt”);
You can open a different file after constructing an inputFile object if needs be. For instance, if
you must get the filename from the user, you can do the following:
InFile inputFile = new InFile();
System.out.println(“Enter the name of your file ”
+“(include file extension): ”);
String filename = Keyboard.readString();
inputFile.open (filename);
11
Methods of the InFile class that are useful to know include:
int readInt ()
double readDouble()
String readString()
String readlnString()
int readlnInt()
double readlnDouble()
void readln ()
boolean eof();
void close();
reads a single integer (note that multiple integers may be on
one line in a file)
reads a double
reads text—if more than one word is on a line in the file, then
only the first word is read
reads text, but will read the entire line regardless of spaces
reads an int and ignores the rest of the line
reads a double and ignores the rest of the line
skips to the next line
returns true if the end of file is reached
closes the file—important for output files!
For example, imagine that we are reading from a file that contains your name and age. The
following short program will read the data and print it on the screen:
import cs.ssa.*;
class FileTest
{
public static void main(String[] args)
{
String name;
int age;
Infile inputFile = new Infile();
inputFile.open("myFile.txt");
name = inputFile.readString();
age = inputFile.readInt();
inputFile.close();
System.out.println(“Your name is: ” + name);
System.out.println(“Your age is: ” + age);
}
}
As you may guess, printing data to a file will utilize the “OutFile” class. If the file name does
not exist before you open it, then it will be created. If it does exist, then its contents will be
overwritten. Some of the common methods are:
void open ()
// opens the file
void print(int/double/String) // operates on common data types
void println(int / double / String)
// prints data and goes to
// a new line
void close();
// closes the file
12
Examine quickly the code below. What do you think it achieves?
import cs.ssa.*;
import cs1.*;
class Mystery
{
public static void main(String[] args)
{
String name, password;
OutFile outputFile = new OutFile();
outputFile.open("myFile.txt");
System.out.print(“Enter name: ”);
name = Keyboard.readString();
System.out.print(“Enter password: ”);
password = Keyboard.readString();
outputFile.printLn(name);
outputFile.printLn(password);
outputFile.close();
}
}
It is very important that you always close your files after you are done using them. If you do not
close an output file, then everything you write to it may be lost when the program terminates.
The longer a file is open the greater the chance it has of being corrupted. For example, if your
computer crashes before your files are closed, you may lose data. Java protects programmers
from making errors, or exceptions, with file I/O by demanding that the programmer take care of
possible errors within the code. Errors that occur when reading from and writing to files produce
a certain type of exception called an IOException. A function that might cause this type of
error is said to throw this exception. Some exceptions you have seen in Java crash your
program, for example, reading in the wrong data type. We will learn more about exception
handling at a later time. For now, make sure you are aware that many things can go wrong with
file I/O: a file may be corrupted on the disk, it may not exist, or perhaps if the file is lengthy,
another process may change it at the same time that your program is trying to access it.
To finish, here is a method that will get a random word from an input file:
public static String getWordFromFile()
{ // selects a word from a dictionary file
double dNum;
int selection;
String value = “”;
dNum = Math.random() * 5; // number of possibilities
selection = (int) dNum;
// type cast
InFile inputFile = new InFile(“words.txt”);
for (int count = 0; count < selection; count++)
value = inputFile.readString();
inputFile.close();
return value;
}
13
String Exercises #1:
Given the following string declaration:
String location = new String (“Taj Mahal”);
What do the following function calls return?
1. location.length() returns: _______
2. location.charAt(2) returns: ________
3. location.indexOf(“Mahal”) returns: ________
4. location.equals(“India”) returns: ________
5. location.compareTo(“taj mahal”) returns: ________
6. location.toUpperCase() returns: ________
What is the final value of the text contained in location after all of the above calls are made?
Try the following exercise in comparing animals. Assume you have the following String
objects:
String
String
String
String
animal1
animal2
animal3
animal4
=
=
=
=
“dog”;
“cat”;
“Dogfish”;
“catfish”;
What would the following comparisons evaluate to? Write P for positive or N for negative or 0
for zero next to each.
____ animal1.compareTo(animal2);
____ animal3.compareTo(animal1);
____ animal2.compareTo(“cat”);
____ animal4.compareTo(animal2);
14
String Exercises #2
1. What will be output when the program segment executes?
String s1 = “palindrome”;
String s2 = new String(“radar”);
String s3 = new String (“radar”);
if (s1.equals(s2))
System.out.print(“equals ”);
else System.out.print(“not equals ”);
if (s2.equals(s3))
System.out.print(“equals”);
else System.out.print(“not equals”);
a.
b.
c.
d.
e.
equals equals
equals not equals
not equals equals
not equals not equals
Some error message.
2. What will be output when the program segment executes?
String s1 = “palindrome”;
String s2 = new String(“palindrome”);
String s3 = s1;
if (s1 == s2)
System.out.print(“equals ”);
else System.out.print(“not equals ”);
if (s1 == s3)
System.out.print(“equals”);
else System.out.print(“not equals”);
a.
b.
c.
d.
e.
equals equals
equals not equals
not equals equals
not equals not equals
Some error message.
15
3. What string value is returned by the call question(“aardvark”)?
public static String question(String s)
{ // precondition: s is not null
String t = “”;
for (int k = 0; k < s.length(); k++)
t += s.charAt(k);
return t;
}
a. aardvark
b. varkaard
c. kkkkkkkk
d. kravdraa
e. None of the above.
4 - 10. Given the following expressions:
String s1 = new String(“problem solving”);
String s2 = new String(“java”);
String s3 = new String (“great work”);
a. s1.length() returns _______
b. s3.length() returns _______
c. s1. charAt(7) returns
_______
d. s2. charAt(7) returns
_______
e. s3.compareTo(s2) returns _________________
f. s2.compareTo(s3) returns _________________
g. s3.indexOf (“work”) returns
_________________
16
AP Computer Science
Project #3: Morphology
Specifications: Most spoken languages have rules by which the nouns and/or the verbs change
their form, usually according to criteria such as person, gender, time, voice, etc. For instance,
the English language adds the suffix “-ed” to some verbs to indicate the past tense, and adds the
helping verb “has” to indicate the perfect tense.
Your task is to aid foreign students of elementary English by writing a program that will
take any noun and verb and produce proper present, past and future tense sentence forms of that
verb. You program should handle regular nouns that add –s and those that add –es. It should
handle past tense / participles that add –ed. It should also include a small database of at least 10
irregular nouns (e.g. goose  geese) and 10 irregular verbs (e.g. see  saw, seen). A sample
run-time format might be:
Welcome to the morphology program. . . .
Please enter a subject (noun) in its singular form (‘quit’ ends): dog
Please enter a verb in its base form (infinitive without “to”): walk
dog walks; dog walked; dog has walked; dogs walk; dogs walked; dogs have walked
Please enter a subject (noun) in its singular form (‘quit’ ends): watch
Please enter a verb in its base form (infinitive without “to”): run
watch runs; watch ran; watch has run; watches run; watches ran; watches have run
Please enter a subject (noun) in its singular form (‘quit’ ends): fish
Please enter a verb in its base form (infinitive without “to”): see
fish sees; fish saw; fish has seen; fish see; fish saw; fish have seen
This is only a sample—you may change your format as it suits you, so long as it is user-friendly.
Prompt the user with clear instructions about the input format, etc.
Design: Your program may use only one class, the driver program. It must be properly
subdivided into methods and it must appropriately use variables at the parameter level, local
level, and / or class level.
Implementation: You must include at least one String-returning method to handle regular word
changes. A suggestion might be:
static public String getRegularPastTense(String verb)
You also must use file I/O. I suggest that you make two data files, one of which contains
irregular noun forms and one that contains irregular verb forms. The first line of the file may
contain an integer that indicates how many lines of data that the file contains. For instance, you
may create a file called “nouns.txt” as follows:
17
5
fish fish
mouse mice
sheep sheep
ox oxen
octopus octopi
Then you may write a method called “checkIrregularNoun”:
static public String checkIrregularNoun(String noun)
// returns “null” for a non-irregular noun;
// otherwise, returns the irregular form
{
String value = null;
InFile myFile = new InFile(“nouns.txt”);
int numLines = myFile.readInt();
for (int x=0; x < numLines; x++)
{
String current = myFile.readString();
if (current.equals(noun))
value = myFile.readString(); // assign the irregular form
else myFile.readlnString(); // skip remainder of the line
}
myFile.close();
return value;
}
Testing: Test your program with a variety of inputs. When you do so, keep track of your testing.
Handle some common exceptions. In your concluding reflections, address:
- List some specific ways that the program could be expanded to handle more “natural
language” features.
- For a foreign language (you choose which one), list at least three of the morphology rules
that a similar program should handle.
18
AP Computer Science
Project #2: Mad-Libs
Specifications: Your computer will choose a short nursery rhyme and allow the user to fill in
blanks for at least four words in Mad-Libs style. Consider the example of “Humpty-dumpty.”
Your program will establish a string containing the rhyme, marking out the substitutions in
between the asterisk (‘*’) characters as such:
rhyme = “Humpty dumpty sat on a *singular noun*\nHumpty dumpty had a great
*singular noun*\nAll the king’s *plural animal* and . . ..”;
The program will scan for areas between the * marks and prompt the user to fill in those blanks.
Then the program will display the resulting nursery rhyme. Your program should scan for line
breaks and place your text accordingly.
The computer should select the nursery rhyme at random from a file. The output should be
displayed on a window, showing line breaks in the appropriate places.
Design: Your program may use only one class, the driver program, although you may also use an
extended window class to help display the final output. Your program must be properly
subdivided into methods and it must appropriately use variables at the parameter level, local
level, and / or class level.
19
Implementation: You must include at least one String-returning method. A suggestion might be:
static public String replace1Blank(String entireRhyme)
You also must use file I/O. The first line of the data file may contain an integer that indicates
how many lines of data that the file contains. For instance, you may create a file called
“rhymes.txt” as follows:
3
Humpty dumpty sat on a *singular noun*\nHumpty dumpty had a great . . .
Twinkle twinkle little *singular noun*\nHow I wonder . . .
When I was going to Saint *saint’s name*\nI met a man with *number* wives
Thus reading the file can be done as follows:
static public String getRhyme()
// chooses a rhyme at random from the file
{
String value = null;
InFile myFile = new InFile(“nouns.txt”);
int numLines = myFile.readInt();
int rhymeNumber = (int)(numLines * Math.random());
for (int x=0; x < rhymeNumber; x++)
{
value = myFile.readlnString();
}
myFile.close();
return value;
}
// get random #
Note that the line break symbols ‘\n’ will literally be stored as a backslash and an ‘n’. You will
need to scan your string and replace those two characters with the single ‘\n’ in your program.
Testing: Test your program with a variety of inputs. When you do so, keep track of your testing.
Handle some common exceptions. In your concluding reflections, address:
- Select one of your rhymes. How many characters are stored in memory when it is read
into a string variable (include white spaces)? For this rhyme, how many characters are
being stored by the program in memory at worst? This will take some counting.
Consider that strings are passed as reference parameters.
20
Download