Comp 110 SillyString - Part I

In this problem set you will implement your own String class named SillyString. It will have many methods, including the usual suspects like size, indexOf, and equals. It will also have some methods standard Strings do not. Coming up with the algorithm for each of these methods is like solving a little puzzle.

This problem set will be broken into two parts over the next week and a half. It is structured to increase in difficulty as you progress through it. It is on a similar scope of time/difficulty as Drop, Stop, or Roll was so we encourage you to start early.

Part 1 - 200 Points - Due Tuesday 2/21 at 11:59pm
Part 2 - 300 Points - Due Monday 2/27 at 11:59pm

Through implementing and testing the SillyString class, you will gain practice with for loops and arrays while learning the mechanics of classes, objects, method calls, and fields.

PSA: In order to receive help from UTAs on this assignment, you must be able to demonstrate test cases for the methods you are working on in TestRunner.

Warning: For this problem set you are prohibited from taking shortcuts by using of any of Java's built-in classes (especially String) or methods. You can certainly pass the autograder doing this, but we will assign a score of 0 points to both parts when we take our manual pass on everyone's code.

Importing the Project

To get started, follow these steps to install the Support Code.

  1. Start Eclipse
  2. Select and copy the following link to your clipboard:
  3. Click the File menu
  4. Select "Import"
  5. Double click "Git" to expand the folder
  6. Double click "Projects from Git"
  7. Double click "Clone URI".
  8. The "URI" field should already have the URI you copied in Step 2 in it. If it does not, paste the URI from step 2 in it. Click next.
  9. Ensure there's a check beside of "master". Click next.
  10. In the "Directory" field, click "Browse". Navigate to your documents folder and select the COMP110 folder. Click next.
  11. Ensure "Import existing Eclipse projects" is selected. Click next.
  12. Ensure the correct Problem Set folder is checked. Click finish.

Part 0. Understanding the TestRunner

In this problem set we are providing to you a SillyString class with each of the methods you will need to implement already declared. The method definitions are all incorrect and, essentially, blank. Your mission is to come up with working implementations for each method definition.

To test your method definitions you will need to write code in the TestRunner class that calls the methods you're implementing in SillyString with different inputs. In this write-up, we're giving you some sample ideas for values to test with, but you should try to come up with your own test cases as well.

We are provided sample testing code for the size, charAt, and countVowels methods. You should set up similar tests as you implement each of your other methods. In order to receive help from UTAs on this problem set you must be able to demonstrate that you are actually testing it from within your code.

Getting Started with PS3

Part 1. Fundamentals

Section 1. Basic Methods

1.1 int size()

Return the number of characters the SillyString contains. Hint: begin by looking at the _chars field of SillyString in the stencil code and understanding how it is initialized in the constructor. Note that _chars is an array of characters. How do you get the number of elements an array contains? Return that number. Also note that you can use the array field length.

SillyString empty = new SillyString("");
empty.size() -> 0
SillyString letters = new SillyString("abc");
letters.size() -> 3

1.2 char charAt(int index)

Return the character of the SillyString held at the given index. Note: you can assume the index is valid.

SillyString letters = new SillyString("abc");
letters.charAt(0) -> 'a'
letters.charAt(1) -> 'b'
letters.charAt(2) -> 'c'

1.3 int countVowels()

Return the number of occurrences of the vowels in the SillyString. Only count the letters a, e, i, o, u.

SillyString letters = new SillyString("abc");
letters.countVowels() -> 1
SillyString consonants = new SillyString("bcdy");
consonants.countVowels() -> 0
SillyString vowels = new SillyString("aeiou");
vowels.countVowels() -> 5

1.4 int count(char c)

Return the number of occurrences of the character c in the SillyString.

SillyString letters = new SillyString("abbccc");
letters.count('a') -> 1
letters.count('b') -> 2
letters.count('c') -> 3
letters.count('d') -> 0

1.5 int indexOf(char c, int start)

Return the index of the first occurrences of the character parameter c (double emphasis: the parameter named c, not the literal character 'c') in the SillyString starting from index start. Return -1 if the character c cannot be found after the start index.

SillyString phrase = new SillyString("the quick brown fox");
phrase.indexOf('z', 0)  -> -1
phrase.indexOf('e', 0)  -> 2
phrase.indexOf('e', 2)  -> 2
phrase.indexOf('e', 3)  -> -1
phrase.indexOf('o', 0)  -> 12
phrase.indexOf('o', 13) -> 17

Section 2. Boolean Tests

2.1 boolean contains(char c)

Return true if the SillyString contains the character c, false otherwise. Hint: consider how you might make use of the indexOf method in section 1.

SillyString phrase = new SillyString("the quick brown fox");
phrase.contains('z')  -> false
phrase.contains('e')  -> true
phrase.contains('t')  -> true

2.2 boolean every(char c)

Return true if every character in the SillyString is the character c, false otherwise. This video walks through a very similar problem with a different kind of array that should help give you some ideas if you are stuck.

SillyString phrase = new SillyString("the quick brown fox");
phrase.every('a')  -> false
SillyString aBunchOfZs = new SillyString("zzzzzz");
aBunchOfZs.every('a') -> false
aBunchOfZs.every('z') -> true
SillyString almost = new SillyString("aaaaaz");
almost.every('a') -> false
almost.every('z') -> false

2.3 boolean endsWith(char[] suffix)

Return true if the SillyString ends with the exact same characters as given in the character array suffix parameter, false otherwise.

SillyString phrase = new SillyString("the quick brown fox");
phrase.endsWith(new char[] { 'a', 'b', 'c' })  -> false
phrase.endsWith(new char[] { 'f', 'o', 'x' }) -> true

2.4 boolean isPalindrome()

Return true if the SillyString is a palindrome, false otherwise. Odd-length palindromes are accepted.

SillyString phrase = new SillyString("the quick brown fox");
phrase.isPalindrome() -> false
SillyString letters = new SillyString("aba");
letters.isPalindrome() -> true
SillyString numbers = new SillyString("1221");
numbers.isPalindrome() -> true

Section 3. Utility Methods

3.1 boolean equals(SillyString other)

Return true if the SillyString is the same size and contains the exact same characters as the other SillyString. Note that from within the equals method you can call methods on the other SillyString, like other.charAt(0).

SillyString word = new SillyString("the");
SillyString letters = new SillyString("abc");
SillyString theWordThe = new SillyString("the");
SillyString phrase = new SillyString("the quick brown fox");
word.equals(letters)    -> false
word.equals(theWordThe) -> true
word.equals(phrase)     -> false
word.equals(word)       -> true

3.2 SillyString clone()

Return a clone of the SillyString object. Cloning is a strange concept to early programmers. The idea is you will make a copy of all fields and construct a new SillyString object from those copies.

Helpful hint: You will need to be aware of an alternate constructor of the SillyString class provided for you in the stencil code. You can construct a SillyString in two ways:

SillyString a = new SillyString("abc"); // Construct via String
char[] letters = new char[] { 'a', 'b', 'c' };
SillyString b = new SillyString(letters); // Construct via char[]

Your job: 

1. Declare a new char array variable and initialize it to a new array that can hold the same number of elements as the SillyString.

2. Copy all of the chars from the _chars field to the array you setup in step 1.

3. Construct a new SillyString instance using the copied char array. See the constructor example above for reference. Return this instance and you're done with part 1!

SillyString word = new SillyString("the");
SillyString clone = word.clone();
word.equals(clone)                  -> true
word == clone                       -> false
word.getChars() == clone.getChars() -> false

Part 2. Advanced Methods

Part 2 instructions here.

Submission Instructions

Like the last problem set, this one will be broken into two submissions.

Submissions will open shortly. In the meantime, you should test your work by coming up with cases in the TestRunner. For this problem set you should aim to get close to full credit on your first submission or two because you've thought of and tested good cases in your TestRunner code.