& myArray) os << myArray.toString(); return os;"> & myArray) os << myArray.toString(); return os;">
Download presentation
Presentation is loading. Please wait.
1
Lab 03 - Iterator
2
Step 1 – int Array Class Software Design #include <iostream>
#include <string> #include <sstream> #define MAX_ARRAY_SIZE using namespace std; class MyArray { private: int size_; int* array_; public: MyArray(const int array_size) : size_(0) { array_ = (int*)malloc(array_size * sizeof(int)); } void push_back(int item) { array_[size_++] = item; }; }; int main(int argc, char * argv[]) { MyArray numbers(MAX_ARRAY_SIZE); numbers.push_back(1); numbers.push_back(2); numbers.push_back(3); numbers.push_back(4); cout << numbers << endl; return 0; } string toString() const { stringstream out; out << "myArray"; for (int i = 0; i < size_; i++) out << ((i % 10) ? " " : "\n") << array_[i]; return out.str(); } friend std::ostream& operator<< (ostream& os, const MyArray<T>& myArray) os << myArray.toString(); return os;
3
Step 2 – Template Class Software Design #include <iostream> #include <string> #include <sstream> #define MAX_ARRAY_SIZE using namespace std; template<typename T> class MyArray { private: int size_; T* array_; public: MyArray(const int array_size) : size_(0) { array_ = (T*)malloc(array_size * sizeof(T)); } void push_back(T item) { array_[size_++] = item; }; }; int main(int argc, char * argv[]) { MyArray<int> numbers(MAX_ARRAY_SIZE); numbers.push_back(1); numbers.push_back(2); numbers.push_back(3); numbers.push_back(4); cout << numbers << endl; return 0; } Templates are a feature of the C++ programming language that allows functions and classes to operate with generic types, allowing a function or class to work on many different data types without being rewritten for each one. There are three kinds of templates: function templates, class templates and, since C++14, variable templates.
4
Step 3 – Add an Iterator MyArray Iterator Software Design
#include <iostream> #include <string> #include <sstream> #define MAX_ARRAY_SIZE using namespace std; template<typename T> class MyArray { private: int size_; T* array_; public: MyArray(const int array_size) : size_(0) { array_ = (int*)malloc(array_size * sizeof(int)); } void push_back(T item) { array_[size_++] = item; }; class Iterator int index_; Iterator(T* a) : array_(a), index_(0) {} T& operator[](int i) const { return array_[i]; } }; Iterator begin() { return MyArray<T>::Iterator(array_); } int main(int argc, char * argv[]) { MyArray<int> numbers(MAX_ARRAY_SIZE); numbers.push_back(1); numbers.push_back(2); numbers.push_back(3); numbers.push_back(4); MyArray<int>::Iterator iter = numbers.begin(); for (int i = 0; i < 4; ++i) cout << iter[i] << ' '; cout << endl << endl; return 0; } MyArray Iterator Nested classes can access all members of the parent via a reference/pointer
5
Step 4 – Add Functionality
Software Design #include <iostream> #include <string> #include <sstream> #define MAX_ARRAY_SIZE using namespace std; template<typename T> class MyArray { private: int size_; T* array_; public: MyArray(const int array_size) : size_(0) { array_ = (int*)malloc(array_size * sizeof(int)); } void push_back(T item) { array_[size_++] = item; }; class Iterator int index_; Iterator(T* a) : array_(a), index_(0) {} T& operator[](int i) const { return array_[index_ + i]; } T& operator*() const { return array_[index_]; } Iterator operator++(T) { Iterator tmp(*this); ++index_; return tmp; } }; Iterator begin() { return MyArray<T>::Iterator(array_); } int main(int argc, char * argv[]) { MyArray<int> numbers(MAX_ARRAY_SIZE); numbers.push_back(1); numbers.push_back(2); numbers.push_back(3); numbers.push_back(4); MyArray<int>::Iterator iter = numbers.begin(); for (int i = 0; i < 4; ++i) cout << *iter++ << ' '; cout << endl << endl; return 0; }
6
2.6, pgs. 170-179 2.6 Efficiency of Algorithms 170 Big-O Notation 172
Comparing Performance 176 Algorithms with Exponential and Factorial Growth Rates 178 2.6, pgs
7
Big-O Notation Software Design Understanding how the execution time (and memory requirements) of an algorithm grow as a function of increasing input size gives programmers a tool for comparing various algorithms and determining how they will perform. If the execution time stays the same regardless of the number of inputs, then the growth rate is of order 1. If the execution time approximately doubles when the number of inputs, n, doubles, then the algorithm grows at a linear rate or a growth rate of order n. If the execution time is approximately quadrupled when the number of inputs is doubled, then the algorithm grows at a quadratic rate or at a growth rate of order of n2.
8
Big-O Notation Software Design Consider the following functions with respect to execution: n times for (int i = 0; i < n; i++) { // Statement(s) }
9
Big-O Notation Software Design Consider the following functions with respect to execution: n times for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) // Statement(s) } (n m) times
10
Big-O Notation Software Design Consider the following functions with respect to execution: n times (n m) times for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) // Statement(s) } (n2) times
11
Big-O Notation Software Design Consider the following functions with respect to execution: n times (n m) times (n2) times for (int i = 0; i < n - 1; i++) { for (int j = i + 1; j < n; j++) // Statement(s) } (n log n) times
12
Big-O Notation Software Design Consider the following functions with respect to execution: n times (n m) times (n2) times (n log n) times. Computer scientists use the notation O(n) to represent the first case O(n m) to represent the second O(n2) to represent the third O(n log n) to represent the fourth The symbol O can be thought of as an abbreviation for “order of magnitude” and is called big-O notation.
13
Big-O Notation Software Design A simple way to determine the big-O of an algorithm or program is to look at any loops and to see whether the loops are nested. Assuming that the loop body consists only of simple statements, a single loop is O(n) a nested loop is O(n2) a nested loop in a nested loop is O(n3), and so on The growth rate of f(n) will be determined by the fastest growing term, which is the one with the largest exponent. In general, it is safe to ignore all constants and to drop the lower-order terms when determining the order of magnitude.
14
Big-O Example T(n) = n2 + 3n + 9 void T(int n) {
Software Design void T(int n) { for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) // Simple Statement; } // Simple Statement 1; // Simple Statement 2; // Simple Statement 3; // ... // Simple Statement 8; // Simple Statement 9; The outer loop will execute n times. The inner loop will execute n times for each outer loop iteration. We can conclude that the relationship between processing time and n (the number of Simple Statements processed) is: T(n) = n2 + 3n + 9 The loop will execute 3 Simple Statements n times Finally, 9 Simple Statements are executed.
15
Formal Definition of Big-O
Software Design T(n) is the Big-O of f(n) if there exists two constants, n0 and c, greater than zero, such that for all n > n0, c T(n) >= f(n). In other words, as n get sufficiently large (larger than n0), there is some constant c for which the processing time will always be greater than or equal to f(n). Given f(n) = n2 + 3n + 9, show that this is O(n2). Find constants n0 and c such that for all n > n0, cn2 > n2 + 3n + 9 (ie. find the point where cn2 = n2 + 3n + 9). Let n = n0, and solve for c c = / n0 + 9 / n02 When n0 is 3, this gives us a c of 3. So, 3n2 > n2 + 3n + 9 for all n > 3
16
is more simply expressed as n > n0, c T(n) >= f(n)
Software Design An algorithm of O(n2 + 3n + 9) is more simply expressed as O(n2) 3n2 n > n0, c T(n) >= f(n) n2 + 3n + 9
17
Software Design The growth rate of f(n) will be determined by the fastest growing term, which is the one with the largest exponent. In the example, an algorithm of O(n2 + 3n + 9) is more simply expressed as O(n2). In general, it is safe to ignore all constants and to drop the lower-order terms when determining the order of magnitude. Basic Rules: Nested loops are multiplied together. Sequential loops are added. Only the largest term is kept, all others are dropped. Constants are dropped. Conditional checks are constant (i.e. 1).
18
Common Growth Rates Software Design
19
Effects of Different Growth Rates
Software Design Algorithms with exponential and factorial growth rates have an effective practical limit on the size of the problem they can be used to solve. With an O(2n) algorithm, if 100 inputs takes an hour then, 101 inputs will take 2 hours 105 inputs will take 32 hours 114 inputs will take 16,384 hours (almost 2 years!) Encryption algorithms take advantage of this characteristic: Some cryptographic algorithms can be broken in O(2n) time, where n is the number of bits in the key. A key length of 40 is considered breakable by a modern computer. A key length of 100 bits will take a billion-billion (1018) times longer than a key length of 40.
20
O(n) O(n) O(1) O(n2) O(nlog(n)) O(2n) Software Design
for (int i = 0; i < n; i++) { cout << i << endl; } for (int i = 0; i < size; i++) { cout << arr[i] << endl; } O(n) O(n) { cout << i << endl; } O(1) for (int i = 0; i < n + 1; i++) { for (int j = i + 1; j < n; j++) //do swap stuff, constant time } for (int i = 0; i < size; i++) { cout << a[i] << endl; } for (int j = 0; j < size; j++) cout << a[i] + a[j] << endl; O(n2) O(nlog(n)) int fib(int num) { if (num <= 1) return num; return fib(num - 2) + fib(num - 1); } O(2n)
21
Sequential Containers
Chapter 4 Sequential Containers
22
Objectives Software Design To become familiar with the Standard Template Library (STL) and template classes. To understand how to use a vector class and how to implement it using an array for storage. To understand the difference between a shallow copy and deep copy. To introduce linked lists and study the differences between single-, double-, and circular linked list data structures. To introduce structs. So far we’ve considered one data structure — the array. The C++ developers have provided more tools for programmers by providing a rich set of data structures written as C++ template classes. These template classes are all part of the Standard Template Library (STL). In this chapter we discuss the STL classes called sequences.
23
Sequence Classes Software Design A sequence has the property that elements can be inserted or removed anywhere in the sequence, not just at the beginning or at the end. Some sequences are indexed, which means their elements can be accessed in arbitrary order (called random access) using a subscript to select an element. For other sequences you must start at the beginning and process the elements in order. Iterators facilitate sequential access and random access. Rhe vector and list (linked list) classes and their similarities and differences . These classes implement the common interface requirements for sequential containers.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.