2.3.2 Write a recursive function that takes an integer n as its argument and returns
ln (n !).
public class Lnn{
public static double lnn(int n){
if(n==1){
return 0.0;
}
return lnn(n-1)+Math.log(n)/Math.log(Math.E);
}
public static void main(String[] args){
int n = Integer.parseInt(args[0]);
System.out.println(lnn(n));
}
}
2.3.15 Binary representation. Write a program that takes a positive integer n (in decimal) as a command-line argument and prints its binary representation. Recall, in PROGRAM 1.3.7, that we used the method of subtracting out powers of 2. Now, use the following simpler method: repeatedly divide 2 into n and read the remainders backward. First, write a while loop to carry out this computation and print the bits in the wrong order. Then, use recursion to print the bits in the correct order.
public class IntegerToBinary {
public static void convert(int n) {
if (n == 0) return;
convert(n / 2);
StdOut.print(n % 2);
}
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
convert(n);
StdOut.println();
}
}
IntegerToBinary.java (princeton.edu)
2.3.17 Permutations. Write a program Permutations that takes an integer command-line argument n and prints all n ! permutations of the n letters starting at a (assume that n is no greater than 26). A permutation of n elements is one of the n ! possible orderings of the elements. As an example, when n = 3, you should get the following output (but do not worry about the order in which you enumerate them):
bca cba cab acb bac abc
public class Permutations {
// print n! permutation of the characters of the string s (in order)
public static void perm1(String s) { perm1("", s); }
private static void perm1(String prefix, String s) {
int n = s.length();
if (n == 0) StdOut.println(prefix);
else {
for (int i = 0; i < n; i++)
perm1(prefix + s.charAt(i), s.substring(0, i) + s.substring(i+1, n));
}
}
// print n! permutation of the elements of array a (not in order)
public static void perm2(String s) {
int n = s.length();
char[] a = new char[n];
for (int i = 0; i < n; i++)
a[i] = s.charAt(i);
perm2(a, n);
}
private static void perm2(char[] a, int n) {
if (n == 1) {
StdOut.println(new String(a));
return;
}
for (int i = 0; i < n; i++) {
swap(a, i, n-1);
perm2(a, n-1);
swap(a, i, n-1);
}
}
// swap the characters at indices i and j
private static void swap(char[] a, int i, int j) {
char c = a[i];
a[i] = a[j];
a[j] = c;
}
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
String elements = alphabet.substring(0, n);
perm1(elements);
StdOut.println();
perm2(elements);
}
}
Permutations.java (princeton.edu)
2.3.18 Permutations of size k. Modify Permutations from the previous exercise so that it takes two command-line arguments n and k, and prints all P(n, k) =n! / (n-k)! permutations that contain exactly k of the n elements. Below is the desired output when k = 2 and n = 4 (again, do not worry about the order):
ab ac ad ba bc bd ca cb cd da db dc
public class PermutationsK {
public static void choose(char[] a, int k) {
enumerate(a, a.length, k);
}
private static void enumerate(char[] a, int n, int k) {
if (k == 0) {
for (int i = n; i < a.length; i++)
StdOut.print(a[i]);
StdOut.println();
return;
}
for (int i = 0; i < n; i++) {
swap(a, i, n-1);
enumerate(a, n-1, k-1);
swap(a, i, n-1);
}
}
// helper function that swaps a[i] and a[j]
public static void swap(char[] a, int i, int j) {
char temp = a[i];
a[i] = a[j];
a[j] = temp;
}
// sample client
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int k = Integer.parseInt(args[1]);
String elements = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
char[] a = new char[n];
for (int i = 0; i < n; i++)
a[i] = elements.charAt(i);
choose(a, k);
}
}
PermutationsK.java (princeton.edu)
2.3.19 Combinations. Write a program Combinations that takes an integer command-line argument n and prints all 2n combinations of any size. A combination is a subset of the n elements, independent of order. As an example, when n = 3, you should get the following output:
a ab abc ac b bc c
Note that your program needs to print the empty string (subset of size 0).
public class Combinations {
// print all subsets of the characters in s
public static void comb1(String s) { comb1("", s); }
// print all subsets of the remaining elements, with given prefix
private static void comb1(String prefix, String s) {
if (s.length() > 0) {
StdOut.println(prefix + s.charAt(0));
comb1(prefix + s.charAt(0), s.substring(1));
comb1(prefix, s.substring(1));
}
}
// alternate implementation
public static void comb2(String s) { comb2("", s); }
private static void comb2(String prefix, String s) {
StdOut.println(prefix);
for (int i = 0; i < s.length(); i++)
comb2(prefix + s.charAt(i), s.substring(i + 1));
}
// read in N from command line, and print all subsets among N elements
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
String elements = alphabet.substring(0, n);
// using first implementation
comb1(elements);
StdOut.println();
// using second implementation
comb2(elements);
StdOut.println();
}
}
Combinations.java (princeton.edu)
2.3.20 Combinations of size k. Modify Combinations from the previous exercise so that it takes two integer command-line arguments n and k, and prints all C(n, k) = n ! / (k !(n-k)!) combinations of size k. For example, when n = 5 and k = 3, you should get the following output:
abc abd abe acd ace ade bcd bce bde cd
public class CombinationsK {
// print all subsets that take k of the remaining elements, with given prefix
public static void comb1(String s, int k) { comb1(s, "", k); }
private static void comb1(String s, String prefix, int k) {
if (s.length() < k) return;
else if (k == 0) StdOut.println(prefix);
else {
comb1(s.substring(1), prefix + s.charAt(0), k-1);
comb1(s.substring(1), prefix, k);
}
}
// print all subsets that take k of the remaining elements, with given prefix
public static void comb2(String s, int k) { comb2(s, "", k); }
private static void comb2(String s, String prefix, int k) {
if (k == 0) StdOut.println(prefix);
else {
for (int i = 0; i < s.length(); i++)
comb2(s.substring(i + 1), prefix + s.charAt(i), k-1);
}
}
// reads in two integer command-line arguments n and k and
// print all subsets of size k from n elements
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int k = Integer.parseInt(args[1]);
String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
String elements = alphabet.substring(0, n);
comb1(elements, k);
StdOut.println();
comb2(elements, k);
}
}