From 45e01074bbce95eedcd6c72b9885433341eef4d6 Mon Sep 17 00:00:00 2001 From: Trygve Date: Tue, 12 Mar 2024 20:52:05 +0100 Subject: [PATCH] opprenskning --- lab_3/sequences-int/doubly-linked-list.h | 2 +- lab_3/sequences-int/dynamic-array.cpp | 47 +++++++++++++--------- lab_3/sequences-int/dynamic-array.h | 1 - lab_3/sequences-int/sequence-test.cpp | 44 ++++++++++++++++++-- lab_3/sequences-int/sequence.h | 42 ------------------- lab_3/sequences-int/singly-linked-list.cpp | 2 +- lab_3/sequences-int/singly-linked-list.h | 3 +- 7 files changed, 70 insertions(+), 71 deletions(-) delete mode 100644 lab_3/sequences-int/sequence.h diff --git a/lab_3/sequences-int/doubly-linked-list.h b/lab_3/sequences-int/doubly-linked-list.h index f3126f7..12b293d 100644 --- a/lab_3/sequences-int/doubly-linked-list.h +++ b/lab_3/sequences-int/doubly-linked-list.h @@ -2,8 +2,8 @@ #define DOUBLY_LINKED_LIST_H #include +#include #include "queue.h" -#include "sequence.h" namespace seq { diff --git a/lab_3/sequences-int/dynamic-array.cpp b/lab_3/sequences-int/dynamic-array.cpp index 8e6a601..d0226a2 100644 --- a/lab_3/sequences-int/dynamic-array.cpp +++ b/lab_3/sequences-int/dynamic-array.cpp @@ -1,6 +1,8 @@ #include #include +#include +#include "queue.h" #include "dynamic-array.h" using namespace seq; @@ -14,7 +16,6 @@ void DynamicArray::clear() this->capacity = 0; } -// insert an item at index i void DynamicArray::enqueue(int value) { int i = this->logical_size; @@ -40,7 +41,7 @@ void DynamicArray::enqueue(int value) // copy all of temp_storage into values[i+1] to values[logical_size] std::copy(temp_storage, temp_storage + shifted_elements, &this->values[i+1]); - delete temp_storage; + delete[] temp_storage; } // now we can write the inserted item into values[i] @@ -48,29 +49,35 @@ void DynamicArray::enqueue(int value) this->values[i] = value; } -// remove the item at index i int DynamicArray::dequeue() { - int i = 0; - // shift all elements from index i+1 onward one to the left - // we use a temporary storage and copy() from to do this efficiently - size_t shifted_elements = this->logical_size - i - 1; - if(shifted_elements > 0) - { - int* temp_storage = new int[shifted_elements](); - - // copy values[i+1] to values[logical_size-1] into temp_storage - std::copy(this->values + i+1, this->values + this->logical_size, temp_storage); - - // copy all of temp_storage into values[i] to values[logical_size-2] - std::copy(temp_storage, temp_storage + shifted_elements, &this->values[i]); - delete temp_storage; + if (this->size() == 0) { + return 0; } - this->logical_size--; // with this, we are done with the task + int i = 0; + // Save the first element wich we want to return: + int outgoing = this->values[0]; - // now let us see whether we have deleted so many items that we should resize to save memory - if(this->capacity/2 >= this->logical_size) this->resize(this->capacity/2); + // shift all elements from onward one to the left + size_t shifted_elements = this->logical_size - 1; + + int* temp_storage = new int[shifted_elements](); + + // copy values[i+1] to values[logical_size-1] into temp_storage + std::copy(this->values + 1, this->values + this->logical_size, temp_storage); + + // copy all of temp_storage into values[i] to values[logical_size-2] + std::copy(temp_storage, temp_storage + shifted_elements, &this->values[i]); + delete[] temp_storage; + if (!this->empty()) { + this->logical_size--; // with this, we are done with the task + + // now let us see whether we have deleted so many items that we should resize to save memory + if(this->capacity/2 >= this->logical_size) this->resize(this->capacity/2); + + } + return outgoing; } // allocate static array with "new_capacity" elements, diff --git a/lab_3/sequences-int/dynamic-array.h b/lab_3/sequences-int/dynamic-array.h index feb9630..c67b1f9 100644 --- a/lab_3/sequences-int/dynamic-array.h +++ b/lab_3/sequences-int/dynamic-array.h @@ -1,5 +1,4 @@ #include "queue.h" -#include "sequence.h" namespace seq { diff --git a/lab_3/sequences-int/sequence-test.cpp b/lab_3/sequences-int/sequence-test.cpp index 95fa959..b09512a 100644 --- a/lab_3/sequences-int/sequence-test.cpp +++ b/lab_3/sequences-int/sequence-test.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "dynamic-array.h" #include "queue.h" @@ -12,11 +13,19 @@ namespace /* * run a simple test */ - void test_sequence(seq::Queue* sqn, int n, int m, std::ostream* os) + void test_queue(seq::Queue* sqn, int n, int m, std::ostream* os) { assert((m > 0) && (n > m)); if(os) *os << "Enqueue even numbers from 0 to " << 2*(n-1) << ".\n"; for(int i = 0; i < n; i++) sqn->enqueue(2*i); + for(int i = 0; i < n; i++) sqn->dequeue(); + } + void test_queue(std::queue* sqn, int n, int m, std::ostream* os) + { + assert((m > 0) && (n > m)); + if(os) *os << "Enqueue even numbers from 0 to " << 2*(n-1) << ".\n"; + for(int i = 0; i < n; i++) sqn->push(2*i); + for(int i = 0; i < n; i++) sqn->pop(); } /* @@ -24,16 +33,38 @@ namespace */ float test_with_time_measurement(seq::Queue* sqn, int iterations) { - int sequence_length = 200001; + int queue_length = 20001; int deletions = 10; - test_sequence(sqn, sequence_length, deletions, &std::cout); + test_queue(sqn, queue_length, deletions, &std::cout); int log_entries = 10; std::cout << "\nNow repeat the above " << iterations << " times:\n"; auto t0 = std::chrono::high_resolution_clock::now(); for(int i = 0; i < iterations; i++) { - test_sequence(sqn, sequence_length, deletions, nullptr); + test_queue(sqn, queue_length, deletions, nullptr); + if((i+1) % (iterations/log_entries) == 0) + { + std::cout << "\t" << i+1 << "\n"; + std::cout.flush(); // make sure that status output is shown without delay + } + } + auto t1 = std::chrono::high_resolution_clock::now(); + return 1.0e-06 * std::chrono::duration_cast(t1-t0).count(); + } + + float test_with_time_measurement(std::queue* sqn, int iterations) + { + int queue_length = 20001; + int deletions = 10; + test_queue(sqn, queue_length, deletions, &std::cout); + + int log_entries = 10; + std::cout << "\nNow repeat the above " << iterations << " times:\n"; + auto t0 = std::chrono::high_resolution_clock::now(); + for(int i = 0; i < iterations; i++) + { + test_queue(sqn, queue_length, deletions, nullptr); if((i+1) % (iterations/log_entries) == 0) { std::cout << "\t" << i+1 << "\n"; @@ -61,7 +92,12 @@ int main() seq::DoublyLinkedList dll; float dll_time = test_with_time_measurement(&dll, iterations); + std::cout << "\n\n*** test with std::queue ***\n"; + std::queue queue; + float queue_time = test_with_time_measurement(&queue, iterations); + std::cout << "\n\nRuntime for dynamic array:\t" << dyna_time << " s\n"; std::cout << "Runtime for singly linked list:\t" << sll_time << " s\n"; std::cout << "Runtime for doubly linked list:\t" << dll_time << " s\n"; + std::cout << "Runtime for std::queue:\t" << queue_time << " s\n"; } diff --git a/lab_3/sequences-int/sequence.h b/lab_3/sequences-int/sequence.h deleted file mode 100644 index 2151e68..0000000 --- a/lab_3/sequences-int/sequence.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef SEQUENCE_H -#define SEQUENCE_H - -#include - -namespace seq -{ - class Sequence - { - public: - virtual bool empty() const = 0; // test whether the sequence is empty - virtual size_t size() const = 0; // return the size (number of items in the sequence) - - // it is the caller's responsibility to ensure that the sequence is not empty when calling front() or back()! - virtual int& front() = 0; // return a reference to the first item - virtual int& back() = 0; // return a reference to the final item - - // return a reference to the item at position i of the sequence, counting from 0 - // it is the caller's responsibility that the index is within range - virtual int& at(int i) = 0; - - /* - * accepts an additional item into the sequence (front or back); - * the pushed item is passed by reference, but a copy of it is stored in the Sequence - * the Sequence takes ownership of the copy (but not of the original!) - */ - virtual void push(const int& pushed_item) = 0; // default push operation (front or back) - virtual void push_front(const int& pushed_item) = 0; - virtual void push_back(const int& pushed_item) = 0; - - virtual void pop() = 0; // default pop operation (front or back) - virtual void pop_front() = 0; // remove the first element - virtual void pop_back() = 0; // remove the last element - virtual void clear() = 0; // remove all the items from the sequence - - // it is the caller's responsibility that the index is within range - virtual void insert_at(int i, const int& inserted_item) = 0; // insert an item at index i - virtual void erase_at(int i) = 0; // remove the item at index i - }; -} - -#endif diff --git a/lab_3/sequences-int/singly-linked-list.cpp b/lab_3/sequences-int/singly-linked-list.cpp index b44f4e6..cb3441c 100644 --- a/lab_3/sequences-int/singly-linked-list.cpp +++ b/lab_3/sequences-int/singly-linked-list.cpp @@ -1,5 +1,5 @@ +#include #include "singly-linked-list.h" -#include using namespace seq; diff --git a/lab_3/sequences-int/singly-linked-list.h b/lab_3/sequences-int/singly-linked-list.h index 56e96a2..5ce638d 100644 --- a/lab_3/sequences-int/singly-linked-list.h +++ b/lab_3/sequences-int/singly-linked-list.h @@ -2,7 +2,6 @@ #define SINGLY_LINKED_LIST_H #include -#include "sequence.h" #include "queue.h" namespace seq @@ -36,7 +35,7 @@ namespace seq bool empty() const { return (this->head == nullptr); } // test whether the singly linked list is empty size_t size() const; // return the size (number of items in the singly linked list) - void enqueue(int element); + void enqueue(int value); int dequeue(); void clear() { while(!this->empty()) this->dequeue(); } // remove all the items from the list