Rename year directories to allow natural ordering

This commit is contained in:
2023-12-20 03:57:27 +00:00
parent 0ab1f5ad3a
commit 1f7d812b98
1895 changed files with 0 additions and 7188 deletions

View File

@ -0,0 +1,69 @@
import javax.swing.JOptionPane;
/**
* Array implementation of Queue ADT
*/
public class ArrayQueue implements Queue
{
protected Object Q[]; // array used to implement the queue
protected int rear = -1; // index for the rear of the queue
protected int capacity; // The actual capacity of the queue array
public static final int CAPACITY = 1000; // default array capacity
public ArrayQueue() {
// default constructor: creates queue with default capacity
this(CAPACITY);
}
public ArrayQueue(int cap) {
// this constructor allows you to specify capacity
capacity = (cap > 0) ? cap : CAPACITY;
Q = new Object[capacity];
}
public void enqueue(Object n)
{
if (isFull()) {
JOptionPane.showMessageDialog(null, "Cannot enqueue object; queue is full.");
return;
}
rear++;
Q[rear] = n;
}
public Object dequeue()
{
// Can't do anything if it's empty
if (isEmpty())
return null;
Object toReturn = Q[0];
// shuffle all other objects towards 0
int i = 1;
while (i <= rear) {
Q[i-1] = Q[i];
i++;
}
rear--;
return toReturn;
}
public boolean isEmpty() {
return (rear < 0);
}
public boolean isFull() {
return (rear == capacity-1);
}
public Object front()
{
if (isEmpty())
return null;
return Q[0];
}
}

View File

@ -0,0 +1,63 @@
/** Array implementation of Stack ADT */
import javax.swing.JOptionPane;
public class ArrayStack implements Stack
{
protected int capacity; // The actual capacity of the stack array
protected static final int CAPACITY = 1000; // default array capacity
protected Object S[]; // array used to implement the stack
protected int top = -1; // index for the top of the stack
public ArrayStack() {
// default constructor: creates stack with default capacity
this(CAPACITY);
}
public ArrayStack(int cap) {
// this constructor allows you to specify capacity of stack
capacity = (cap > 0) ? cap : CAPACITY;
S = new Object[capacity];
}
public void push(Object element) {
if (isFull()) {
JOptionPane.showMessageDialog(null, "ERROR: Stack is full.");
return;
}
top++;
S[top] = element;
}
public Object pop() {
Object element;
if (isEmpty()) {
JOptionPane.showMessageDialog(null, "ERROR: Stack is empty.");
return null;
}
element = S[top];
S[top] = null;
top--;
return element;
}
public Object top() {
if (isEmpty()) {
JOptionPane.showMessageDialog(null, "ERROR: Stack is empty.");
return null;
}
return S[top];
}
public boolean isEmpty() {
return (top < 0);
}
public boolean isFull() {
return (top == capacity-1);
}
public int size() {
return (top + 1);
}
}

View File

@ -0,0 +1,21 @@
// class to implement Method 2
public class IVersusNMinusI implements PalindromeChecker {
// method 2 - comparing each element at index i to the element at n - i where n is the last index
@Override
public boolean checkPalindrome(String str) {
// looping through the first half of the String
NewPalindrome.operations[1]++;
for (int i = 0; i < Math.floor(str.length() / 2); i++) {
NewPalindrome.operations[1] += 1 + 1 + 1 + 1; // 1 for the getting str.length(), 1 for Math,floor, 1 for checking condition, 1 for incrementing
// returning false if the digits don't match
NewPalindrome.operations[1] += 1 + 1 + 1 + 1; // 1 for str.charAt(i), 1 for ((str.lenght() -1) - 1), 1 for the other str.charAt(), 1 for checking the condition
if (str.charAt(i) != str.charAt((str.length()-1) - i)) {
return false;
}
}
// returning true as default
return true;
}
}

View File

@ -0,0 +1,93 @@
import java.io.*;
public class NewPalindrome {
public static long[] operations = new long[4]; // array to contain the global operations count for each method
public static int[] decCount = new int[4]; // array to hold the count of decimal palindromes found using each method
public static int[] binCount = new int[4]; // array to hold the count of binary palindromes found using each method
public static int[] bothCount = new int[4]; // array to hold the count of numbers that are palindromes in both decimal & binary found using each method
public static long[] startTime = new long[4]; // array to hold the start time of each method's test loop
public static long[] totalTime = new long[4]; // array to hold the total time of each method's test loop
// array to hold all the String versions of the numbers so that they don't have to be generated for each method
// 0th column will be decimal, 1st column will be binary
public static String[][] strings = new String[1_000_001][2];
// array of StringBuilder objects used to hold the csv data (size of problem, number of operations) for each method
public static StringBuilder[] data = new StringBuilder[4];
// array of the four classes that will be tested
public static PalindromeChecker[] palindromeCheckers = {new ReverseVSOriginal(), new IVersusNMinusI(), new StackVSQueue(), new RecursiveReverse()};
public static void main(String args[]) {
// initialising the data array to StringBuilder objects
for (int i = 0; i < 4; i++) {
data[i] = new StringBuilder("operations,size\n");
}
// filling up the strings array
for (int i = 0; i <= 1_000_000; i++) {
strings[i][0] = Integer.toString(i, 10); // converting i to a String base 10
strings[i][1] = binary2string(strings[i][0]); // converting the decimal String to a binary String
}
// looping through each PalindromeChecker object in the palindromeCheckers array
for (int j = 0; j < 4; j++) {
// getting start time
startTime[j] = System.currentTimeMillis(); operations[j]++;
// looping through the numbers 0 to 1,000,000 and checking if their binary & decimal representations are palindromic
operations[j]++;
for (int i = 0; i <= 1_000_000; i++) {
// incrementing the operations count by 2, 1 for the loop condition check and 1 for incrementing i
operations[j] += 2;
// converting the number to a decimal or binary String and checking if is a palindrome
boolean isDecPalindrome = palindromeCheckers[j].checkPalindrome(strings[i][0]); operations[j]++;
boolean isBinPalindrome = palindromeCheckers[j].checkPalindrome(strings[i][1]); operations[j]++;
// incrementing the appropriate counter if the number is a palindrome in that base
decCount[j] = isDecPalindrome ? decCount[j] + 1 : decCount[j]; operations[j] += 1 + 1; // incremnting by 2, 1 for assignment, 1 for condition check
binCount[j] = isBinPalindrome ? binCount[j] + 1 : binCount[j]; operations[j] += 1 + 1;
bothCount[j] = isDecPalindrome && isBinPalindrome ? bothCount[j] + 1 : bothCount[j]; operations[j] += 1 + 1 +1; // 2 condition checks and one assignment, so incrementing by 3
// appending to the data StringBuilder at intervals of 50,000
if (i % 50_000 == 0) {
data[j].append(operations[j] + "," + i + "\n");
}
}
// calculating total time taken for method 1 and printing out the results
totalTime[j] = System.currentTimeMillis() - startTime[j]; operations[j] += 1 + 1; // incrementing by 2, 1 for getting current time and subtracting start time, 1 for assignment
System.out.println("Number of decimal palindromes found using Method " + j + ": " + decCount[j]);
System.out.println("Number of binary palindromes found using Method " + j + ": " + binCount[j]);
System.out.println("Number of palindromes in both decimal & binary found using Method " + j + ": " + bothCount[j]);
System.out.println("Number of primitive operations taken in Method " + j + ": " + operations[j]);
System.out.println("Time taken for Method " + j + ": " + totalTime[j] + " milliseconds");
System.out.println();
// outputting the data to separate csv files
try {
String filename = "method" + j + ".csv";
File csv = new File(filename);
// creating file if it doesn't already exist
csv.createNewFile();
FileWriter writer = new FileWriter(filename);
writer.write(data[j].toString());
writer.close();
} catch (IOException e) {
System.out.println("IO Error occurred");
e.printStackTrace();
System.exit(1);
}
}
}
// utility method to convert a decimal String to its equivalent binary String
public static String binary2string(String decimalStr) {
return Integer.toString(Integer.parseInt(decimalStr), 2); // parsing the String to an int and then parsing that int to a binary String
}
}

View File

@ -0,0 +1,320 @@
import java.io.*;
public class Palindrome {
// global operations count for each method
public static long operations1 = 0;
public static long operations2 = 0;
public static long operations3 = 0;
public static long operations4 = 0;
// String objects used to hold the csv data (size of problem, number of operations) for each method
public static StringBuilder data1 = new StringBuilder("operations,size\n");
public static StringBuilder data2 = new StringBuilder("operations,size\n");
public static StringBuilder data3 = new StringBuilder("operations,size\n");
public static StringBuilder data4 = new StringBuilder("operations,size\n");
public static void main(String args[]) {
// generating all the String versions of the numbers so that they don't have to be generated for each method
// 0th column will be decimal, 1st column will be binary
String[][] strings = new String[1_000_001][2];
for (int i = 0; i <= 1_000_000; i++) {
strings[i][0] = Integer.toString(i, 10); // converting i to a String base 10
strings[i][1] = binary2string(strings[i][0]); // converting the decimal String to a binary String
}
// variables for method 1 - reversed order String vs original String
int decCount1 = 0; operations1++; // count of decimal palindromes for use by method 1
int binCount1 = 0; operations1++; // count of binary palindromes for use by method 1
int bothCount1 = 0; operations1++; // count of numbers that are palindromic in both binary & decimal for use by method 1
long startTime1 = System.currentTimeMillis(); operations1 += 1 + 1;
// testing method 1 - reversed order String vs original String
// incrementing the operations counter for the initialisation of i below
operations1++;
for (int i = 0; i <= 1_000_000; i++) {
// incrementing the operations count by 2, 1 for the loop condition check and 1 for incrementing i
operations1 += 2;
// converting the number to a decimal or binary String and checking if is a palindrome
boolean isDecPalindrome = reverseVSoriginal(strings[i][0]); operations1++;
boolean isBinPalindrome = reverseVSoriginal(strings[i][1]); operations1++;
// incrementing the appropriate counter if the number is a palindrome in that base
decCount1 = isDecPalindrome ? decCount1 + 1 : decCount1; operations1 += 1 + 1; // incremnting by 2, 1 for assignment, 1 for condition check
binCount1 = isBinPalindrome ? binCount1 + 1 : binCount1; operations1 += 1 + 1;
bothCount1 = isDecPalindrome && isBinPalindrome ? bothCount1 + 1 : bothCount1; operations1 += 1 + 1 +1; // 2 condition checks and one assignment, so incrementing by 3
// appending to the data StringBuilder at intervals of 50,000
if (i % 50_000 == 0) {
data1.append(operations1 + "," + i + "\n");
}
}
// calculating total time taken for method 1 and printing out the results
long totalTime1 = System.currentTimeMillis() - startTime1; operations1 += 1 + 1; // incrementing by 2, 1 for getting current time and subtracting start time, 1 for assignment
System.out.println("Number of decimal palindromes found using Method 1: " + decCount1);
System.out.println("Number of binary palindromes found using Method 1: " + binCount1);
System.out.println("Number of palindromes in both decimal & binary found using Method 1: " + bothCount1);
System.out.println("Number of primitive operations taken in Method 1: " + operations1);
System.out.println("Time taken for Method 1: " + totalTime1 + " milliseconds");
// variables for method 2 - comparing each element at index i to the element at n - i where n is the last index
int decCount2 = 0; operations2++; // count of decimal palindromes for use by method 2
int binCount2 = 0; operations2++; // count of binary palindromes for use by method 2
int bothCount2 = 0; operations2++; // count of numbers that are palindromic in both binary & decimal for use by method 2
long startTime2 = System.currentTimeMillis(); operations2 += 1 + 1;
// testingmethod 2 - comparing each element at index i to the element at n - i where n is the last index
operations2++;
for (int i = 0; i <= 1_000_000; i++) {
operations2 += 1 + 1;
// converting the number to a decimal or binary String and checking if is a palindrome
boolean isDecPalindrome = iVSiMinusn(strings[i][0]); operations2++;
boolean isBinPalindrome = iVSiMinusn(strings[i][1]); operations2++;
// incrementing the appropriate counter if the number is a palindrome in that base
decCount2 = isDecPalindrome ? decCount2 + 1 : decCount2; operations2 += 1 + 1;
binCount2 = isBinPalindrome ? binCount2 + 1 : binCount2; operations2 += 1 + 1;
bothCount2 = isDecPalindrome && isBinPalindrome ? bothCount2 + 1 : bothCount2; operations2 += 1 + 1 +1;
// appending to the data StringBuilder at intervals of 50,000
if (i % 50_000 == 0) {
data2.append(operations2 + "," + i + "\n");
}
}
// calculating total time taken for method 2 and printing out the results
long totalTime2 = System.currentTimeMillis() - startTime2; operations2 += 1 + 1;
System.out.println();
System.out.println("Number of decimal palindromes found using Method 2: " + decCount2);
System.out.println("Number of binary palindromes found using Method 2: " + binCount2);
System.out.println("Number of palindromes in both decimal & binary found using Method 2: " + bothCount2);
System.out.println("Number of primitive operations taken in Method 2: " + operations2);
System.out.println("Time taken for Method 2: " + totalTime2 + " milliseconds");
// variables for method 3 - comparing each element at index i to the element at n - i where n is the last index
int decCount3 = 0; operations3++; // count of decimal palindromes for use by method 3
int binCount3 = 0; operations3++; // count of binary palindromes for use by method 3
int bothCount3 = 0; operations3++; // count of numbers that are palindromic in both binary & decimal for use by method 3
long startTime3 = System.currentTimeMillis(); operations3 += 1 + 1;
// testingmethod 3 - comparing each element at index i to the element at n - i where n is the last index
operations3++;
for (int i = 0; i <= 1_000_000; i++) {
operations3 += 1 + 1;
// converting the number to a decimal or binary String and checking if is a palindrome
boolean isDecPalindrome = stackVsqueue(strings[i][0]); operations3++;
boolean isBinPalindrome = stackVsqueue(strings[i][1]); operations3++;
// incrementing the appropriate counter if the number is a palindrome in that base
decCount3 = isDecPalindrome ? decCount3 + 1 : decCount3; operations3 += 1 + 1;
binCount3 = isBinPalindrome ? binCount3 + 1 : binCount3; operations3 += 1 + 1;
bothCount3 = isDecPalindrome && isBinPalindrome ? bothCount3 + 1 : bothCount3; operations3 += 1 + 1 + 1;
// appending to the data StringBuilder at intervals of 50,000
if (i % 50_000 == 0) {
data3.append(operations3 + "," + i + "\n");
}
}
// calculating total time taken for method 3 and printing out the results
long totalTime3 = System.currentTimeMillis() - startTime3; operations3 += 1 + 1;
System.out.println();
System.out.println("Number of decimal palindromes found using Method 3: " + decCount3);
System.out.println("Number of binary palindromes found using Method 3: " + binCount3);
System.out.println("Number of palindromes in both decimal & binary found using Method 3: " + bothCount3);
System.out.println("Number of primitive operations taken in Method 3: " + operations3);
System.out.println("Time taken for Method 3: " + totalTime3 + " milliseconds");
// variables for method 4 - comparing each element at index i to the element at n - i where n is the last index
int decCount4 = 0; operations4++; // count of decimal palindromes for use by method 4
int binCount4 = 0; operations4++; // count of binary palindromes for use by method 4
int bothCount4 = 0; operations4++; // count of numbers that are palindromic in both binary & decimal for use by method 4
long startTime4 = System.currentTimeMillis(); operations4 += 1 + 1;
// testingmethod 4 - comparing each element at index i to the element at n - i where n is the last index
operations4++;
for (int i = 0; i <= 1_000_000; i++) {
operations4 += 2;
// converting the number to a decimal or binary String and checking if is a palindrome
boolean isDecPalindrome = recursiveReverseVSoriginal(strings[i][0]); operations4++;
boolean isBinPalindrome = recursiveReverseVSoriginal(strings[i][1]); operations4++;
// incrementing the appropriate counter if the number is a palindrome in that base
decCount4 = isDecPalindrome ? decCount4 + 1 : decCount4; operations4 += 1 + 1;
binCount4 = isBinPalindrome ? binCount4 + 1 : binCount4; operations4 += 1 + 1;
bothCount4 = isDecPalindrome && isBinPalindrome ? bothCount4 + 1 : bothCount4; operations4 += 1 + 1 + 1;
// appending to the data StringBuilder at intervals of 50,000
if (i % 50_000 == 0) {
data4.append(operations4 + "," + i + "\n");
}
}
// calculating total time taken for method 4 and printing out the results
long totalTime4 = System.currentTimeMillis() - startTime4; operations4 += 1 + 1;
System.out.println();
System.out.println("Number of decimal palindromes found using Method 4: " + decCount4);
System.out.println("Number of binary palindromes found using Method 4: " + binCount4);
System.out.println("Number of palindromes in both decimal & binary found using Method 4: " + bothCount4);
System.out.println("Number of primitive operations taken in Method 4: " + operations4);
System.out.println("Time taken for Method 4: " + totalTime4 + " milliseconds");
// outputting the data to separate csv files
try {
File csv1 = new File("method1.csv");
File csv2 = new File("method2.csv");
File csv3 = new File("method3.csv");
File csv4 = new File("method4.csv");
// creating files if they don't already exist
csv1.createNewFile();
csv2.createNewFile();
csv3.createNewFile();
csv4.createNewFile();
FileWriter writer1 = new FileWriter("method1.csv");
writer1.write(data1.toString());
writer1.close();
FileWriter writer2 = new FileWriter("method2.csv");
writer2.write(data2.toString());
writer2.close();
FileWriter writer3 = new FileWriter("method3.csv");
writer3.write(data3.toString());
writer3.close();
FileWriter writer4 = new FileWriter("method4.csv");
writer4.write(data4.toString());
writer4.close();
} catch (IOException e) {
System.out.println("IO Error occurred");
e.printStackTrace();
System.exit(1);
}
}
// method 1 - reversed order String vs original String
public static boolean reverseVSoriginal(String str) {
String reversedStr = ""; operations1++;
// looping through each character in the String, backwards
// incrementing operations counter by 2, 1 for initialisating i, 1 for getting str.length()
operations1 += 1 + 1;
for (int i = str.length(); i > 0; i--) {
operations1 += 1 + 1; // for loop condition check & incrementing i
reversedStr += str.charAt(i-1); operations1 += 1 + 1;
}
// returning true if the Strings are equal, false if not
operations1 += str.length(); // the equals method must loop through each character of the String to check that they are equal so it is O(n)
return str.equals(reversedStr);
}
// method 2 - comparing each element at index i to the element at n - i where n is the last index
public static boolean iVSiMinusn(String str) {
// looping through the first half of the String
operations2++;
for (int i = 0; i < Math.floor(str.length() / 2); i++) {
operations2 += 1 + 1 + 1 + 1; // 1 for the getting str.length(), 1 for Math,floor, 1 for checking condition, 1 for incrementing
// returning false if the digits don't match
operations2 += 1 + 1 + 1 + 1; // 1 for str.charAt(i), 1 for ((str.lenght() -1) - 1), 1 for the other str.charAt(), 1 for checking the condition
if (str.charAt(i) != str.charAt((str.length()-1) - i)) {
return false;
}
}
// returning true as default
return true;
}
// method 3 - using a stack and a queue to do, essentially, what method 2 does
public static boolean stackVsqueue(String str) {
ArrayStack stack = new ArrayStack(); operations3 += 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1;
ArrayQueue queue = new ArrayQueue(); operations3 += 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1;
// looping through each character in the String and adding the character to the stack & queue
operations3++;
for (int i = 0; i < str.length(); i++) {
operations3 += 1 + 1 + 1;
stack.push(str.charAt(i)); operations3 += 1 + 1 + 1 + 1;
queue.enqueue(str.charAt(i)); operations3 += 1 + 1 + 1 + 1;
}
// looping through each character on the stack & queue and comparing them, returning false if they're different
operations3++;
for (int i = 0; i < str.length(); i++) {
operations3 += 1 + 1 + 1;
operations3 += 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1;
if (!stack.pop().equals(queue.front())) {
return false;
}
// the complexity of ArrayQueue.dequeue() is 3n+2, where n is the number of items in the queue when dequeue() is called.
// we need to determine the number of items in the queue so that we can determine the number of primitive operations performed when queue.dequeue() is called.
// to do this, we'll loop through the queue, dequeuing each object and enqueueing it in another ArrayQueue. once complete, we'll reassign the variable queue to point to the new ArrayQueue containing all the objects
ArrayQueue newQueue = new ArrayQueue(); // not counting the operations for this as it's not part of the algorithm, it's part of the operations counting
int n = 0; // n is the number of items in the ArrayQueue when dequeue() is called
while (!queue.isEmpty()) {
newQueue.enqueue(queue.dequeue());
n++;
}
queue = newQueue; // setting queue to point to the newQueue, which is just the state that queue would have been in if we didn't do this to calculate the primitive operations
newQueue = null; // don't need the newQueue object reference anymore
operations3 += 3*n + 2; // complexity of dequeue is 3n+2
queue.dequeue();
}
return true;
}
// method 4 - comparing the String reversed using recursion to the original String (essentially method 1 but with recursion)
public static boolean recursiveReverseVSoriginal(String str) {
// returning true if the original String is equal to the reversed String, false if not
operations4++;
return str.equals(reverse(str));
}
// method to reverse the characters in a String using recursion
public static String reverse(String str) {
// base case - returning an empty String if there is no character left in the String
operations4++;
if (str.length() == 0) {
return "";
}
else {
char firstChar = str.charAt(0); operations4 += 1 + 1;
String remainder = str.substring(1); operations4 += 1 + 1; // selecting the rest of the String, excluding the 0th character
// recursing with what's left of the String
String reversedRemainder = reverse(remainder); operations4++;
// returning the reversed rest of String with the first character of the String appended
return reversedRemainder + firstChar;
}
}
// utility method to convert a decimal String to its equivalent binary String
public static String binary2string(String decimalStr) {
return Integer.toString(Integer.parseInt(decimalStr), 2); // parsing the String to an int and then parsing that int to a binary String
}
}

View File

@ -0,0 +1,3 @@
public interface PalindromeChecker {
public boolean checkPalindrome(String str);
}

View File

@ -0,0 +1,14 @@
/*
* Abstract Queue interface
*/
public interface Queue {
// most important methods
public void enqueue(Object n); // add an object at the rear of the queue
public Object dequeue(); // remove an object from the front of the queue
// others
public boolean isEmpty(); // true if queue is empty
public boolean isFull(); // true if queue is full (if it has limited storage)
public Object front(); // examine front object on queue without removing it
}

View File

@ -0,0 +1,29 @@
// class to implement method 4
public class RecursiveReverse implements PalindromeChecker {
// comparing the String reversed using recursion to the original String (essentially method 1 but with recursion)
@Override
public boolean checkPalindrome(String str) {
// returning true if the original String is equal to the reversed String, false if not
NewPalindrome.operations[3]++;
return str.equals(reverse(str));
}
// method to reverse the characters in a String using recursion
public static String reverse(String str) {
// base case - returning an empty String if there is no character left in the String
NewPalindrome.operations[3]++;
if (str.length() == 0) {
return "";
}
else {
char firstChar = str.charAt(0); NewPalindrome.operations[3] += 1 + 1;
String remainder = str.substring(1); NewPalindrome.operations[3] += 1 + 1; // selecting the rest of the String, excluding the 0th character
// recursing with what's left of the String
String reversedRemainder = reverse(remainder); NewPalindrome.operations[3]++;
// returning the reversed rest of String with the first character of the String appended
return reversedRemainder + firstChar;
}
}
}

View File

@ -0,0 +1,21 @@
// class to implement Method 3
public class ReverseVSOriginal implements PalindromeChecker {
// method 1 - reversed order String vs original String
@Override
public boolean checkPalindrome(String str) {
String reversedStr = ""; NewPalindrome.operations[0]++;
// looping through each character in the String, backwards
// incrementing operations counter by 2, 1 for initialisating i, 1 for getting str.length()
NewPalindrome.operations[0] += 1 + 1;
for (int i = str.length(); i > 0; i--) {
NewPalindrome.operations[0] += 1 + 1; // for loop condition check & incrementing i
reversedStr += str.charAt(i-1); NewPalindrome.operations[0] += 1 + 1;
}
// returning true if the Strings are equal, false if not
NewPalindrome.operations[0] += str.length(); // the equals method must loop through each character of the String to check that they are equal so it is O(n)
return str.equals(reversedStr);
}
}

View File

@ -0,0 +1,13 @@
/** Abstract Stack interface */
public interface Stack
{
// most important methods
public void push(Object n); // push an object onto top of the stack
public Object pop(); // pop an object from top of the stack
// others
public Object top(); // examine top object on stack without removing it
public boolean isEmpty(); // true if stack is empty
public boolean isFull(); // true if stack is full (if it has limited storage)
}

View File

@ -0,0 +1,48 @@
// class to implement method 3
public class StackVSQueue implements PalindromeChecker {
// method 3 - using a stack and a queue to do, essentially, what method 2 does (compare the first index to the last index, etc.)
@Override
public boolean checkPalindrome(String str) {
ArrayStack stack = new ArrayStack(); NewPalindrome.operations[2] += 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1;
ArrayQueue queue = new ArrayQueue(); NewPalindrome.operations[2] += 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1;
// looping through each character in the String and adding the character to the stack & queue
NewPalindrome.operations[2]++;
for (int i = 0; i < str.length(); i++) {
NewPalindrome.operations[2] += 1 + 1 + 1;
stack.push(str.charAt(i)); NewPalindrome.operations[2] += 1 + 1 + 1 + 1;
queue.enqueue(str.charAt(i)); NewPalindrome.operations[2] += 1 + 1 + 1 + 1;
}
// looping through each character on the stack & queue and comparing them, returning false if they're different
NewPalindrome.operations[2]++;
for (int i = 0; i < str.length(); i++) {
NewPalindrome.operations[2] += 1 + 1 + 1;
NewPalindrome.operations[2] += 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1;
if (!stack.pop().equals(queue.front())) {
return false;
}
// the complexity of ArrayQueue.dequeue() is 3n+2, where n is the number of items in the queue when dequeue() is called.
// we need to determine the number of items in the queue so that we can determine the number of primitive operations performed when queue.dequeue() is called.
// to do this, we'll loop through the queue, dequeuing each object and enqueueing it in another ArrayQueue. once complete, we'll reassign the variable queue to point to the new ArrayQueue containing all the objects
ArrayQueue newQueue = new ArrayQueue(); // not counting the operations for this as it's not part of the algorithm, it's part of the operations counting
int n = 0; // n is the number of items in the ArrayQueue when dequeue() is called
while (!queue.isEmpty()) {
newQueue.enqueue(queue.dequeue());
n++;
}
queue = newQueue; // setting queue to point to the newQueue, which is just the state that queue would have been in if we didn't do this to calculate the primitive operations
newQueue = null; // don't need the newQueue object reference anymore
NewPalindrome.operations[2] += 3*n + 2; // complexity of dequeue is 3n+2
queue.dequeue();
}
return true;
}
}

View File

@ -0,0 +1,14 @@
public class Test {
public static void main(String[] args) {
String str = "1234567890";
ArrayQueue queue = new ArrayQueue();
for (int i = 0; i < str.length(); i++) {
queue.enqueue(str.charAt(i));
}
for (int i = 0; i < str.length(); i++) {
queue.dequeue();
}
}
}

View File

@ -0,0 +1,22 @@
operations,size
29,0
5716904,50000
11989234,100000
18683879,150000
25533879,200000
32383879,250000
39423164,300000
46523164,350000
53623164,400000
60723164,450000
67823164,500000
75051729,550000
82401729,600000
89751729,650000
97101729,700000
104451729,750000
111801729,800000
119151729,850000
126501729,900000
133851729,950000
141201734,1000000
1 operations size
2 29 0
3 5716904 50000
4 11989234 100000
5 18683879 150000
6 25533879 200000
7 32383879 250000
8 39423164 300000
9 46523164 350000
10 53623164 400000
11 60723164 450000
12 67823164 500000
13 75051729 550000
14 82401729 600000
15 89751729 650000
16 97101729 700000
17 104451729 750000
18 111801729 800000
19 119151729 850000
20 126501729 900000
21 133851729 950000
22 141201734 1000000

View File

@ -0,0 +1,22 @@
operations,size
15,0
1881959,50000
3768823,100000
5660295,150000
7552719,200000
9445167,250000
11337607,300000
13230031,350000
15122471,400000
17014895,450000
18907343,500000
20800207,550000
22693407,600000
24586615,650000
26479855,700000
28373063,750000
30266287,800000
32159487,850000
34052711,900000
35945943,950000
37839175,1000000
1 operations size
2 15 0
3 1881959 50000
4 3768823 100000
5 5660295 150000
6 7552719 200000
7 9445167 250000
8 11337607 300000
9 13230031 350000
10 15122471 400000
11 17014895 450000
12 18907343 500000
13 20800207 550000
14 22693407 600000
15 24586615 650000
16 26479855 700000
17 28373063 750000
18 30266287 800000
19 32159487 850000
20 34052711 900000
21 35945943 950000
22 37839175 1000000

View File

@ -0,0 +1,22 @@
operations,size
105,0
17250278,50000
36003532,100000
55780375,150000
75979194,200000
96178166,250000
116909827,300000
137812321,350000
158715267,400000
179617761,450000
200521097,500000
221777541,550000
243367974,600000
264958463,650000
286548836,700000
308139668,750000
329729920,800000
351320353,850000
372910963,900000
394501277,950000
416092270,1000000
1 operations size
2 105 0
3 17250278 50000
4 36003532 100000
5 55780375 150000
6 75979194 200000
7 96178166 250000
8 116909827 300000
9 137812321 350000
10 158715267 400000
11 179617761 450000
12 200521097 500000
13 221777541 550000
14 243367974 600000
15 264958463 650000
16 286548836 700000
17 308139668 750000
18 329729920 800000
19 351320353 850000
20 372910963 900000
21 394501277 950000
22 416092270 1000000

View File

@ -0,0 +1,22 @@
operations,size
29,0
6590279,50000
13847075,100000
21610649,150000
29560649,200000
37510649,250000
45687791,300000
53937791,350000
62187791,400000
70437791,450000
78687791,500000
87092069,550000
95642069,600000
104192069,650000
112742069,700000
121292069,750000
129842069,800000
138392069,850000
146942069,900000
155492069,950000
164042075,1000000
1 operations size
2 29 0
3 6590279 50000
4 13847075 100000
5 21610649 150000
6 29560649 200000
7 37510649 250000
8 45687791 300000
9 53937791 350000
10 62187791 400000
11 70437791 450000
12 78687791 500000
13 87092069 550000
14 95642069 600000
15 104192069 650000
16 112742069 700000
17 121292069 750000
18 129842069 800000
19 138392069 850000
20 146942069 900000
21 155492069 950000
22 164042075 1000000

View File

@ -0,0 +1,214 @@
\documentclass[a4paper]{article}
\usepackage{listings}
\usepackage{xcolor}
\definecolor{codegreen}{rgb}{0,0.6,0}
\definecolor{codegray}{rgb}{0.5,0.5,0.5}
\definecolor{codeorange}{rgb}{1,0.49,0}
\definecolor{backcolour}{rgb}{0.95,0.95,0.96}
\usepackage{pgfplots}
\pgfplotsset{width=\textwidth,compat=1.9}
\lstdefinestyle{mystyle}{
backgroundcolor=\color{backcolour},
commentstyle=\color{codegray},
keywordstyle=\color{codeorange},
numberstyle=\tiny\color{codegray},
stringstyle=\color{codegreen},
basicstyle=\ttfamily\footnotesize,
breakatwhitespace=false,
breaklines=true,
captionpos=b,
keepspaces=true,
numbers=left,
numbersep=5pt,
showspaces=false,
showstringspaces=false,
showtabs=false,
tabsize=2,
xleftmargin=10pt,
}
\lstset{style=mystyle}
\input{head}
\begin{document}
%-------------------------------
% TITLE SECTION
%-------------------------------
\fancyhead[C]{}
\hrule \medskip % Upper rule
\begin{minipage}{0.295\textwidth}
\begin{raggedright}
\footnotesize
Andrew Hayes \hfill\\
21321503 \hfill\\
a.hayes18@nuigalway.ie
\end{raggedright}
\end{minipage}
\begin{minipage}{0.4\textwidth}
\begin{centering}
\large
CT2109 Assignment 3\\
\normalsize
\end{centering}
\end{minipage}
\begin{minipage}{0.295\textwidth}
\begin{raggedleft}
\footnotesize
\today \hfill\\
\end{raggedleft}
\end{minipage}
\medskip\hrule
\medskip
\begin{centering}
Double-Base Palindromes \& Complexity Analysis\\
\end{centering}
\medskip\hrule
\bigskip
\section{Problem Statement}
The overall purpose of this assignment is to perform some basic complexity analysis on four distinct algorithms, each of which aim to achieve the same result: determining whether a String is palindromic.
More specifically, each algorithm will be fed the binary \& decimal representations of each integer between $0_{10}$ and $1,000,000_{10}$, in String form.
Each algorithm will then determine whether the String is palindromic, returning either \verb|true| or \verb|false|.
Each method will have three counter variables to record the number of palindromes found: one for the numbers whose decimal form is palindromic, one for the numbers whose binary form is palindromic, and one
for the numbers which are palindromic in both decimal \& binary form.
\\\\
The number of primitive operations will be recorded using a separate global variable for each method.
Additionally, the real time taken by each method (in milliseconds) will be recorded.
These measurements will form the basis of the complexity analysis performed.
The number of primitive operations will be recorded for each method and plotted against the size of the problem (the number of values being checked for palindromicity, $n$).
This graph should reflect the ``order'' of the problem, i.e. it should match the big-O representation derived from a time-complexity analysis of the algorithm.
For example, an exponential curve on the graph would indicate that the algorithm is of $O(n^2)$ complexity, while a straight line through the origin would indicate that the algorithm is of $O(n)$ complexity.
\section{Analysis \& Design Notes}
The first thing that we'll want to do in this program is declare the variables that we'll use to record the data for each method being tested.
We will have seven arrays of size four, with one index for each method being tested.
These arrays will be:
\begin{itemize}
\item \verb|long[] operations| - To count the number of primitive operations for each method.
\item \verb|int[] decCount| - To count how many numbers that are palindromic in decimal form are found using each method.
\item \verb|int[] binCount| - To count how many numbers that are palindromic in binary form are found using each method.
\item \verb|int[] bothCount| - To count how many numbers that are palindromic in both decimal \& binary form are found using each method.
\item \verb|long[] startTime| - To record the start time (in Unix epoch form) of the testing of each of the four methods.
\item \verb|long[] totalTime| - To record the total time (in milliseconds) by the testing of each of the four methods.
\item \verb|StringBuilder[] data| - This will be be used to create a String of CSV data for each method, which will be output to a \verb|.csv| file at the end of testing.
Doing this saves us from having to open, write to, \& close a \verb|.csv| file every time we want to record some data, which would be very inefficient.
\end{itemize}
The first thing that we'll do in the main method is initialise all the indices in the \verb|StringBuilder[] data| array to have the appropriate headings from each column, one column for the number of primitive operations
and one for the size of the problem that used that number of primitive operations, i.e. \verb|"operations,size\n"|.
\\\\
We'll also want to generate a two-dimensional array of all the Strings that we'll be testing for palindromicity, with one dimension for decimal Strings and one dimension for binary Strings, both going up to
$1,000,000_{10}$.
Generating this once in the beginning will save us from having to re-generate the same Strings four times, which would be very inefficient.
\\\\
Each method that we will be testing will have its own class that implements the interface \verb|PalindromeChecker|.
This interface will contain a single method with the signature \verb|public boolean checkPalindrome(String str)|.
The reason for doing this will be to follow OOP principles \& the DRY principle so that we don't have unnecessary repetition of code.
This will allow us to have one generic loop through each of the numbers from $0_{10}$ to $1,000,000_{10}$ instead of four separate ones.
Each of the methods that we will be testing will be overridden implementations of \verb|checkPalindrome|.
We will have four classes that implement \verb|PalindromeChecker|:
\begin{itemize}
\item \verb|ReverseVSOriginal| - This class will contain ``Method One'' outlined in the assignment specification, which checks if a String is palindromic by comparing the String to a reversed copy of itself, hence the name.
\item \verb|IVersusIMinusN| - This will contain ``Method Two'' outlined in the assignment specification, which checks if a String is palindromic by looping through each character in the String using an iterator
\verb|i| and comparing the character at index \verb|i| to the character at index \verb|n-i|, where \verb|n| is the last index in the String, i.e., comparing the first character to the last, the second character to the second-last, etc.
\item \verb|StackVSQueue| - This will contain ``Method Three'' outlined in the assignment specification, which checks if a String is palindromic using essentially the same technique as ``Method Two''
but instead of simply iterating through the String, each character of the String will be put onto both a Stack \& a Queue, and then items will be removed from the Stack \& Queue and compared to each other.
The LIFO nature of the Stack and the FIFO nature of the Queue result in this comparison being first character versus last, second character versus second-last, and so on.
\item \verb|RecursiveReverse| - This will contain ``Method Four'' outlined in the assignment specification, which checks if a String is palindromic using essentially the same technique as ``Method One''
but using recursion to reverse the String instead of iteration.
\end{itemize}
An array called \verb|PalindromeCheckers[]| will be initialised to contain an instance of each of these four classes.
This array will be iterated over (using iterator \verb|j|) to test each method, which prevents code repetition.
In said loop, firstly, the \verb|startTime[j]| will be recorded using \verb|System.getCurrentTimeMillis();|.
Then, a loop will be entered that iterators over each number between $0_{10}$ to $1,000,000_{10}$.
Both the decimal \& binary Strings at index \verb|i| of the \verb|strings[]| array will be passed to \verb|palindromeCheckers[j].checkPalindrome()| to be checked for palindromicity.
Then, \verb|decCount[j]|, \verb|binCount[j]|, \& \verb|bothCount[j]| will be iterated or will remain unchanged, as appropriate.
\\\\
The count of primitive operations for each method will be iterated as they are executed.
I won't count the \verb|return| statements at the end of methods or accessing a variable or array index as primitive operations, as these (especially the \verb|return| statements) are computationally
insignificant, and certainly aren't on the same level as something like creating a new variable in memory.
Unfortunately, it's not really possible to say with accuracy what is \& isn't a ``primitive operation'' in a language so high-level \& abstract as Java, but I feel that this is a reasonable approximation.
We want to record the count of primitive operations at regular intervals of 50,000 during the process, so we will append the operations count and the current \verb|i| to \verb|data[j]| if \verb|i| is
divisible by 50,000.
\\\\
Once the loop using iterator \verb|i| has ended, the total time taken will be recorded by subtracting the current time from the start time.
The number of palindromes found in decimal, binary, and both decimal \& binary will be printed out to the screen, along with the total time taken \& the total number of primitive operations for that method.
Finally, the data for that method will be written to a \verb|.csv| file.
This will be repeated for all four methods in the \verb|palindromeCheckers| array.
\section{Code}
\lstinputlisting[language=Java, breaklines=true, title={NewPalindrome.java}]{../code/NewPalindrome.java}
\lstinputlisting[language=Java, breaklines=true, title={PalindromeChecker.java}]{../code/PalindromeChecker.java}
\lstinputlisting[language=Java, breaklines=true, title={ReverseVSOriginal.java}]{../code/ReverseVSOriginal.java}
\lstinputlisting[language=Java, breaklines=true, title={IVersusIMinusN.java}]{../code/IVersusNMinusI.java}
\lstinputlisting[language=Java, breaklines=true, title={StackVSQueue.java}]{../code/StackVSQueue.java}
\lstinputlisting[language=Java, breaklines=true, title={RecursiveReverse.java}]{../code/RecursiveReverse.java}
\newpage
\section{Testing}
\begin{center}
\begin{tikzpicture}
\begin{axis}[
title={Number of Primitive Operations per Method},
xlabel={Size of Problem},
ylabel={Number of Operations}
]
\addplot table [x=size, y=operations, col sep=comma] {../code/method0.csv};
\addplot table [x=size, y=operations, col sep=comma] {../code/method1.csv};
\addplot table [x=size, y=operations, col sep=comma] {../code/method2.csv};
\addplot table [x=size, y=operations, col sep=comma] {../code/method3.csv};
\legend{Iterative Reverse vs Original,$i$ vs $n-i$,Stack vs Queue,Recursive Reverse vs Original}
\end{axis}
\end{tikzpicture}
\end{center}
\begin{figure}[h]
\centering
\includegraphics[width=0.7\textwidth]{images/output.png}
\caption{Output of the Main Method}
\end{figure}
The output from the program shows that all the methods agreed on the number of palindromes found in each category, which shows us
that they did indeed work as intended.
\\\\
We can see from the graph that $i$ versus $n-i$ or \verb|IVersusNMinusI| method was the most efficient, as it used the fewest
primitive operations out of the four methods (37,839,177) and the complexity grew relatively slowly as the size of the problem increased,
demonstrated by the fact that its curve has quite a gentle slope.
This is reflected in the testing times as it was by far the fastest method (referred to in the screenshot as ``Method 1'', as
indexing was done from 0), taking only 39 milliseconds to complete.
This makes sense, as the method consisted of just one loop and some basic operations, without using any fancy data structures.
Furthermore, this method quickly detects non-palindromic Strings, and returns \verb|false|, saving computation.
\\\\
The next most efficient method was the iterative reverse versus original or \verb|ReverseVSOriginal| method.
Despite being the next most efficient method, it took almost ten times the time that \verb|IVersusNMinusI| took to complete, taking 366
milliseconds, which, all things considered, is still quite fast.
The number of primitive operations and the rate of growth of this method were also accordingly higher than the previous method.
\\\\
The third most efficient method was the recursive reverse versus original or \verb|RecursiveReverse| method.
This makes sense, as it uses a very similar approach to the second most efficient method, but instead did it recursively.
Despite this solution appearing somewhat more elegant from a lines of code perspective, it was in practice less efficient than
its iterative counterpart, both in terms of memory (as the recursive function calls had to remain in memory until all the sub-calls
were complete) and in terms of operations, taking approximately 20 million more primitive operations to complete the same task
as the iterative approach.
It was also significantly slower than its iterative counterpart, taking around 200 milliseconds more to complete the task.
We can also tell from looking at the graph that at low problem sizes that this approach is comparable \& rather similar in terms
of efficiency to the iterative approach, but they quickly diverge, with the recursive approach having a significantly steeper
slope.
We can extrapolate from this that this method would be even less efficient at very large problem sizes, as its rate of growth
is quite large.
\\\\
By far the least efficient method was the Stack versus Queue or \verb|StackVSQueue| method.
It took by far the greatest number of primitive operations, and the rate of growth was ridiculously large, rapidly diverging from
the other four techniques.
Its rate of growth is so large that it would likely quickly become unusable for any significantly large problem.
This is reinforced by the fact that it took 3,519 milliseconds to complete the task, being the only method that took more than one
second to do so, and taking almost 100 times what the best-performing method took.
\end{document}

View File

@ -0,0 +1,49 @@
\addtolength{\hoffset}{-2.25cm}
\addtolength{\textwidth}{4.5cm}
\addtolength{\voffset}{-3.25cm}
\addtolength{\textheight}{5cm}
\setlength{\parskip}{0pt}
\setlength{\parindent}{0in}
%----------------------------------------------------------------------------------------
% PACKAGES AND OTHER DOCUMENT CONFIGURATIONS
%----------------------------------------------------------------------------------------
\usepackage{blindtext} % Package to generate dummy text
\usepackage{charter} % Use the Charter font
\usepackage[utf8]{inputenc} % Use UTF-8 encoding
\usepackage{microtype} % Slightly tweak font spacing for aesthetics
\usepackage[english]{babel} % Language hyphenation and typographical rules
\usepackage{amsthm, amsmath, amssymb} % Mathematical typesetting
\usepackage{float} % Improved interface for floating objects
\usepackage[final, colorlinks = true,
linkcolor = black,
citecolor = black]{hyperref} % For hyperlinks in the PDF
\usepackage{graphicx, multicol} % Enhanced support for graphics
\usepackage{xcolor} % Driver-independent color extensions
\usepackage{marvosym, wasysym} % More symbols
\usepackage{rotating} % Rotation tools
\usepackage{censor} % Facilities for controlling restricted text
\usepackage{listings, style/lstlisting} % Environment for non-formatted code, !uses style file!
\usepackage{pseudocode} % Environment for specifying algorithms in a natural way
\usepackage{style/avm} % Environment for f-structures, !uses style file!
\usepackage{booktabs} % Enhances quality of tables
\usepackage{tikz-qtree} % Easy tree drawing tool
\tikzset{every tree node/.style={align=center,anchor=north},
level distance=2cm} % Configuration for q-trees
\usepackage{style/btree} % Configuration for b-trees and b+-trees, !uses style file!
\usepackage[backend=biber,style=numeric,
sorting=nyt]{biblatex} % Complete reimplementation of bibliographic facilities
\addbibresource{ecl.bib}
\usepackage{csquotes} % Context sensitive quotation facilities
\usepackage[yyyymmdd]{datetime} % Uses YEAR-MONTH-DAY format for dates
\renewcommand{\dateseparator}{-} % Sets dateseparator to '-'
\usepackage{fancyhdr} % Headers and footers
\pagestyle{fancy} % All pages have headers and footers
\fancyhead{}\renewcommand{\headrulewidth}{0pt} % Blank out the default header
\fancyfoot[L]{} % Custom footer text
\fancyfoot[C]{} % Custom footer text
\fancyfoot[R]{\thepage} % Custom footer text
\newcommand{\note}[1]{\marginpar{\scriptsize \textcolor{red}{#1}}} % Enables comments in red on margin
%----------------------------------------------------------------------------------------

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@ -0,0 +1,165 @@
% avm.sty -- for attribute-value matrices -- mar 29, 1992; rev. dec 6, 1993
% (c) 1992 christopher manning (manning@csli.stanford.edu) -- see avm.doc.tex
\newif\ifavmactive\newif\ifavmsorted\newif\ifavmlabeled
\newif\ifavmcenter\newif\ifavmbottom
\newif\ifavmbottomright\newif\ifavmtopleft\newif\ifavmtopright
\newdimen\avmdimen
\newbox\avmboxone\newbox\avmboxthree
\def\avmoptions#1{\avmactivefalse\avmsortedfalse\avmlabeledfalse
\avmcenterfalse\avmbottomfalse
\avmbottomrightfalse\avmtopleftfalse\avmtoprightfalse
\def\more{#1}\ifx\more\empty\else\avmjoptions#1,\@nil\fi}
\def\avmjoptions#1,#2\@nil{\def\more{#2}\csname avm#1true\endcsname
\ifx\more\empty\else\avmjoptions#2\@nil\fi}
\def\avmfont#1{\def\avmjfont{#1}}
\def\avmjfont{}
\def\avmvalfont#1{\def\avmjvalfont{#1}}
\def\avmjvalfont{}
\def\avmsortfont#1{\def\avmjsortfont{#1}}
\def\avmjsortfont{}
\def\avmhskip#1{\def\avmjhskip{#1}}
\def\avmjhskip{1em}
\def\avmbskip#1{\def\avmjbskip{#1}}
\def\avmjbskip{0em}
\def\avmvskip#1{\def\avmjvskip{#1}}
\def\avmjvskip{0.385ex}%was .3875
\def\avmjprolog#1{$\mskip-\thinmuskip
\left#1\hskip\avmjbskip\vcenter\bgroup\vskip\avmjvskip
\ialign\bgroup\avmjfont
\strut ##\unskip\hfil
&&\hskip\avmjhskip\avmjvalfont ##\unskip\hfil\cr}
\def\avmjpostlog#1{\crcr\egroup\vskip\avmjvskip\egroup
\hskip\avmjbskip\right#1\mskip-\thinmuskip$\ignorespaces}
\def\avmjcatcode{\let\lparen=(\let\rparen=)\catcode`\[=13\catcode`\]=13
\catcode`\<=13\catcode`\@=13\catcode`\(=13\catcode`\)=13
\catcode`\>=13\catcode`\|=13}
{\avmjcatcode % new group: redefine above catcodes as active
\gdef\specialavm{\avmjcatcode
\def({\avmjprolog\lparen}%
\def){\avmjpostlog\rparen}%
\def<{\avmjprolog\langle}%
\def>{\avmjpostlog\rangle}%
\ifavmsorted
\def[##1{\setbox\avmboxthree=\hbox{\avmjsortfont##1\/}\setbox2=\hbox
\bgroup\avmjprolog\lbrack}%
\def]{\avmjpostlog\rbrack\egroup\avmjsort}%
\else\ifavmlabeled
\def[##1{\def\more{##1}\setbox2=\hbox\bgroup\avmjprolog[}%
\def]{\avmjpostlog]\egroup\node{\more}{\box2}}%
\else
\def[{\avmjprolog\lbrack}%
\def]{\avmjpostlog\rbrack}%
\fi\fi
%
\def\<{$\langle$}\def\>{$\rangle$}%
\def\({\lparen}\def\){\rparen}%
\def\[{\lbrack}\def\]{\rbrack}%
\def|{$\,\vert\,$}%
\def@##1{\avmbox{##1}}%
} % end defn of \specialavm
} % restore active catcodes
\long\def\avm{\begingroup
\ifavmactive\specialavm
\else
\def\({\avmjprolog(}%
\def\){\avmjpostlog)}%
\def\<{\avmjprolog\langle}%
\def\>{\avmjpostlog\rangle}%
%
\ifavmsorted
\def\[##1{\setbox\avmboxthree=\hbox{\avmjsortfont##1\/}\setbox
2=\hbox\bgroup\avmjprolog[}%
\def\]{\avmjpostlog]\egroup\avmjsort}%
\else\ifavmlabeled
\def\[##1{\def\more{##1}\setbox2=\hbox\bgroup\avmjprolog[}%
\def\]{\avmjpostlog]\egroup\node{\more}{\box2}}%
\else
\def\[{\avmjprolog[}%
\def\]{\avmjpostlog]}%
\fi\fi
%
\def\|{$\,\vert\,$}%
\def\@##1{\avmbox{##1}}%
\fi % end not active
%
\ifx\LaTeX\undefined\def\\{\cr}% running under TeX
\else \def\\{\@tabularcr}% Leverage off LaTeX's \\*[dimen] options
\fi
\def\!{\node}%
\long\def\avmjsort{\dimen2=\ht2\advance\dimen2 by -.25\baselineskip
\global\dimen\avmdimen=\wd\avmboxthree
\ifavmtopleft \raise\dimen2\llap{\box\avmboxthree}\box2%
\else\ifavmtopright \box2\raise\dimen2\box\avmboxthree%
\else\ifavmbottomright \box2\lower\dimen2\box\avmboxthree%
\else \lower\dimen2\llap{\box\avmboxthree}\box2%
\fi\fi\fi}%
\long\def\sort##1##2{\setbox2=\hbox{##2}\setbox
\avmboxthree=\hbox{\avmjsortfont##1\/}\dimen2=\ht2
\advance\dimen2 by -.25\baselineskip
\ifavmtopleft \raise\dimen2\box\avmboxthree\box2%
\else\ifavmtopright \box2\raise\dimen2\box\avmboxthree%
\else\ifavmbottomright \box2\lower\dimen2\box\avmboxthree%
\else \lower\dimen2\box\avmboxthree\box2%
\fi\fi\fi}%
\long\def\osort##1##2{\setbox2=\hbox{##2}\setbox
\avmboxthree=\hbox{\avmjsortfont ##1\/}\avmjsort}%
\def\avml{\avmjprolog.}%
\def\avmr{\avmjpostlog.}%
\def\avmb##1{\node{##1}{\lbrack\;\rbrack}}%
\def\avmd##1{\node{##1}{---}}%
\def\q##1{\ifx ##1\{$\lbrace$\else
\ifx ##1\}$\rbrace$\else
\ifx ##1<$\langle$\else
\ifx ##1>$\rangle$\fi \fi \fi \fi}%
\def\{{\avmjprolog\lbrace}%
\def\}{\avmjpostlog\rbrace}%
\def\;{\hskip\avmjhskip}%
\def\avmspan##1{\multispan2\strut ##1\expandafter\hfil}%
\avmjfont
\openup\avmjvskip
\setbox\avmboxone=\hbox\bgroup\ignorespaces
} % end defn of \avm
\def\endavm{\egroup\ifvmode\leavevmode\fi % this if is useful!
\ifavmsorted\null\hskip\dimen\avmdimen\fi
\ifavmcenter
\box\avmboxone
\else \ifavmbottom
\lower.575\baselineskip\hbox{\vbox{\box\avmboxone\null}}%
\else
% the next bit is ripped off from Emma's \evnup in lingmacros.sty
\dimen2=\ht\avmboxone\advance\dimen2 by -.725\baselineskip
\lower\dimen2\box\avmboxone
\fi \fi \endgroup}
% based on TeXbook exercise 21.3
\def\avmbox#1{\setbox2=\hbox{$\scriptstyle #1$}\lower.2ex\vbox{\hrule
\hbox{\vrule\kern1.25pt
\vbox{\kern1.25pt\box2\kern1.25pt}\kern1.25pt\vrule}\hrule}}
% ============ COSTOM CONFIGURATION =============
\avmfont{\sc}
\avmoptions{sorted,active}
\avmvalfont{\rm}
\avmsortfont{\scriptsize\it}
% ===============================================

View File

@ -0,0 +1,131 @@
%% Last Modified: Thu Oct 18 18:26:25 2007.
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{style/btree}
\typeout{Document Style `weiw_BTree - Support drawing B+-Tree (ver 0.999)}
\RequirePackage{tikz}
\RequirePackage{ifthen}
% use libraries
\usetikzlibrary{arrows,shapes,decorations,matrix}
%% global declaration
\tikzstyle{btreeptr} = [draw, semithick, minimum height=2em]
\tikzstyle{btreeval} = [draw, semithick, minimum size=2em]
\tikzstyle{btreevale} = [draw,semithick, minimum size=2em]
\tikzstyle{btlink} = [draw, semithick, ->, >=triangle 45]
%% macro
%% helper macros
\newcommand{\suppressemptystr}[1]{% leave blank for entries in leaf nodes
\ifthenelse{\equal{#1}{}}%
{%
\relax%
}%
% Else
{%
#1\textsuperscript{*}%
}%
}%
\newcommand{\xyshift}[3]{% help to place the nodes
\begin{scope}[xshift=#1, yshift=#2]
#3
\end{scope}%
}
%% Common btree macros
\newcommand{\btreelink}[2]{% #1: src node; #2: dest node;
\draw[btlink] ([yshift=3pt] #1.south) -- (#2-b.north);
}
\newcommand{\btreelinknorth}[2]{% #1: src node; #2: dest node;
\draw[btlink] ([yshift=3pt] #1.south) -- (#2.north);
}
\newcommand{\btreetriangle}[2]{% #1: node name; #2 text inside
\node[anchor=north, regular polygon, regular polygon sides=3, draw] (#1) {#2};
}
%%======================================================================
%% btree with capacity = 4
\newcommand{\btreeinodefour}[5]{%
\matrix [ampersand replacement=\&] (#1)
{
\node[btreeptr] (#1-1) {\vphantom{1}}; \& \node[btreeval] (#1-a) {#2}; \&
\node[btreeptr] (#1-2) {\vphantom{1}}; \& \node[btreeval] (#1-b) {#3}; \&
\node[btreeptr] (#1-3) {\vphantom{1}}; \& \node[btreeval] (#1-c) {#4}; \&
\node[btreeptr] (#1-4) {\vphantom{1}}; \& \node[btreeval] (#1-d) {#5}; \&
\node[btreeptr] (#1-5) {\vphantom{1}}; \\
};
}
\newcommand{\btreelnodefour}[5]{%
\matrix [ampersand replacement=\&, outer sep=0pt, matrix anchor=north] (#1)
{
\node[btreevale] (#1-a) {\suppressemptystr{#2}}; \&
\node[btreevale] (#1-b) {\suppressemptystr{#3}}; \&
\node[btreevale] (#1-c) {\suppressemptystr{#4}}; \&
\node[btreevale] (#1-d) {\suppressemptystr{#5}}; \\
};
}
%%======================================================================
%% btree with capacity = 3
\newcommand{\btreeinodethree}[4]{%
\matrix [ampersand replacement=\&] (#1)
{
\node[btreeptr] (#1-1) {\vphantom{1}}; \& \node[btreeval] (#1-a) {#2}; \&
\node[btreeptr] (#1-2) {\vphantom{1}}; \& \node[btreeval] (#1-b) {#3}; \&
\node[btreeptr] (#1-3) {\vphantom{1}}; \& \node[btreeval] (#1-c) {#4}; \&
\node[btreeptr] (#1-4) {\vphantom{1}}; \\
};
}
\newcommand{\btreelnodethree}[4]{%
\matrix [ampersand replacement=\&, outer sep=0pt, matrix anchor=north] (#1)
{
\node[btreevale] (#1-a) {\suppressemptystr{#2}}; \&
\node[btreevale] (#1-b) {\suppressemptystr{#3}}; \&
\node[btreevale] (#1-c) {\suppressemptystr{#4}}; \\
};
}
%%======================================================================
%% btree with capacity = 2
\newcommand{\btreeinodetwo}[4]{%
\matrix [ampersand replacement=\&] (#1)
{
\node[btreeptr] (#1-1) {\vphantom{1}}; \& \node[btreeval] (#1-a) {#2}; \&
\node[btreeptr] (#1-2) {\vphantom{1}}; \& \node[btreeval] (#1-b) {#3}; \&
\node[btreeptr] (#1-3) {\vphantom{1}}; \\
};
}
\newcommand{\btreelnodetwo}[3]{%
\matrix [ampersand replacement=\&, outer sep=0pt, matrix anchor=north] (#1)
{
\node[btreevale] (#1-a) {\suppressemptystr{#2}}; \&
\node[btreevale] (#1-b) {\suppressemptystr{#3}}; \\
};
}
%%======================================================================
%% simple example
% \begin{center}
% \scalebox{0.7}{
% \begin{tikzpicture}
% %
% \btreeinodefour{root}{13}{17}{24}{30};
% \xyshift{-40mm}{-20mm}{\btreelnodefour{n1}{2}{3}{5}{7}}
% \xyshift{-0mm}{-20mm}{\btreelnodefour{n2}{14}{16}{}{}}
% \xyshift{40mm}{-20mm}{\btreelnodefour{n3}{19}{20}{22}{}}
% \xyshift{80mm}{-20mm}{\btreelnodefour{n4}{24}{27}{29}{}}
% \xyshift{120mm}{-20mm}{\btreelnodefour{n5}{33}{34}{38}{39}}
% %
% \foreach \x in {1,2,...,5} { \btreelink{root-\x}{n\x} }
% \end{tikzpicture}
% }
% \end{center}

View File

@ -0,0 +1,38 @@
% Source: ss17_wissschreib (Eva)
\lstset{
basicstyle=\ttfamily\scriptsize\mdseries,
keywordstyle=\bfseries\color[rgb]{0.171875, 0.242188, 0.3125},
identifierstyle=,
commentstyle=\color[rgb]{0.257813, 0.15625, 0},
stringstyle=\itshape\color[rgb]{0.0195313, 0.195313, 0.0117188},
numbers=left,
numberstyle=\tiny,
stepnumber=1,
breaklines=true,
frame=none,
showstringspaces=false,
tabsize=4,
backgroundcolor=\color[rgb]{0.98,0.98,0.98},
captionpos=b,
float=htbp,
language=Python,
xleftmargin=15pt,
xrightmargin=15pt
}
%(deutsche) Sonderzeichen
\lstset{literate=%
{Ä}{{\"A}}1
{Ö}{{\"O}}1
{Ü}{{\"U}}1
{ä}{{\"a}}1
{ö}{{\"o}}1
{ü}{{\"u}}1
{ß}{{\ss}}1
}
%Verwendung im Text:
%-> \begin{lstlisting}[language=Python,firstnumber=27] ... \end{lstlisting}
%-> \begin{lstlisting}[language=Python,numbers=none] ... \end{lstlisting}
%-> \lstinline[language=JAVA]{...}