From 214142583b8e6f2c47eafc96c6ac79fe74fc1079 Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Tue, 20 Feb 2018 10:09:12 -0800 Subject: [PATCH] Finish ArrayStack. --- ods/data/Makefile.am | 18 ------------------ ods/notes/chapter2.txt | 12 ++++++++++++ ods/src/array_test.cc | 7 +++++++ ods/src/ods/array_stack.h | 30 ++++++++++++++++++++++++++---- 4 files changed, 45 insertions(+), 22 deletions(-) delete mode 100644 ods/data/Makefile.am diff --git a/ods/data/Makefile.am b/ods/data/Makefile.am deleted file mode 100644 index e324dbe..0000000 --- a/ods/data/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -pkgdata_DATA = corpus.txt ods-cpp/main.cpp ods-cpp.pdf - -corpus.txt: corpus.txt.gz - gzip -d -k $@.gz - -ods-cpp/main.cpp: ods-cpp.tgz - tar xzf ods-cpp.tgz - -ODS_SAMPLE_CODE_URL := http://opendatastructures.org/ods-cpp.tgz -ods-cpp.tgz: - if command -v curl 2>&1 > /dev/null ; then curl -L -O $(ODS_SAMPLE_CODE_URL) ; \ - elif command -v curl 2>&1 > /dev/null ; then wget $(ODS_SAMPLE_CODE_URL) ; fi - -ODS_PDF_URL := http://opendatastructures.org/ods-cpp.pdf -ods-cpp.pdf: - if command -v curl 2>&1 > /dev/null ; then curl -L -O $(ODS_PDF_URL) ; \ - elif command -v curl 2>&1 > /dev/null ; then wget $(ODS_PDF_URL) ; fi - diff --git a/ods/notes/chapter2.txt b/ods/notes/chapter2.txt index 9ef8889..6152937 100644 --- a/ods/notes/chapter2.txt +++ b/ods/notes/chapter2.txt @@ -19,3 +19,15 @@ resizing isn't too bad. * Uses backing array *a*. * Typically, the array will be larger than necessary, so an element *n* is used to track the actual number of elements stored in the stack. +* Add and remove requires shifting all the elements after i (O(n - i) + complexity), ignoring potential calls to resize +* Resizing is triggered when we run out of room in an add or when a remove + brings us to the point where the array is more than 3n elements +* Resizing creates a new array of size 2n and copies all the elements over; + this then has complexity O(n). +* The analysis of add and remove didn't consider cost of resize. +* An amortised analysis is done instead that considers the cost of all calls + to add and remove, given a sequence of *m* calls to either. +* Lemma: if an empty ArrayStack is created and any sequence of *m* >= 1 calls + to add and remove are performed, the total time spent in calls to resize is + O(m). diff --git a/ods/src/array_test.cc b/ods/src/array_test.cc index ef3c8c8..aaefb9c 100644 --- a/ods/src/array_test.cc +++ b/ods/src/array_test.cc @@ -23,4 +23,11 @@ main(void) cout << "as[1] " << as.get(1) << endl; as.remove(0); cout << "as[0] " << as.get(0) << endl; + + cout << "size: " << as.size() << ", cap: " << as.cap() << endl; + as.add(0, 47); + as.add(0, 11); + as.add(0, 17); + as.add(0, 1); + cout << "size: " << as.size() << ", cap: " << as.cap() << endl; } diff --git a/ods/src/ods/array_stack.h b/ods/src/ods/array_stack.h index 952a0c5..5449576 100644 --- a/ods/src/ods/array_stack.h +++ b/ods/src/ods/array_stack.h @@ -11,9 +11,13 @@ template class ArrayStack { public: ArrayStack(int len) : n(0), a(Array(len)) {} - int size(void) { return a.length; } + int size(void) { return n; } + int cap(void) { return a.length; } T get(int i) { return a[i]; } - T set(int i, T x) { + T set(int i, T x) { + if (i > n) { + n = i+1; + } T y = a[i]; a[i] = x; return y; @@ -35,7 +39,6 @@ public: T remove(int i) { T x = a[i]; for (int j = i; j < (n-1); j++) { - std::cout << j << "\t" << i << "\t" << a[j] << std::endl; a[j] = a[j+1]; } n--; @@ -47,7 +50,26 @@ public: return x; } - void resize(void) {} + static inline int max(int x, int y) { + return x > y ? x : y; + } + + void resize(void) { + int nlen = max(2 * n, 1); + Array b(nlen); + for (int i = 0; i < n; i++) { + b[i] = a[i]; + } + a = b; + } + + T pop(void) { + return a.remove(n - 1); + } + + void push(T x) { + return a.add(n, x); + } private: int n; Array a;