106729382 -1Chapter 1 Data structures and Algorithms - A data structure is a systematic way of organizing and accessing data. Programming languages specify primitive data structures, ex: int, char .. as well as their operations, ex: + , -, * …etc - In Object oriented Programming Programmers, programmers design data structures using classes. - Classes bundle encapsulate data with operations that manipulate the data. - Data structures that store large collections of data are called containers. Containers have operations to access items, insert items and remove items from the collection. Arrays, Vectors, List Containers, Maps and Graphs. - Large applications call for frequent insertion and deletion of items. Arrays Vectors, list containers, maps and graphs are some of the basic data structures Applications use. - Arrays have good features such as indexing, but serious problems, ex: fixed size, elements are stored by position, insertion and deletion is difficult because it requires moving items in the list. - 0 1 2 3 4 5 Vectors allow arrays to grow ( or shrink) dynamically at run-time, but insertion and deletion is still difficult (requires moving items in the list) Vector with 6 elements: 0 1 2 3 Vector with 9 elements: 4 5 0 1 2 3 Vector with 4 elements: 4 5 6 0 1 2 3 7 8 106729382 -2- Arrays, Vectors, List Containers, Maps and Graphs (continued) - List containers allow efficient inserts and deletes but they are still only allow sequential access unless the position is known. Ex: Linked list Items are is easy to insert and delete - Maps are containers that store elements by value rather than position. Maps have a key-value relationship ( See Page 188 ) - Tree structures store elements by searching down a path from the root. Root A - Graphs – or grid of nodes and interconnecting edges are often used in applications developed by airline and communication companies. Nodes Denver er San Diego o New York Edges Chicago Las Vegas Albuquerque 106729382 -3- ADT - ABSTRACT DATA TYPE Data Abstraction is the central concept in object oriented program design. The abstract data type defines both data organization and data handling operations. The structure called abstract data type (ADT). The abstraction defines the domain along with the operations that access the data. The Abstract Data Type (ADT) is an abstract model that describes an interface between a client (user) and the data. In C++ a user defined type called class is used to represent the ADT. A class consists of members that include data values and operations. Operations specify how a client may manipulate the data. The operations are also called methods because they define methods of accessing data. A class contains two separate parts: A public part and a private part. The public part describes an interface that allows a client to manipulate objects without knowledge of the internal details of an implementation. The private part contains the data and internal operations that assist in the implementation of the data abstraction. The class encapsulates information by treating the data items and methods as a single entity. To protect the integrity of data, the class structure can be such that outside access to both data and operations is restricted. This principle is called information hiding. A master control module can access public members of an object to instruct the object to perform some activities. The process of directing an objec’s activities is referred to as message passing. The sender of the message (client code) can send appropriate information along with the message. When the object receives the message it can then change its state ( update its internal data ). The object can return data to the sender. An Item or variable of class type (i.e. instance of a class) is called an object. 106729382 -4- ADT FORMAT Example: Sequential List ADT SeqList is Data A non-negative integer specifying the number of items currently in the list (size), and a list of data items Operations // ADT Initializer Constructor Initial Values: None Process: Set the size of the list to 0 ListSize Input: Preconditions: Process: Output: Postconditions: None None Read the size of the list The list size. None ListEmpty Input: Preconditions: Process: Output: Postconditions: None None check the size of the list Return TRUE if the list is empty, otherwise return FALSE none ClearList Input: Precondition: Process Output: Postconditions: None None remove all elements from the list and set the list size to 0. None the list is empty. .................... etc ...................... Inputs: values provided by the client Preconditions - that must apply to the data before the operation is performed Process - performed by the operations Output - values that are returned to the client Postconditions - indicate any change in the data Initializer- constructor assigns initial values to the data 106729382 -5- Application: Sequential List Class Specification: A C++ is normally given by first declaring the class. The Class Declaration is a concrete representation of an ADT. Class Implementation: The Class Implementation is separate from the declaration and contains the definition of the methods. Ex: Class Specification: DECLARATION class SeqList { private: // list storage array and number of current list elements DataType listItem[ARRAYSIZE]; int size; ] public: // constructor SeqList(void); // List Access Methods int ListSize(void); int ListEmpty(void) const; int Find (DataType& item ) const; DataType GetData ( int post) const; // List modification methods void Insert ( const DataType& item ); void Delete (const DataType& item ); DataType DeleteFront ( void ); void ClearList ( void ); }; 106729382 -6- SOFTWARE REUSABILITY Object oriented approach promotes the reuse of code that has already been developed and tested. It saves development time and promotes uniformity across implementations. Objects and Inheritance Object - Oriented programming provides a mechanism by which a derived class is allowed to inherit the data and operations from a base class. This is called Class Inheritance. Example: OrderedList CLASS SPECIFICATION DECLARATION class OrderedList: public SeqList { // Inherit the SeqList class public: OrderedList (void ); // Initialize base class to // create an empty list void Insert ( const Datatype& item ); }; DESCRIPTION Insert overrides the base class method of the same name. It traverses the list inherited from the base class and inserts the item at the position that maintains ordering. 106729382 -7- Abstract Base Classes and Polymorphism Class inheritance combines with abstract base classes to create an important data structure tool. Abstract Base Classes specify the public interface of a class with its client independent of the internal implementation of a class’s data and operations. The public interface remains constant even if the internal implementation changes The abstract base class provides limited implementation details and focuses on declaration of public methods. A C++ abstract base class declares some methods as pure virtual functions The general concept of virtual functions supports inheritance by allowing two or more objects in an inheritance hierarchy to have operations with the same declarations that perform distinct tasks. This concept is called polymorphism. It allows objects from a variety of classes to respond to the same message. the receiver of the message is determined dynamically at run time. Object-oriented programming as “inheritance with runtime polymorphism. C++ supports this construct using dynamic binding and virtual member functions. When using inheritance structures in C++, operations that are dynamically bound to their objects are declared as virtual member functions ( Ex: Paint() ). Code is generated to create a table specifying the locations of an object’s virtual functions. A link is established between the object and the table . At runtime, when the location of the object is referenced, the system uses this location to gain access to the table and execute the correct function. 106729382 -8- CLASS time24 Declaration class time24 { public: time24(int h = 0, int m = 0); // constructor initializes hour and minute void addTime(int m); // update time by adding m minutes to the current time // Precondition: m must be >= 0 // Postcondition: The new time is m minutes later time24 duration(const time24& t); // return the length of time from the current time to some // later // time t as a time24 value // Precondition: time t must not be earlier than the // current time. If it is, throw a rangeError exception void readTime(); // input from the keyboard time in the form hh:mm // Postcondition: Assign value hh to hour and mm to minute // and adjust units to the proper range. void writeTime() const; // display on the screen the current time in the form hh:mm int getHour() const; // return the hour value for the current time int getMinute() const; // return the minute value for the current time private: . . . . }; 106729382 -9- Implementation of time24 Class CLASS time24 Declaration Class time24 { . . . . . private: int hour, minute; // data members // utility function sets the hour value in the range 0 to 23 // and the minute value in the range 0 to 50 void normalizeTime(); }; // *********************************************************** // time24 class implementation // *********************************************************** // set minute and hour within their proper ranges void time24::normalizeTime() { int extraHours = minute / 60; // set minute in range 0 to 59 minute %= 60; // update hour. set in range 0 to 23 hour = (hour + extraHours) % 24; } // constructor. initialize time data time24::time24(int h, int m) : hour(h), minute(m) { // put hour and minute in correct range normalizeTime(); } // add m minutes to the time void time24::addTime(int m) { // add m to minute. minute may exceed 59, so normalize minute += m; normalizeTime(); } 106729382 - 10 - Implementation of the time24Class time24 time24::duration(const time24& t) { // convert current time and time t to minutes int currTime = hour * 60 + minute; int tTime = t.hour * 60 + t.minute; // if t is earlier than the current time, throw an exception if (tTime < currTime) throw rangeError( "time24 duration(): argument is an earlier time"); else // create an anonymous object as the return value return time24(0, tTime-currTime); } void time24::readTime() { char colonSeparator; cin >> hour >> colonSeparator >> minute; // make sure hour and minute are in range normalizeTime(); } // output time in the format <hour>:<minute> void time24::writeTime() const { // save current format flags and fill character long currentFlags = cout.flags(); char currentFill = cout.fill(); // set fill char to ' ' and enable right justification cout.fill(' '); cout.setf(ios::right,ios::adjustfield); // output the hour cout << setw(2) << hour << ':'; // set fill char to '0' and output the minute cout.fill('0'); cout << setw(2) << minute << " "; // restore the fill char and the format flags cout.fill(currentFill); cout.setf(currentFlags); } int time24::getHour() const { return hour; } int time24::getMinute() const { return minute; } 106729382 - 11 Declaring and using Objects // // // // // // // File: prg1_1.cpp the program uses time24 objects to compute the cost of parking a car in a public garage at the rate is $6.00 per hour. after the user inputs the times at which a customer enters and exits the garage, the program outputs a receipt that includes the enter and exit times, the length of time the car is parked and the total charges #include <iostream> #include "d_time24.h" using namespace std; int main() { // cost of parking per hour const double PERHOUR_PARKING = 6.00; // objects designate when a car enters and leaves the garage // and the total amount of parking time time24 enterGarage, exitGarage, parkingTime; // length of billing time in hours double billingHours; cout << "Enter the times the car enters and exists the garage: "; enterGarage.readTime(); exitGarage.readTime(); // evaluate the total parking time parkingTime = enterGarage.duration(exitGarage); // evaluate the parking time in minutes billingHours = parkingTime.getHour() + parkingTime.getMinute()/60.0; // output parking receipt including time of arrival, time // of departure, total parking time, and cost of parking cout << "Car enters at: "; enterGarage.writeTime(); cout << endl; cout << "Car exits at: "; exitGarage.writeTime(); cout << endl; cout << "Parking time: "; parkingTime.writeTime(); cout << endl; cout << "Cost is $" << billingHours * PERHOUR_PARKING << endl; return 0; } /* Run: Enter the times the car enters and exists the garage: 8:30 11:00 Car enters at: 8:30 Car exits at: 11:00 Parking time: 2:30 Cost is $15 */ 106729382 - 12 Implementing a Class with inline code #ifndef RECTANGLE_CLASS #define RECTANGLE_CLASS // maintains measurement properties of a rectangle class rectangle { public: // constructor. initializes length and width rectangle(double len = 0.0, double wid = 0.0): length(len), width(wid) {} // return the area (length * width) double area() const { return length * width; } // return the perimeter (2 * (length + width)) double perimeter() const { return 2 * (length + width); } // change the dimensions of the rectangle to len and wid void setSides(double len, double wid) { length = len; width = wid; } // return the length of the rectangle double getLength() const { return length; } // return the width of the rectangle double getWidth() const { return width; } private: double length, width; }; #endif // RECTANGLE_CLASS // declare a 4 * 6 rectangle and a 0.0 by 0.0 rectangle rectangle r(4,6), s; // output perimeter of rectangle r cout << r.perimeter(); // output: 20 // set dimensions for s to the length of r and twice its // width s.setSides(r.getLenth(), 2 * r.getWidth()); cout << s.area(); // output 48 106729382 - 13 Application Programming Interface (API) Opbject Oriented Programmers have developed a documentation format that collapses the key information from the ADT and the class declaration. The documentation is called an application programming interface (API) The format includes the prototype for the constructor and public member functions of the class. It includes an action statement that describes what the operation does. See randomNumber API on page 24 in your text book. 106729382 - 14 String Class // // // // // // // File prg1_3.cpp the program prompts the user for the pathname of a file. it uses string class operations to identify and output the pathname and filename. if the filename has the extension "cpp", create and output the name of an executable file whose extension "exe" replaces the extension "cpp" #include <iostream> #include <string> using namespace std; int main() { string pathname, path, filename, executableFile; // index of '\' and '.' int backslashIndex, dotIndex; cout << "Enter the path name: "; cin >> pathname; // identify index of last '\'. note: because // escape codes such as '\n' begin with \, // C++ represents \ by '\\' backslashIndex = pathname.find_last_of('\\'); // pathname is characters prior to the last '\' path = pathname.substr(0,backslashIndex); cout << "Path: " << path << endl; // tail of pathname is the filename filename = pathname.substr(backslashIndex+1,-1); cout << "Filename: " << filename << endl; // see if the filename has the extension ".cpp". // first find the index of the last '.'. if there // is no '.', dotIndex is -1 dotIndex = filename.find_last_of('.'); // test if there is a '.' and the remaining characters are // "cpp" if (dotIndex != -1 && filename.substr(dotIndex+1) == "cpp") { // setup string executable by erasing "cpp" and appending "exe" executableFile = filename; executableFile.erase(dotIndex+1,3); executableFile += "exe"; cout << "Executable: " << executableFile << endl; } return 0; } /* 106729382 - 15 - Output: Run 1: Enter the path name: \class\programs\testfile Path: \class\programs Filename: testfile Run 2: Enter the path name: programs\strings\filedemo.cpp Path: programs\strings Filename: filedemo.cpp Executable: filedemo.exe Run 3: Enter the path name: \program.cpp Path: Filename: program.cpp Executable: program.exe */