Arrays, Vectors, List Containers, Maps and Graphs (continued)

advertisement
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
*/
Download