/**
 * Various methods that demonstrate recursion. 
 * Note: these should really be static methods.
 *   @author Dave Reed 
 *   @version 11/2/17
 */
public class Recursion {
    
    /**
     * Uses looping to count the number of e's in a String.
     *   @param str the string to be counted
     *   @return the number of occurrences of 'e' in str
     */
    public int eCountLoop(String str) {
       int count = 0;
       for (int i = 0; i < str.length(); i++) {
           if (str.charAt(i) == 'e') {
               count++;
           }
        }
       return count;
    }

    /**
     * Uses recursion to count the number of e's in a String.
     *   @param str the string to be counted
     *   @return the number of occurrences of 'e' in str
     */
    public int eCountRec(String str) {
        if (str.length() == 0) {
            return 0;
        }
        else {
            int count = this.eCountRec(str.substring(1, str.length()));
            if (str.charAt(0) == 'e') {
                count++;
            }
            return count;
        }
    }
    
    /**
     * Uses looping to convert a binary String to its decimal value.
     *   @param bitString the string to be converted
     *   @return the decimal value represented by bitString
     */
    public int valueOfLoop(String bitString) {
        int total = 0;
        int posValue = 1;
        for (int i = bitString.length()-1; i >= 0; i--) {
            if (bitString.charAt(i) == '1') {
                total += posValue;
            }
            posValue *= 2;
        }
        return total;
    }

    /**
     * Uses recursion to convert a binary String to its decimal value.
     *   @param bitString the string to be converted
     *   @return the decimal value represented by bitString
     */
    public int valueOfRec(String bitString) {
        if (bitString.length() == 0) {
            return 0;
        }
        else {
            int value = 2*this.valueOfRec(bitString.substring(0, bitString.length()-1));
            if (bitString.charAt(bitString.length()-1) == '1') {
                value++;
            }
            return value;
        }
    }
    
    /**
     * Uses recursion to print all bit strings of a given length, in numerical order. 
     * Note: this uses a private helper method, which is also passed a prefix for strings to print.
     *   @param len the length of the desired bit strings
     */
    public void showBits(int len) {
        this.showBits(len, "");
    }
    
    private void showBits(int len, String prefix) {
        if (prefix.length() == len) {
            System.out.println(prefix);
        }
        else {
            this.showBits(len, prefix+"0");
            this.showBits(len, prefix+"1");
        }
    }   
}
