Commit c76cfccf authored by Torstein's avatar Torstein

Koden fra forelesning om rekursjon tirsdag 15. mars

parent cc367136
......@@ -9,10 +9,11 @@ import inf101v16f12.graph.TreeNode;
public class TreeGenerator extends AbstractGenerator<Tree> {
public static final int MAXDEPTH = 10;
public static final int MAXBRANCH = 5;
private int nextName = 0;
@Override
public Tree generate(Random r) {
Tree t = new Tree();
Tree t = new Tree(String.valueOf(nextName++));
int cdepth = 1 + r.nextInt(MAXDEPTH);
generateRec(cdepth, t.getRoot(), r);
return t;
......@@ -24,7 +25,7 @@ public class TreeGenerator extends AbstractGenerator<Tree> {
int childCount = 1 + r.nextInt(MAXBRANCH);
for (int i=0; i<childCount; i++) {
int cdepth = r.nextInt(depth);
TreeNode child = root.newChild();
TreeNode child = root.newChild(String.valueOf(nextName++));
generateRec(cdepth, child, r);
}
......@@ -37,7 +38,7 @@ public class TreeGenerator extends AbstractGenerator<Tree> {
* @return
*/
public Tree binary(int depth) {
Tree t = new Tree();
Tree t = new Tree(String.valueOf(nextName++));
binaryRec(depth, t.getRoot());
return t;
}
......@@ -46,7 +47,7 @@ public class TreeGenerator extends AbstractGenerator<Tree> {
if (depth <= 0)
return;
for (int i=0; i<2; i++)
root.newChild();
root.newChild(String.valueOf(nextName++));
for (TreeNode child : root.getChildren())
binaryRec(depth-1, child);
}
......@@ -71,7 +72,7 @@ public class TreeGenerator extends AbstractGenerator<Tree> {
*/
@SuppressWarnings("unused")
public Tree example() {
Tree t = new Tree();
Tree t = new Tree("r");
TreeNode root = t.getRoot();
TreeNode a = root.newChild("a");
TreeNode b = root.newChild("b");
......
package inf101v16f12.graph;
import java.util.ArrayList;
import java.util.List;
public class Tree {
private TreeNode root = new TreeNode(null, "r");
private final TreeNode root;
public Tree(String rootName) {
this.root = new TreeNode(null, rootName);
}
/**
* @return the root
*/
......@@ -19,17 +21,8 @@ public class Tree {
*/
@Override
public String toString() {
String s = "Tree [\n";
s = toStringRec(s, 1, this.root) + "]";
return s;
}
private static String toStringRec(String s, int indent, TreeNode root) {
s = s + new String(new char[indent*2]).replace("\0", " ");
s = s + root.getName() + "\n";
for (TreeNode child : root.getChildren())
s = toStringRec(s, indent+1, child);
return s;
// TODO
return null;
}
......@@ -38,15 +31,8 @@ public class Tree {
* @return the depth of the tree
*/
public int getDepth() {
return depthRec(this.root);
}
private static int depthRec(TreeNode root) {
int max = -1;
for (TreeNode child : root.getChildren()) {
max = Math.max(max, depthRec(child));
}
return 1 + max;
// TODO
return 0;
}
......@@ -55,36 +41,20 @@ public class Tree {
* @return the leaves of the tree
*/
public List<TreeNode> getLeaves() {
List<TreeNode> leaves = new ArrayList<TreeNode> ();
getLeavesRec(leaves, this.root);
return leaves;
// TODO
return null;
}
private static void getLeavesRec(List<TreeNode> leaves, TreeNode root) {
if (root.getChildren().isEmpty())
leaves.add(root);
else {
for (TreeNode child : root.getChildren())
getLeavesRec(leaves, child);
}
}
/**
*
* @return the maximum degree of any node in the tree
*/
public int maxDeg() {
return maxDegRec(this.root);
}
private static int maxDegRec(TreeNode root) {
int deg = root.getChildren().size();
for (TreeNode child : root.getChildren())
deg = Math.max(deg, 1+maxDegRec(child));
return deg;
// TODO
return 0;
}
/**
* Will return a node with the matching name, if found.
* If there is more than one node with the given name,
......@@ -94,17 +64,7 @@ public class Tree {
* @return a node matching the name given
*/
public TreeNode findNode(String name) {
return findNode(name, this.root);
}
private TreeNode findNode(String name, TreeNode root) {
if (root.getName().equals(name))
return root;
for (TreeNode child : root.getChildren()) {
TreeNode hit = findNode(name, child);
if (hit != null)
return hit;
}
// TODO
return null;
}
......
......@@ -4,28 +4,15 @@ import java.util.ArrayList;
import java.util.List;
public class TreeNode {
private static int nextName = 0;
private final int id = nextName++;
private final String name;
private final TreeNode parent;
private final List<TreeNode> children = new ArrayList<TreeNode>();
public TreeNode(TreeNode parent) {
this.parent = parent;
this.name = String.valueOf(this.id);
}
public TreeNode(TreeNode parent, String name) {
this.parent = parent;
this.name = name;
}
public TreeNode newChild() {
TreeNode child = new TreeNode(this);
this.children.add(child);
return child;
}
public TreeNode newChild(String name) {
TreeNode child = new TreeNode(this, name);
this.children.add(child);
......@@ -53,13 +40,6 @@ public class TreeNode {
return this.name;
}
/**
* @return the name
*/
public int getId() {
return this.id;
}
/**
* @return the parent
*/
......
......@@ -14,9 +14,9 @@ public class Basic {
if (s.length() <= 1)
return true;
// Recursive case
char first = s.charAt(0);
char last = s.charAt(s.length()-1);
return (first == last && isPalindrome(s.substring(1, s.length()-1)));
if (s.charAt(0) != s.charAt(s.length()-1))
return false;
return isPalindrome(s.substring(1, s.length()-1));
}
......@@ -34,6 +34,7 @@ public class Basic {
return reverse(s.substring(1)) + s.charAt(0);
}
/**
* Returns the sum of the digits (decimal notation)
*
......@@ -41,14 +42,8 @@ public class Basic {
* @return sum of digits of num
*/
public static int sumOfDigits(int num) {
// Base case
if (num == 0)
return 0;
// Recursive cases
else if (num < 0)
return sumOfDigits(Math.abs(num));
else
return num%10 + sumOfDigits(num/10);
// TODO
return 0;
}
}
......@@ -11,22 +11,11 @@ public class FileSystem {
public static void listAll(File path) {
// Always: print Path
System.out.println(path.getAbsoluteFile());
// Base case: path is a file, so do not recurse
if (!path.isDirectory()) {
return;
}
// Recursive case
else {
for (File child : path.listFiles())
listAll(child);
}
// TODO
}
public static void biggestFile(String path) {
//TODO
// TODO
}
}
package inf101v16f12.recursion;
import java.util.ArrayList;
import java.util.List;
public class GameSolvers {
......@@ -33,22 +32,25 @@ public class GameSolvers {
"Moving a Tower of Hanoi of height " + n + " from a to c");
return move(n, "a", "b", "c");
}
public static int move(int n, String from, String via, String to) {
// Base case
if (n == 1) {
System.out.println("" + n + ": " + from + " -> " + to);
System.out.println("1: "+from+" -> "+to);
return 1;
}
int moves = 0;
moves += move(n - 1, from, to, via); // Move top of stack away
moves += 1; // Move the biggest piece to "to"
System.out.println("" + n + ": " + from + " -> " + to);
moves += move(n - 1, via, from, to); // Move top stack back again
return moves;
// Recursive case
int steps = 0;
steps += move(n-1, from, to, via);
System.out.println(n+": "+from+" -> "+to);
steps += 1;
steps += move(n-1, via, from, to);
return steps;
}
/**
* Yields a solution to the nQueens problem of placing n queens of an n by n
* Yields a solution to the nQueens problem of placing n queens on an n by n
* chess board such that none of the queens can strike each other. A queen
* can strike another queen if they share the same row, column or diagonal
* on the board.
......@@ -65,44 +67,11 @@ public class GameSolvers {
* @return a list representing placements of queens
*/
public static List<Integer> nQueens(int n) {
List<Integer> placed = new ArrayList<Integer>();
return nQueens(n, placed);
}
private static List<Integer> nQueens(int n, List<Integer> placed) {
// Base cases
if (causeConflict(placed))
return null;
if (n == placed.size())
return placed;
// Recursive search
for (int row = 0; row < n; row++) {
placed.add(row);
List<Integer> res = nQueens(n, placed);
if (res != null)
return res;
placed.remove(placed.size() - 1);
}
// TODO
return null;
}
private static boolean causeConflict(List<Integer> queens) {
if (queens.isEmpty())
return false;
int col = queens.size() - 1;
int row = queens.get(col);
for (int col2 = 0; col2 < col; col2++) {
int row2 = queens.get(col2);
if (row2 == row)
return true;
int drow = Math.abs(row - row2);
int dcol = col - col2;
if (drow == dcol)
return true;
}
return false;
}
// N-queens
// Subset sum
// Knapsack
// Edit distance
......
......@@ -18,11 +18,25 @@ public class MathFunctions {
* @return the n'th Fibonacci number
*/
public static int fib(int n) {
// Base case
if (n == 0)
return 0;
if (n == 1)
return 1;
return fib(n - 1) + fib(n - 2);
// Recursive case
return fib(n-1) + fib(n-2);
}
public static int fib2(int n) {
int prev = 0;
int next = 1;
for (int i=0; i<n; i++) {
int tmp = next;
next = next + prev;
prev = tmp;
}
return prev;
}
/**
......@@ -36,7 +50,8 @@ public class MathFunctions {
* @return The factorial of n, n! = 1*2*3...*n
*/
public static int factorial(int n) {
return (n == 0) ? 1 : n * factorial(n - 1);
// TODO
return 0;
}
/**
......@@ -49,7 +64,8 @@ public class MathFunctions {
* @return n^k
*/
public static int power(int b, int e) {
return (e == 0) ? 1 : b * power(b, e - 1);
// TODO
return 0;
}
/**
......@@ -142,9 +158,8 @@ public class MathFunctions {
* @return the greatest common divisor of x and y
*/
public static int gcd(int x, int y) {
if (y == 0)
return x;
return gcd(y, x % y);
// TODO
return 0;
}
}
......@@ -2,36 +2,95 @@ package inf101v16f12.recursion;
public class Sorting {
// Insertion sort
// Merge sort
/**
* Merge sort
* @param lst list that will be sorted
* Sorts the list using the selection sort algorithm
*
* @param lst
*/
public static void selectionSort(int[] lst) {
int[] res = new int[lst.length];
boolean[] seen = new boolean[lst.length];
// For each position in the new list, find smallest available to use
for (int k = 0; k < lst.length; k++) {
res[k] = getMin(lst, seen);
}
// Move back to original list
for (int k = 0; k < lst.length; k++) {
lst[k] = res[k];
}
}
public static int getMin(int[] lst, boolean[] seen) {
int minVal = Integer.MAX_VALUE;
int minIdx = -1;
for (int i = 0; i < lst.length; i++) {
if (!seen[i] && lst[i] < minVal) {
minIdx = i;
minVal = lst[i];
}
}
seen[minIdx] = true;
return minVal;
}
/**
* Sorts the list destructively using merge sort algorithm
*
* @param lst
* list that will be sorted
*/
public static void mergeSort(int[] lst) {
int[] tmp = new int[lst.length];
mergeSort(lst, tmp, 0, lst.length);
}
private static void mergeSort(int[] lst, int[] tmp, int left, int right) {
public static void mergeSort(int[] lst, int[] tmp, int left, int right){
// Base case
if (right - left <= 1)
if (right-left <= 1)
return;
// Recursive case
int center = left + (right-left)/2;
int center = (left + right)/2;
mergeSort(lst, tmp, left, center);
mergeSort(lst, tmp, center, right);
merge(lst, tmp, left, center, right);
}
private static void merge(int[] lst, int[] tmp, int first, int center,
int last) {
// TODO Auto-generated method stub
private static void merge(int[] lst, int[] tmp, int left, int center,
int right) {
// Plaiting
int li = left;
int ri = center;
int k = left;
// Plaiting Case 1: Both li and ri in range
while (li < center && ri < right) {
if (lst[li] < lst[ri])
tmp[k++] = lst[li++];
else
tmp[k++] = lst[ri++];
}
// Plaiting Case 2: Only li in range
while (li < center) {
tmp[k++] = lst[li++];
}
// Plaiting Case 3: Only ir in range
while (ri < right) { /// Her var feilen! (jeg skrev center, ikke right)
tmp[k++] = lst[ri++];
}
// Move back to lst
for (int i=left; i<right; i++) {
lst[i] = tmp[i];
}
}
/**
* Sorts the list destructively using the quick sort algorithm
*
* @param lst
*/
public static void quickSort(int[] lst) {
// TODO
}
// Quick sort
}
......@@ -14,7 +14,7 @@ public class TestGameSolvers {
}
@Test
//@Test
public void testNQueens() {
System.out.println("n=1: "+GameSolvers.nQueens(1));
System.out.println("n=2: "+GameSolvers.nQueens(2));
......
package inf101v16f12.tests;
import static org.junit.Assert.*;
import org.junit.Test;
import inf101v16f12.recursion.MathFunctions;
public class TestMathFunctions {
@Test
public void testFib() {
assertEquals(0, MathFunctions.fib(0));
assertEquals(1, MathFunctions.fib(1));
assertEquals(5, MathFunctions.fib(5));
assertEquals(8, MathFunctions.fib(6));
}
@Test
public void testFib2() {
assertEquals(0, MathFunctions.fib2(0));
assertEquals(1, MathFunctions.fib2(1));
assertEquals(5, MathFunctions.fib2(5));
assertEquals(8, MathFunctions.fib2(6));
MathFunctions.fib2(1000);
}
}
......@@ -3,23 +3,70 @@ package inf101v16f12.tests;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Random;
import org.junit.Test;
import inf101v16f12.recursion.Sorting;
public class TestSorting {
public static final int TESTS = 5;
public static final int LISTLEN = 750*1;
private static final Random r = new Random();
@Test
public void testMergeSort() {
public void testMergeSortSimple() {
int[] lst = { 3, 5, 7, 1, 9, 9, 3, 4, 2 };
Sorting.mergeSort(lst);
System.out.println(Arrays.toString(lst));
assertTrue(isSorted(lst));
}
@Test
public void testSelectionSortSimple() {
int[] lst = { 3, 5, 7, 1, 9, 9, 3, 4, 2 };
Sorting.selectionSort(lst);
System.out.println(Arrays.toString(lst));
assertTrue(isSorted(lst));
}
@Test
public void testGetMin() {
int[] lst = { 3, 5, 7, 1, 9, 9, 3, 4, 2 };
boolean[] seen = new boolean[lst.length];
assertFalse(seen[3]);
assertEquals(1, Sorting.getMin(lst, seen));
assertTrue(seen[3]);
assertEquals(2, Sorting.getMin(lst, seen));
assertTrue(seen[8]);
}
@Test
public void testMergeSortBig() {
for (int i=0; i<TESTS; i++) {
int[] lst = new int[LISTLEN];
for (int j=0; j<LISTLEN; j++) {
lst[j] = r.nextInt(LISTLEN) - (LISTLEN/2);
Sorting.mergeSort(lst);
assertTrue(isSorted(lst));
}
}
}
@Test
public void testSelectionSortBig() {
for (int i=0; i<TESTS; i++) {
int[] lst = new int[LISTLEN];
for (int j=0; j<LISTLEN; j++) {
lst[j] = r.nextInt(LISTLEN) - (LISTLEN/2);
Sorting.selectionSort(lst);
assertTrue(isSorted(lst));
}
}
}
public static boolean isSorted(int[] lst) {
private static boolean isSorted(int[] lst) {
if (lst.length <= 1)
return true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment