/** A class of static recursive functions on Strings. */ public class StringRecursion { // IN THIS LECTURE, all String parameters are not null. /** Yields" length of s */ public static int len(String s) { //System.out.println("s is: \"" + s + "\""); if (s.isEmpty()) { return 0; } // { s has at least one character} return 1 + len(s.substring(1)); } /** Yields: number of 'e's in s */ public static int numEs(String s) { //System.out.println("s is: \"" + s + "\""); if (s.isEmpty()) { return 0; } // { s has at least one character} // return (number of 'e's in s[0]) + (number of 'e's in s[1..]) return (s.charAt(0) == 'e' ? 1 : 0) + numEs(s.substring(1)); } /** Yields: s but with blanks removed */ public static String deblank(String s) { if (s.isEmpty()) { return s; } if (s.charAt(0) == ' ') { return deblank(s.substring(1)); } return s.charAt(0) + deblank(s.substring(1)); } /** Yields: s but with everything that is not a letter removed */ public static String depunct(String s) { if (s.isEmpty()) { return s; } if (!Character.isLetter(s.charAt(0))) { return depunct(s.substring(1)); } return s.charAt(0) + depunct(s.substring(1)); } /** Yields: "the characters c and d differ only in case, if at all" */ private static boolean equalIgnoreCase(char c, char d) { return Character.toUpperCase(c) == Character.toUpperCase(d); } /** Yields: "s is a palindrome" * There are two ways to define a palindrome: * 1. s is a palindrome if it reads the same backward and forward. * 2. s is a palindrome if either * (1) its length is <= 1 OR * (2) its first and last chars are the same and the string * between them is a palindrome. * Letters that differ only in case are considered to match. */ public static boolean isPal(String s) { //System.out.println("s is: \"" + s + "\""); if (s.length() < 2) return true; // { s has at least 2 characters } // return (first and last chars match) && (inner substring is pal.) return equalIgnoreCase(s.charAt(0), s.charAt(s.length()-1)) && isPal(s.substring(1,s.length()-1)); } /** Yields: "s is a palindrome" * Comparison is not case-sensitive. */ public static boolean isPal2(String s) { return s.equalsIgnoreCase(reverse(s)); } /** Yields: "s is a palindrome if you pay attention only to the letters" * Case and any non-letter characters are ignored. */ public static boolean isPalLoosely(String s) { return isPal(depunct(s)); } /** Yields: s with its characters in reverse order */ public static String reverse(String s) { if (s.length() < 2) { return s; } // { s has at least 2 chars } return reverse(s.substring(1)) + s.charAt(0); } }