Computer Science APEA 15-100, Summer 2009
Homework 6
Due:  Thu 9-Jul-2009 at 8:59am (email copy only)
(no late submissions accepted).


Read these instructions first!


  1. Reading
  2. Finish Lab 6
  3. ch5Exercises
  4. pi(n) -- The Prime Counting Function
  5. isPalindrome
  6. mostFrequentLetter
  7. Bonus/Optional:  isPalindromeBonus (A better isPalindrome)
  8. Bonus/Optional:  Empirically Confirming the Prime Number Theorem

  1. Reading
    Begin reading the material for the next quiz, which covers 3.1, 3.2, 3.4, 3.5, 3.6 (just printf), 3.8, 5.1, 5,2, 5.3, 5.5, 5.7, and 5.8.  You will have time tomorrow and over the weekend to finish this reading.
     
  2. Finish Lab 6
    Finish all the examples from lab 6.  Include the solutions in your submission, all in one file named Lab6.java.  Note: the lab collaboration policy continues to apply to the lab problems.  So you can collaborate at will to solve these problems.  This only applies to the lab problems -- all other problems in this assignment are subject to the usual homework collaboration policy.
     
  3. ch5Exercises
    Do the following Exercises from Chapter 5 (pp 281-283):
    Exercises 5.1,  5.2,  5.3,  5.4,  5.5
     
  4. pi(n) -- The Prime Counting Function
    Write the following method:
       public static int pi(int n)
    This method, which has nothing to do with the constant π, takes a number n and returns the number of prime numbers less than or equal to n.  This is a very important function in mathematics.  For your test method (which you must write!), you will want to use some known values for pi(n), which you may obtain from the Wikipedia page on the Prime Counting Function (you may skip the heavy-duty math and look at the first two columns in this table).  This method should use the isPrime method we wrote in class.
     
  5. isPalindrome
    Write the following method:
       public static boolean isPalindrome(String s)
    This method takes a possibly-null string and returns true if the given string is a palindrome, that is, the same forwards as backwards, and false otherwise.  The method returns false if the string is null, but true if it is empty (why?).  Note that this version checks non-alphabetic characters, too, so "a ba" is not a palindrome. Here is a test method for you:
      public static void testIsPalindrome() {
        System.out.print("Testing isPalindrome... ");
        assert(isPalindrome("a") == true);
        assert(isPalindrome("ab") == false);
        assert(isPalindrome("a ba") == false);
        assert(isPalindrome("bab") == true);
        assert(isPalindrome("baab") == true);
        assert(isPalindrome("b,ab") == false);
        assert(isPalindrome("b,a,b") == true);
        assert(isPalindrome("Madam, I'm Adam") == false);
        assert(isPalindrome("madamimadam") == true);
        assert(isPalindrome("") == true);
        assert(isPalindrome(null) == false);
        System.out.println("Passed all tests!");
      }

    Hint:  For this and other problems in this assignment, you may need to determine the length of a string.  This is done with the length method, as the following code demonstrates:

    class MyCode {
      public static void main(String[] args) {
        String s = "Carpe diem";
        int n = s.length();
        System.out.println(n);  // prints 10
      }
    }  
  6. mostFrequentLetter
    Write the following method:
       public static char mostFrequentLetter(String s)
    This method takes a string and returns the most-frequently-occurring letter in the given string, with ties going to the first letter alphabetically, and ignoring case, so 'a' and 'A' both count as an 'A'.  Also, the method's result is always an uppercase letter. If the string is empty or null or does not contain any letters, the result should be the char value 0 (see the test code).  Here is a test method for you:
      public static void testMostFrequentLetter() {
        System.out.print("Testing mostFrequentLetter... ");
        assert(mostFrequentLetter("STUV") == 'S');
        assert(mostFrequentLetter("tuvw") == 'T');
        assert(mostFrequentLetter("UTSR") == 'R');
        assert(mostFrequentLetter("This is a test") == 'S');
        assert(mostFrequentLetter("") == ((char)0));
        assert(mostFrequentLetter(null) == ((char)0));
        System.out.println("Passed all tests!");
      }

    Helper Method:  In writing your mostFrequentLetter method, you must use top-down design, including a well-conceived helper method.  What should it do?  Well, it would be handy if you had a method that took 2 parameters, a String and char, and returned the number of times (that is, the frequency) the given char occurs in the given String.  With this helper method, you could write mostFrequentLetter by checking frequency of each char between 'A' and 'Z' and selecting the largest one.  Note that you must also include a test method for your helper method (and you will be graded, in part, on the quality of the test cases in that test method).
       

  7. Bonus/Optional:  isPalindromeBonus (A better isPalindrome)
    Write the following method:
       public static boolean isPalindromeBonus(String s)
    This method tests for palindromes, just like the non-bonus version that was assigned, only here the matching algorithm only considers alphabetic characters, and then without regard to case.  Non-alphabetic characters are simply skipped while matching.  So, for example, the following IS a palindrome:
        "Madam, I'm Adam!"

    Note:  One way to solve this would be to first construct a new String composed only of the alphabetic characters in the given string, then call the simpler isPalindrome method on that string. You may not solve this problem this way!!   (Not even for partial credit.)  It is too inefficient, and it also sidesteps the logic that we want you to deal with.

    Instead, you must solve this by having one index increase from the left end of the string and the other decrease from the right end, with each index skipping non-alphabetic characters. Think about it...

    Here is a test method for you:
      public static void testIsPalindromeBonus() {
        System.out.print("Testing isPalindromeBonus... ");
        assert(isPalindromeBonus("a") == true);
        assert(isPalindromeBonus("ab") == false);
        assert(isPalindromeBonus("a ba") == true); // false for isPalindrome
        assert(isPalindromeBonus("bab") == true);
        assert(isPalindromeBonus("b,ab") == true); // false for isPalindrome
        assert(isPalindromeBonus("b,abb") == false);
        assert(isPalindromeBonus("b,a,b") == true);
        assert(isPalindromeBonus("Madam, I'm Adam") == true); // false for isPalindrome
        assert(isPalindromeBonus("madamimadam") == true);
        assert(isPalindromeBonus("") == true);
        assert(isPalindromeBonus(null) == false);
        System.out.println("Passed all tests!");
      }
  8. Bonus/Optional:  Empirically Confirming the Prime Number Theorem
    The Prime Number Theorem states:
        
    Where π(x) is the Prime Counting Function which you wrote above.  Write some Java code which empirically confirms that the Prime Number Theorem appears to be true.  You will want to use the Math.log method.  For full credit, your code must at least suggest that the value is not only close to 1, but that it seems to converge to 1.

Carpe diem!