SlideShare a Scribd company logo
CS 23001 Computer Science II: Data Structures & Abstraction
Project #4
Spring 2015
Objectives:
· Develop and use a Tree ADT (n-ary)
· Apply and use tree traversal algorithms
· Manipulate trees by inserting and deleting nodes
· Apply and use STL
Problem:
Build a program profiler. Construct a program to instrument
C++ source code to support program profiling.
It is often important to determine how many times a function or
statement is executed. This is useful not only for debugging but
for determining what parts of a program may need to be
optimized. This process is called profiling. That is, a execution
profile presents how many times each part of a program is
executed using a given set of input data (or for some run time
scenario). To compute a profile, statements need to be added to
the code that keep track of how many times a function or
statement is executed. The process of adding these statements is
called instrumenting the code.
To implement a profiler one must first parse the source code
and generate an Abstract Syntax Tree (AST) of the code. Each
node of the AST describes the syntactic category of the code
stored within it (function, statement, while-statement, etc.). So
at the top level is a syntactic category corresponding to a
program, class, or function (such as in the case of a main).
Under that are sub-trees that further detail the syntactic
categories of each part of the code. Such things as declarations,
parameter lists, while-statement, and expression statements will
describe the various parts of the program.
After the AST is generated it can then be traversed and the
appropriate syntactic structures can be found that need to be
instrumented. Once a construct is found, say a function, new
code can be inserted that keeps track of how many times that
function is executed.
The most difficult part of constructing a profiler is correctly
parsing the source code. Unfortunately, C++ is notoriously
difficult to parse. So here we will use a parsing tool called
src2srcml. This tool reads in C++ code and marks up the code
with XML tags (e.g., block, if, while, condition, name, etc).
That is, the output is an AST in XML. The XML representation
is called srcML (source code markup language).
A number of srcML data files are provided for the project.
However, you can use your own program as input. To run srcML
on wasp or hornet you will first need to set a PATH variable so
the command can be found. You need to execute the command:
export PATH=/local/opt/srcml/bin:$PATH
It is best if you insert this line into your .bash_profile file in
your home directory on wasp/hornet.
Then to generate the srcML file for your own code use the
following:
src2srcml main.cpp -o main.cpp.xml
Use the following for a list of all options:
src2srcml --help
More information about srcML can be found at www.srcML.org
including a list of all the tag names (see Getting Started). You
can also download srcML if you want it on your own machine.
Your program will read in srcML files (in XML) and build an
internal representation of the AST as a tree data structure. When
using XML this internal representation is typically called a
Document Object Model (DOM). A set of classes defining the
data structure (DOM) is in shared (ASTree.hpp and
ASTree.cpp). This part of the project is partially implemented
(i.e., the read and write work). The given code compiles and
runs. The program currently is able to read in a srcML file and
construct the internal tree representation. It can also write the
code (without XML) back out from the internal tree
representation. Your job will be to complete the implementation
and build the insturmenter for the profiler.
The specification for the profiler is as follows:
· The program will take as input a list of files that are to be
profiled. The first file in the list will be the main body.
· The program will instrument all the files to keep track of each
function and statement executed in the program.
· The program will also instrument the main body with two
additional parts. The first is a set of global profiling variables.
Second, at the end of the main body the results of the profiling
data will be printed to an output file (or the screen if none is
supplied).
· Profile how many times each function or method in the
supplied files is executed. Keep track of this by the filename,
line number, and function name.
· Profile how many times each statement is executed. Keep
track of this by filename and line number. Include all statements
ending with a semicolon (e.g., assignments, function calls) and
all statements within loops, if/else, and case statement.
· Do not count break, return, goto, or throw statements.
· Do not count declaration statements.
· Do not count statement in for-loop specifications. For
example, don't count the i=0, i==n, or ++i in for (i=0; i==n;
++i).
· Do not count conditions (but see challenge). That is, only
count statements in the bodies of if-stmts or loop-stmts and not
how many times the condition is executed.
· You do not need to worry about following any formating style
(indentation, etc.) for the inserted code.
· Output: For each file print out, ordered by line number, the
counts for each line and function.
In short, your profiler program will read in source code and
write out source code that has been insturmented. Then you will
compile and run the insturmented version of the code to get the
profile information.
Requirements:
· Part 1 - 30 pts
· Implementation:
· Read the code given in ASTree.hpp/cpp, profile.hpp/cpp, and
main.cpp under shared. You will be required to add code and
comments to these files. You are free to modify them as you see
fit.
· The provided code works (compiles and runs) and the read and
write are implemented.
· Implement the necessary 1) destructor, 2) copy constructor, 3)
swap, and 4) assignment operator for the ASTree class. There
are comments pointing out which methods still need to be
implemented.
· The code uses STL and you may use STL in your solution,
including std::string.
· Testing:
· Test all the methods you implement by providing code that
calls all the methods.
· Use the provided makefile: make profiler
· Part 2 - 30 pts
· Implementation:
· Use the provided profile ADT (profile.hpp/cpp). This is a
simple ADT that uses the STL map data type. It is a map of
(string X int). With the string being the function name and line
number and the integer being the count of times that
line/function was executed.
· To profile the program you will need to create a profile object
for each file (as given on the command line) to keep track of
statements and functions. These will be inserted as code into the
main as global variable declarations. The main is the first file
given in the input.
· All profile objects need to be declared in the main and for
each additional file you will need to include profile.hpp and
declare the file's profile object as external, for example extern
foo_cpp;
· Your profiler only needs to work on cpp files. You do not
need to insturment header files (.h, .hpp).
· For debugging there is a flag called TAGS in ASTree.hpp. If
you set this to true the tags of the abstract syntax tree will be
printed. This gives a view of the data structure.
· Implement the functionality to insert profile declarations into
the main file. You will need this for part 3. For example given
the following main:
·
· //File main1.cpp
· #include <iostream>
·
· int main() {
· int i = 0;
· while (i < 10) {
· ++i;
· std::cout << i;
· }
· return 0;
}
· The profiler will need to insert something like the following
lines of code, minus comments (in red):
·
· //File main1.cpp
· #include <iostream>
·
· #include "profile.hpp" //include your profile
ADT
· profile main1_cpp("main1.cpp"); //Profile object for
counting lines in main1.cpp
·
· int main() {
· int i = 0;
· while (i < 10) {
· ++i;
· std::cout << i;
· }
· return 0;
}
· Testing:
· Test the profile ADT.
· Test the insertion of code into the main.
· Part 3 - 40 pts
· Implementation:
· For every function, insert a line of code to update the
corresponding file profile object given the function name and
line number. The line number is used to provide a unquie map
index for overloaded functions. This will add one to the
corresponding map element. Insert this code as the first line in
the function, right after the { is fine. You may assume there are
no nested functions.
· For every line of code (as defined above) add a line of code
after it that updates the correct file profile object given the line
number. Use the __LINE__ macro for this. This macro returns
an integer and you will need to convert this value to a string for
use in your profile ADT.
· You may ASSUME all loops and conditionals have a block.
That is, no single line bodies. For example, there will always be
a block after a loop as in for (i=0; i==n; ++i) { x=x+1; } versus
no block as in for (i=0; i==n; ++i) x=x+1;.
· Lastly, you will need to add statements to the end of the main
to print out the profile data. This should go just before the
return. You may assume there is only one return in the main.
This report should print each item in the map (function or line
number) followed by the counts.
· Your profiler only needs to work on cpp files. You do not
need to insturment header files (.h, .hpp).
· You should send the profiler output for each input file to a
new file. Prefix a "p-" to the begining of the orginal file name.
For example: p-main.cpp or p-ASTree.cpp
· Given profiler main1.cpp foo.cpp the final code will look
something like the following for file p-main1.cpp:
·
· //File: main1.cpp
· #include <iostream>
·
· #include "profile.hpp"
· profile foo_cpp("foo.cpp");
· profile main1_cpp("main1.cpp");
·
· int main() { main1_cpp.count(__LINE__, "main");
· int i;
· i = 0; main1_cpp.count(__LINE__);
· while (i < 10) {
· ++i; main1_cpp.count(__LINE__);
· std::cout << i; main1_cpp.count(__LINE__);
· }
· std::cout << foo_cpp << std::endl;
· std::cout << main1_cpp << std::endl;
· return 0;
}
· And p-foo.cpp
·
· //File foo.cpp
·
· #include "profile.hpp"
· extern profile foo_cpp;
·
· int foo() { foo_cpp.count(__LINE__, "foo");
· int i;
· i = 0; foo_cpp.count(__LINE__);
· return i;
}
· Testing:
· Your profiler application must be able to work with the
provided source code, a sorting application.
· Run the application for all three algorithm and compare the
profiles.
· ./sorting -bs -sz 100 -od -osd
· The makefile can build the profiler, sort, and profiled sort (p-
sort).
· Challenge - 5 pts extra credit
· Profile all conditionals.
· Count the number of times the conditional in a while, if, for,
repeat, or switch is executed.
· For example, given the following code:
·
· i = 0; //Line 1
· while (i < 10) { //Line 2
· ++i; //Line 3
}
· If this code is run only one time, it will have Line 1 executing
1 time, Line 2 (the conditional) executing 11 times, and Line 3
executing 10 times.
· These should be stored by file and line number but in a
separate profile object (conditionals) for each file.
· Hint: use operator&& or operator,
· Other Requirements:
· You must have a separate specification file (.hpp),
implementation file (.cpp), and main file.
· Your program will be graded on programming and commenting
style as well as the implementation of your ADT.
· Include all source code files in svn.
· See the grading policy for other requirements.
ASTree.cppASTree.cpp/*
* ASTree.cpp
* Abstract Syntax Tree
*
* Created by Jonathan Maletic on 11/8/11.
* Copyright 2013 Kent State University. All rights reserved.
*
* Modified by:
*
*/
#include"ASTree.hpp"
/////////////////////////////////////////////////////////////////////
// Copy constructor for srcML
//
srcML::srcML(const srcML& actual){
tree =newASTree(*(actual.tree));
}
/////////////////////////////////////////////////////////////////////
// Constant time swap for srcML
//
void srcML::swap(srcML& b){
std::string t_header = header;
header = b.header;
b.header = t_header;
ASTree*temp = tree;
tree = b.tree;
b.tree = temp;
}
/////////////////////////////////////////////////////////////////////
// Assignment for srcML
//
srcML& srcML::operator=(srcML rhs){
swap(rhs);
return*this;
}
/////////////////////////////////////////////////////////////////////
// Reads in and constructs a srcML object.
//
std::istream&operator>>(std::istream& in, srcML& src){
char ch;
if(!in.eof()) in >> ch;
src.header = readUntil(in,'>');
if(!in.eof()) in >> ch;
if(src.tree)delete src.tree;
src.tree =newASTree(category, readUntil(in,'>'));
src.tree->read(in);
return in;
}
/////////////////////////////////////////////////////////////////////
// Prints out a srcML object
//
std::ostream&operator<<(std::ostream& out,const srcML& src){
if(TAGS) out <<"<"<< src.header <<">"<< std::endl;
src.tree->print(out,0);
return out;
}
/////////////////////////////////////////////////////////////////////
// Adds in the includes and profile variables
//
void srcML::mainHeader(std::vector<std::string>& profileName
s){
tree->mainHeader(profileNames);
}
/////////////////////////////////////////////////////////////////////
// Adds in the includes and profile variables
//
void srcML::fileHeader(std::vector<std::string>& profileNames
){
tree->fileHeader(profileNames);
}
/////////////////////////////////////////////////////////////////////
// Adds in the report to the main.
//
void srcML::mainReport(std::vector<std::string>& profileName
s){
tree->mainReport(profileNames);
}
/////////////////////////////////////////////////////////////////////
// Inserts a function.count() into each function body.
//
void srcML::funcCount(){
tree->funcCount();
}
/////////////////////////////////////////////////////////////////////
// Inserts a filename.count() for each statement.
//
void srcML::lineCount(const std::string& profilename){
tree->lineCount(profilename);
}
/////////////////////////////////////////////////////////////////////
// Constructs a category, token, or whitespace node for the tree.
//
ASTree::ASTree(nodes t,const std::string& s){
nodeType = t;
switch(nodeType){
case category:
tag = s;
break;
case token:
text = unEscape(s);
break;
case whitespace:
text = s;
break;
}
}
///
/// NOTE: Can implement destructor implemented in .h file or h
ere.
///
/////////////////////////////////////////////////////////////////////
// Copy Constructor for ASTree
//
ASTree::ASTree(constASTree& actual){
//NEED TO IMPLEMENT
}
/////////////////////////////////////////////////////////////////////
// Constant time swap for ASTree
//
voidASTree::swap(ASTree& b){
//NEED TO IMPLEMENT
}
/////////////////////////////////////////////////////////////////////
// Assignment for ASTree
//
ASTree&ASTree::operator=(ASTree rhs){
swap(rhs);
return*this;
}
/////////////////////////////////////////////////////////////////////
// Returns an this->child[i] where (this->child[i]-
>tag == tagName)
//
ASTree*ASTree::getChild(std::string tagName){
std::list<ASTree*>::iterator ptr = child.begin();
while(((*ptr)->tag != tagName)&&(ptr != child.end())){
++ptr;
}
return*ptr;
}
/////////////////////////////////////////////////////////////////////
// Returns the full name of a <name> node.
//
std::string ASTree::getName()const{
std::string result;
if(child.front()->tag !="name"){
result = child.front()->text;//A simple name (e.g., main)
}else{//A complex name (e.g., stack::push).
result = child.front()->child.front()->text;
result +="::";
result += child.back()->child.front()->text;
}
return result;
}
/////////////////////////////////////////////////////////////////////
// Adds in the includes and profile variables in a main file.
//
voidASTree::mainHeader(std::vector<std::string>& profileNam
es){
//NEED TO IMPLEMENT
//Skip down a couple lines.
//For each file profile name, add a new node with a profile
// declaration.
//Also, add in the profile declaration for functions and the
//include for profile.hpp
}
/////////////////////////////////////////////////////////////////////
// Adds in the includes and profile variables for non-main files
//
voidASTree::fileHeader(std::vector<std::string>& profileNames
){
//NEED TO IMPLEMENT
//Skip down a couple lines.
//For each file profile name, add a new node with a profile
// extern declaration.
//Also, add in the extern declaration for functions and the
//include for profile.hpp
}
/////////////////////////////////////////////////////////////////////
// Adds in the report to the main.
// Assumes only one return at end of main body.
//
voidASTree::mainReport(std::vector<std::string>& profileName
s){
//NEED TO IMPLEMENT
//Find the function with name main and then start from the end.
//Find the main - function with name of "main"
//Then start from the end() of this function and iterate
// backwards until you find a return stmt. You'll want
// to insert the report statements before this return.
}
/////////////////////////////////////////////////////////////////////
// Adds in a line to count the number of times each function is e
xecuted.
// Assumes no nested functions.
//
voidASTree::funcCount(){
//NEED TO IMPLEMENT
// Check for function, constructor, destructor.
// Find the function name and insert the count.
}
/////////////////////////////////////////////////////////////////////
// Adds in a line to count the number of times each statement is
executed.
// No breaks, returns, throw etc.
// Assumes all construts (for, while, if) have { }.
//
voidASTree::lineCount(const std::string& profileNames){
//NEED TO IMPLEMENT
// Check for expr_stmt and call
}
/////////////////////////////////////////////////////////////////////
// Read in and construct ASTree
// REQUIRES: '>' was pre temp = readUntil(in, '>');
if(temp[0]=='/'){
closeTag = temp;
break;//Found close tag, stop recursion
}
subtree =newASTree(category, temp);//New subtree
subtree->read(in);//Read it in
in.get(ch);
child.push_back(subtree);//Add it to child
}else{//Found a token
temp = std::string(1, ch)+ readUntil(in,'<');//Read it in.
std::vector<std::string> tokenList = tokeniree);
}
ch ='<';
}
}
return in;
}
/////////////////////////////////////////////////////////////////////
// Print an ASTree
// REQUIRES: indent >= 0
//
std::ostream&ASTree::print(std::ostream& out,int indent)const{
if(TAGS) out << std::setw(indent)<<" ";
if(TAGS) out <<"<"<< tag <<">"<< std::endl;
for(std::list<ASTree*>::const_iterator i = child.begin(); i != chi
ld.end();++i){
switch((*i)->nodeType){
///////////////////
// Utilities
//
bool isStopTag(std::string tag){
if(tag =="decl_stmt")returntrue;
if(tag =="argument_list")returntrue;
if(tag =="init")returntrue;
if(tag =="condition")returntrue;
if(tag =="cpp:include")returntrue;
if(tag =="comment type"block"")returntrue;
if(tag =="comment type"line"")returntrue;
if(tag =="macro")returntrue;
returnfalse;
}
/////////////////////////////////////////////////////////////////////
// Reads until a key is encountered. Does not inclutVal == "<"
//
std::string unEscape(std::string s){
std::size_t pos =0;
while((pos = s.find("&gt;"))!= s.npos){ s.replace(pos,4,">");}
while((pos = s.find("&lt;"))!= s.npos){ s.replace(pos,4,"<");}
while((pos = s.find("&amp;"))!= s.npos){ s.replace(pos,5,"&");}
return s;
}
/////////////////////////////////////////////////////////////////////
// Given: s == " a + c "
// RetVal == {" ", "a", " ", "+", "c", " "}
//
std::vector<std::string> tokenize(const std::string& s){
std::vector<std::string> result;
std::string temp ="";
unsigned i =0;
while(i < s.length()){
while(isspace(s[i])&&(i < s. temp ="";
}
}
return result;
}
ASTree.hpp
/*
* ASTree.hpp
* Abstract Syntax Tree
*
* Created by Jonathan Maletic on 11/8/11.
* Copyright 2013 Kent State University. All rights reserved.
*
* Modified by:
*
*/
#ifndef INCLUDES_ASTree_H_
#define INCLUDES_ASTree_H_
#include <list>
#include <vector>
#include <iostream>
#include <iomanip>
#include <cassert>
#include <algorithm>
#include <string>
class ASTree;
enum nodes {category, token, whitespace};
const bool TAGS = false;
bool isStopTag (std::string);
std::string readUntil (std::istream&, char);
std::string unEscape (std::string);
std::vector<std::string> tokenize (const std::string& s);
////////////////////////////////////////////////////////////////////////
// An ASTree is either a:
// -Syntactic category node
// -Token node
// -Whitespace node
//
// CLASS INV: if (nodeType == category) than (child != 0) &&
(text == "")
// if ((nodeType == token) || (nodeType == whitespace))
then (child == 0) && (text != "")
//
class ASTree {
public:
ASTree () {};
ASTree (nodes t) : nodeType(t) {};
ASTree (nodes t, const std::string&);
~ASTree () {}; //NEED TO IMPLEMENT
ASTree (const ASTree&);
void swap (ASTree&);
ASTree& operator= (ASTree);
ASTree* copyASTree();
ASTree* getChild (std::string);
std::string getName () const;
void mainHeader(std::vector<std::string>&);
void fileHeader(std::vector<std::string>&);
void mainReport(std::vector<std::string>&);
void funcCount ();
void lineCount (const std::string&);
std::ostream& print (std::ostream&, int) const;
std::istream& read (std::istream&);
private:
nodes nodeType; //Category, Token, or
Whitespace
std::string tag, //Category: the tag name and
closeTag; // closing tag.
std::list<ASTree*> child; //Category: A list of subtrees.
std::string text; //Token/Whitespace: the text.
};
////////////////////////////////////////////////////////////////////////
// srcML is an internal data structure for a srcML input file.
// CLASS INV: Assigned(tree)
//
class srcML {
public:
srcML () : tree(0) {};
~srcML () {delete tree;}
srcML (const srcML&);
void swap (srcML&);
srcML& operator= (srcML);
void mainHeader(std::vector<std::string>&);
void fileHeader(std::vector<std::string>&);
void mainReport(std::vector<std::string>&);
void funcCount ();
void lineCount (const std::string&);
friend std::istream& operator>>(std::istream&, srcML&);
friend std::ostream& operator<<(std::ostream&, const
srcML&);
private:
std::string header;
ASTree* tree;
};
#endif
main.cppmain.cpp/*
* main.cpp
* Profiler
*
* Created by Jonathan Maletic on 11/8/11.
* Copyright 2013 Kent State University. All rights reserved.
*
* Requires main.cpp first, followed by other files.
*
* Modified by:
*
*/
#include<iostream>
#include<fstream>
#include<vector>
#include<string>
#include<algorithm>
#include"ASTree.hpp"
#include"profile.hpp"
//
// Reads a srcML file into an internal data structure.
// Then prints out the data structure.
int main(int argc,char*argv[]){
if(argc <2){
std::cerr <<"Error: One or more input files are required."<< s
td::endl;
std::cerr <<" The main must be the first argument follow
ed by any other .cpp files. For example:"<< std::endl;
std::cerr <<"profiler main.cpp.xml file1.cpp.xml file2.cpp.xm
l"<< std::endl << std::endl;
return(1);
}
srcML code;//The source code to be profiled.
std::vector<std::string> files;//The list of file names (without
.xml)
std::vector<std::string> profileNames;//The list of profile nam
es to be used.
for(int i =1; i < argc;++i){
std::string filename = argv[i];
files.push_back(filename);
filename = filename.substr(0, filename.find(".xml"));//Remov
e .xml
std::replace(filename.begin(), filename.end(),'.','_');// Change
. to _
profileNames.push_back(filename);
}
std::ifstream inFile(files[0].c_str());//Read in the main.
inFile >> code;
inFile.close();
code.mainHeader(profileNames);//Add in main header info
code.mainReport(profileNames);//Add in the report
code.funcCount();//Count funciton invocations
code.lineCount(profileNames[0]);//Count line invocations
std::string outFileName ="p-"+ files[0];
outFileName = outFileName.substr(0, outFileName.find(".xml"
));//Remove .xml
std::ofstream outFile(outFileName.c_str());
outFile << code << std::endl;
outFile.close();
for(unsigned i =1; i < files.size();++i){//Read in the rest of the f
iles.
inFile.open(files[i].c_str());
inFile >> code;
inFile.close();
code.fileHeader(profileNames);//Add in file header info
code.funcCount();//Count funciton invocations
code.lineCount(profileNames[i]);//Count line invocations
outFileName ="p-"+ files[i];
outFileName = outFileName.substr(0, outFileName.find(".xm
l"));//Remove .xml
outFile.open(outFileName.c_str());
outFile << code << std::endl;
outFile.close();
}
return0;
}
Makefile
#==============================================
==============================
# Make file for Profiler
#
# CS II Kent State University
#
# J. Maletic 2015
#####################################################
##########
# Variables
CPP = clang++
CPP_OPTS = -g -Wall -W -Wunused -Wuninitialized -Wshadow
-std=c++11
#####################################################
##########
# The first rule is run if only make is typed
msg:
@echo 'Targets are:'
@echo ' profiler:'
@echo ' sort:'
@echo ' p-sort:'
@echo ' clean:'
#####################################################
##########
profiler : main.o ASTree.o
$(CPP) $(CPP_OPTS) -o profiler main.o ASTree.o
main.o : main.cpp ASTree.hpp
$(CPP) $(CPP_OPTS) -c main.cpp
ASTree.o : ASTree.hpp ASTree.cpp
$(CPP) $(CPP_OPTS) -c ASTree.cpp
#==============================================
================
# sort
sort : sort.o sort_lib.o
$(CPP) $(CPP_OPTS) -o sort sort.o sort_lib.o
sort.o: sort_lib.h sort.cpp
$(CPP) $(CPP_OPTS) -c sort.cpp
sort_lib.o: sort_lib.h sort_lib.cpp
$(CPP) $(CPP_OPTS) -c sort_lib.cpp
#==============================================
================
# p-sort
# p-sort.cpp
# p-sort_lib.cpp
p-sort : profile.o p-sort.o p-sort_lib.o
$(CPP) $(CPP_OPTS) -o p-sort profile.o p-sort.o p-
sort_lib.o
p-sort.o: profile.hpp sort_lib.h p-sort.cpp
$(CPP) $(CPP_OPTS) -c p-sort.cpp
p-sort_lib.o: profile.hpp sort_lib.h p-sort_lib.cpp
$(CPP) $(CPP_OPTS) -c p-sort_lib.cpp
profile.o: profile.hpp profile.cpp
$(CPP) $(CPP_OPTS) -c profile.cpp
#####################################################
##########
#This will clean up everything via "make clean"
clean:
rm -f profiler
rm -f sort
rm -f *.o
rm -f p-*
profile.cppprofile.cpp/*
* profile.cpp
*
* Created by Jonathan Maletic on 3/29/2012.
* Copyright 2012 Kent State University. All rights reserved.
*
* Modified by:
*
*/
#include"profile.hpp"
////////////////////////////////////////////////////////////////////////
// Prints out the profile.
//
// TODO: Very simple output, need to make it into columns with
nice headings.
//
std::ostream&operator<<(std::ostream& out,const profile& p){
for(std::map<std::string,int>::const_iterator i = p.item.begin(); i
!= p.item.end();++i){
out << i->first <<" "<< i->second << std::endl;
}
return out;
}
//////////////////////////////////////////////////////////
// PRE: n >= 0
// POST: Returns a text version of a positive integer long
std::string intToString(int n){
assert(n >=0);
std::string result;
if(n ==0)return"0";
while(n >0){
result =char(int('0')+(n %10))+ result;
n = n /10;
}
return result;
}
profile.hpp
/*
* profile.hpp
*
* Created by Jonathan Maletic on 3/29/2012.
* Copyright 2012 Kent State University. All rights reserved.
*
* Modified by:
*
*/
#ifndef INCLUDES_PROFILE_H_
#define INCLUDES_PROFILE_H_
#include <iostream>
#include <cassert>
#include <string>
#include <map>
#include <algorithm>
std::string intToString(int);
////////////////////////////////////////////////////////////////////////
// A map of line numbers or line number function names and
the number
// of times each was called.
//
//
class profile {
public:
profile () {};
void count (const int line, const std::string& fname) {
item[intToString(line) + " " + fname] += 1; }
void count (const int line) {
item[intToString(line)] += 1; }
friend std::ostream& operator<< (std::ostream&, const
profile&);
private:
std::map<std::string, int> item; //Map of items and their
counts
};
#endif
simple.cppsimple.cpp//////////////////////////////////////////////////////////
//////////
// File: simple.cpp
// Creation: 4/2013
// Programmer: Dr. J. Maletic
//
// Description: Simple program for testing profiler
//
//
#include<iostream>
int search(int tbl[],int n,int key){
int result =-1;
for(int i =0; i < n;++i){
if(key == tbl[i]){
result = i;
}
}
return result;
}
int main(){
int lst[5]={2,4,6,8,10};
std::cout << search(lst,5,6);
std::cout << std::endl;
std::cout <<"Done";
std::cout << std::endl;
return0;
}
simple.cpp.xml
////////////////////////////////////////////////////////////////////
// File: simple.cpp
// Creation: 4/2013
// Programmer: Dr. J. Maletic
//
// Description: Simple program for testing profiler
//
//
# include <iostream>
int search ( int tbl [], int n, int key) {
int result = -1;
for ( int i = 0; i < n; ++ i) {
if ( key == tbl [ i]) {
result = i;
}
}
return result;
}
int main () {
int lst [ 5] = { 2, 4, 6, 8, 10};
std:: cout << search ( lst, 5, 6);
std:: cout << std:: endl;
std:: cout << "Done";
std:: cout << std:: endl;
return 0;
}
sort.cppsort.cpp/**
* @brief Application to run sorting algorithms on random int d
ata
*
* @author Dale Haverstock
* @date 2012-04-19
*/
//==============================================
================================
#include"sort_lib.h"
#include<iostream>
#include<iomanip>
#include<vector>
#include<cstdlib>
//==============================================
================================
// Using declarations
using std::string;
using std::vector;
using std::cout;
using std::cerr;
//==============================================
================================
// Function declarations
void process_command_line(Options& opts,int argc,char* argv[
]);
void generate_random_data(vector<int>& data,int size,int seed,i
nt mod);
void output_data(const vector<int>&);
void output_usage_and_exit(const string& cmd);
void output_error_and_exit(const string& msg);
//==============================================
================================
int main(int argc,char* argv[])
{
// Options container
Options opts;
// Get values from the command line, opts may be changed
process_command_line(opts, argc, argv);
// Generate data
vector<int> data;
generate_random_data(data, opts._data_size, opts._seed, opts.
_mod);
// Output data before sorting
if(opts._output_data)
{ cout <<"nData Before: "; output_data(data);}
// Sort, if a sort was specified, there is no default
if(opts._quick_sort){ quick_sort(data);}
if(opts._selection_sort){ selection_sort(data);}
if(opts._bubble_sort){ bubble_sort(data);}
if(!opts._quick_sort &&
!opts._selection_sort &&
!opts._bubble_sort )
{ output_error_and_exit("No sort specified.");}
// Output data after sorting
if(opts._output_sorted_data)
{ cout <<"nData After: "; output_data(data);}
return0;
}
//==============================================
================================
void generate_random_data(vector<int>& vec,int size,int seed,i
nt mod)
{
// Resize vector
vec.resize(size);
// Set random number generator seed
srandom(static_cast<unsignedint>(seed));
// Put random values in vector
for(vector<int>::size_type idx =0; idx < vec.size();++idx)
{
if(mod){ vec[idx]= random()% mod;}
else{ vec[idx]= random();}
}
}
//==============================================
================================
void output_data(const vector<int>& vec)
{
// Number of columns, column width
constint cols =7;
constint width =10;
// Output vector elements
for(vector<int>::size_type idx =0; idx < vec.size();++idx)
{
// Output newline to end row
if(!(idx % cols))
{ cout <<"n";}
cout << std::setw(width)<< vec[idx]<<" ";
}
cout <<'n';
}
//==============================================
================================
// Note:
// * No check for C-string to int conversion success
//
void process_command_line(Options& opts,int argc,char* argv[
])
{
// Useage message if no command line args
if(argc ==1)
{ output_usage_and_exit(argv[0]);}
// Go through the argumets
for(int idx =1; idx < argc;++idx)
{
// Standard library string from C-string
string opt(argv[idx]);
// Process the option
if(opt =="-h"){ output_usage_and_exit(argv[0]);}
if(opt =="-qs"){ opts._quick_sort =true;}
if(opt =="-ss"){ opts._selection_sort =true;}
if(opt =="-bs"){ opts._bubble_sort =true;}
if(opt =="-od"){ opts._output_data =true;}
if(opt =="-osd"){ opts._output_sorted_data =true;}
if(opt =="-sz")
{
if(idx +1< argc){++idx; opts._data_size = atoi(argv[idx]);}
else{ output_error_and_exit("Value for -
sz option is missing.");}
}
if(opt =="-rs")
{
if(idx +1< argc){++idx; opts._seed = atoi(argv[idx]);}
else{ output_error_and_exit("Value for -
rs option is missing.");}
}
if(opt =="-mod")
{
if(idx +1< argc){++idx; opts._mod = atoi(argv[idx]);}
else{ output_error_and_exit("Value for -
mod option is missing.");}
}
if((opt !="-h")&&
(opt !="-qs")&&
(opt !="-ss")&&
(opt !="-bs")&&
(opt !="-od")&&
(opt !="-osd")&&
(opt !="-sz")&&
(opt !="-rs")&&
(opt !="-mod"))
{
output_error_and_exit(string("Error: Bad option: ")+ opt);
}
}
}
//==============================================
================================
void output_usage_and_exit(const string& cmd)
{
cout <<
"Usage: "<< cmd <<" [options]n"
" Options:n"
" -sz int The number of data itemsn"
" -rs int The random number generator seedn"
" -mod int The mod value for random numbersn"
" -od Output data to be sortedn"
" -osd Output sorted datan"
" -qs Use quick sortn"
" -ss Use selection sortn"
" -bs Use bubble sortn"
" -h This messagen"
"n"
" A sort must be specified, there is no default sort.n"
" If more than 1 sort is specified then the first sortn"
" specified from the following order will be done.n"
" 1. quickn"
" 2. selectionn"
" 3. bubblen";
exit(0);
}
//==============================================
================================
void output_error_and_exit(const string& msg)
{
cerr <<"Error: "<< msg <<"n";
exit(1);
}
sort.cpp.xml
/**
* @brief Application to run sorting algorithms on random int
data
*
* @author Dale Haverstock
* @date 2012-04-19
*/
//==============================================
================================
# include "sort_lib.h"
# include <iostream>
# include <iomanip>
# include <vector>
# include <cstdlib>
//==============================================
================================
// Using declarations
using std:: string;
using std:: vector;
using std:: cout;
using std:: cerr;
//==============================================
================================
// Function declarations
void process_command_line ( Options& opts, int argc,
char* argv []);
void generate_random_data ( vector < int>& data, int
size, int seed, int mod);
void output_data ( const vector < int>&);
void output_usage_and_exit ( const string& cmd);
void output_error_and_exit ( const string& msg);
//==============================================
================================
int main ( int argc, char* argv [])
{
// Options container
Options opts;
// Get values from the command line, opts may be changed
process_command_line ( opts, argc, argv);
// Generate data
vector < int> data;
generate_random_data ( data, opts. _data_size, opts.
_seed, opts. _mod);
// Output data before sorting
if ( opts. _output_data)
{ cout << "nData Before: "; output_data ( data); }
// Sort, if a sort was specified, there is no default
if ( opts. _quick_sort) { quick_sort ( data); }
if ( opts. _selection_sort) { selection_sort ( data); }
if ( opts. _bubble_sort) { bubble_sort ( data); }
if ( ! opts. _quick_sort &&
! opts. _selection_sort &&
! opts. _bubble_sort )
{ output_error_and_exit ( "No sort specified."); }
// Output data after sorting
if ( opts. _output_sorted_data)
{ cout << "nData After: "; output_data ( data); }
return 0;
}
//==============================================
================================
void generate_random_data ( vector < int>& vec, int
size, int seed, int mod)
{
// Resize vector
vec. resize ( size);
// Set random number generator seed
srandom ( static_cast<unsigned int>(seed)) ;
// Put random values in vector
for ( vector < int>:: size_type idx = 0; idx < vec.
size (); ++ idx)
{
if ( mod) { vec [ idx] = random () % mod; }
else { vec [ idx] = random (); }
}
}
//==============================================
================================
void output_data ( const vector < int>& vec)
{
// Number of columns, column width
const int cols = 7;
const int width = 10;
// Output vector elements
for ( vector < int>:: size_type idx = 0; idx < vec.
size (); ++ idx)
{
// Output newline to end row
if ( ! ( idx % cols) )
{ cout << "n"; }
cout << std:: setw ( width) << vec [ idx] << " ";
}
cout << 'n';
}
//==============================================
================================
// Note:
// * No check for C-string to int conversion success
//
void process_command_line ( Options& opts, int argc
sort_lib.cppsort_lib.cpp/**
* @brief Application to run sorting algorithms on random int d
ata
*
* @author Dale Haverstock
* @date 2012-04-19
*/
// sort library
//
//==============================================
================================
#include"sort_lib.h"
#include<vector>
//==============================================
================================
// Make shorter type names
typedef std::vector<int>::size_type Vec_Idx;
//==============================================
================================
// Function declarations, uppercase so those stand out
void quick_sort(std::vector<int>& data,int left,int right);
void SWAP(int& n1,int& n2);
bool LESS_THAN(int n1,int n2);
bool GREATER_THAN(int n1,int n2);
//==============================================
================================
void quick_sort(std::vector<int>& data)
{
// Do nothing if empty vector
if(data.size()==0)
{return;}
// Do the sort
quick_sort(data,0, data.size()-1);
}
//==============================================
================================
// The unsigned ints cause problems here, jdx may go to -1.
// Subscripts are cast so there are no warnings.
void quick_sort(std::vector<int>& data,int left,int right)
{
// Calculate the pivot
int pivot = data[Vec_Idx((left + right)/2)];
// Partition
int idx = left, jdx = right;
while(idx <= jdx){
while(LESS_THAN(data[Vec_Idx(idx)], pivot))
idx++;
while(GREATER_THAN(data[Vec_Idx(jdx)], pivot))
jdx--;
if(idx <= jdx)
{
SWAP(data[Vec_Idx(idx)], data[Vec_Idx(jdx)]);
idx++;
jdx--;
}
}
// Recurse
if(left < jdx)
{ quick_sort(data, left, jdx);}
if(idx < right)
{ quick_sort(data, idx, right);}
}
//==============================================
================================
void selection_sort(std::vector<int>& data)
{
// Do nothing if empty vector (note unsigned 0 -
1 is a big number)
if(data.size()==0)
{return;}
// Index of last element in vector, also last in unsorted part
Vec_Idx last = data.size()-1;
// Do the sort
while(last >0)
{
// Find greatest in unsorted part
Vec_Idx idx_of_greatest =0;
for(Vec_Idx idx =0; idx <= last;++idx)
{
if( LESS_THAN(data[idx_of_greatest], data[idx]))
{
// Remember as new greatest so far
idx_of_greatest = idx;
}
}
// Swap last in unsorted with greatest in unsorted part
SWAP(data[last], data[idx_of_greatest]);
// Increase sorted part
--last;
}
}
//==============================================
================================
void bubble_sort(std::vector<int>& data)
{
// Go through vector repeatedly
for(Vec_Idx limit = data.size(); limit >0; limit--)
{
// Go through vector once, swap element and next element if out
of order
for(Vec_Idx idx =0; idx < limit -1; idx++)
{
if( LESS_THAN(data[idx +1], data[idx]))
{
SWAP(data[idx],data[idx +1]);
}
}
}
}
//==============================================
================================
// This is here so the number of calls can be counted.
void SWAP(int& n1,int& n2)
{
std::swap(n1, n2);
}
//==============================================
================================
// This is here so the number of calls can be counted.
bool LESS_THAN(int n1,int n2)
{
return n1 < n2;
}
//==============================================
================================
// This is here so the number of calls can be counted.
bool GREATER_THAN(int n1,int n2)
{
return n1 > n2;
}
sort_lib.cpp.xml
/**
* @brief Application to run sorting algorithms on random int
data
*
* @author Dale Haverstock
* @date 2012-04-19
*/
// sort library
//
//==============================================
================================
# include "sort_lib.h"
# include <vector>
//==============================================
================================
// Make shorter type names
typedef std:: vector < int>:: size_type Vec_Idx;
//==============================================
================================
// Function declarations, uppercase so those stand out
void quick_sort ( std:: vector < int>& data, int left,
int right);
void SWAP ( int& n1, int& n2);
bool LESS_THAN ( int n1, int n2);
bool GREATER_THAN ( int n1, int n2);
//==============================================
================================
void quick_sort ( std:: vector < int>& data)
{
// Do nothing if empty vector
if ( data. size () == 0)
{ return; }
// Do the sort
quick_sort ( data, 0, data. size () - 1);
}
//==============================================
================================
// The unsigned ints cause problems here, jdx may go to -1.
// Subscripts are cast so there are no warnings.
void quick_sort ( std:: vector < int>& data, int left,
int right)
{
// Calculate the pivot
int pivot = data [ Vec_Idx ( ( left + right) / 2)];
// Partition
int idx = left, jdx = right;
while ( idx <= jdx) {
while ( LESS_THAN ( data [ Vec_Idx ( idx)],
pivot))
idx++;
while ( GREATER_THAN ( data [ Vec_Idx (
jdx)], pivot))
jdx--;
if ( idx <= jdx)
{
SWAP ( data [ Vec_Idx ( idx)], data [
Vec_Idx ( jdx)]);
idx++;
jdx--;
}
}
// Recurse
if ( left < jdx)
{ quick_sort ( data, left, jdx); }
if ( idx < right)
{ quick_sort ( data, idx, right); }
}
//==============================================
================================
void selection_sort ( std:: vector < int>& data)
{
// Do nothing if empty vector (note unsigned 0 - 1 is a big
number)
if ( data. size () == 0)
{ return; }
// Index of last element in vector, also last in unsorted part
Vec_Idx last = data. size () - 1;
// Do the sort
while ( last > 0)
{
// Find greatest in unsorted part
Vec_Idx idx_of_greatest = 0;
for ( Vec_Idx idx = 0; idx <= last; ++ idx)
{
if ( LESS_THAN ( data [ idx_of_greatest],
data [ idx]) )
{
// Remember as new greatest so far
idx_of_greatest = idx;
}
}
// Swap last in unsorted with greatest in unsorted part
SWAP ( data [ last], data [ idx_of_greatest]);
// Increase sorted part
-- last;
}
}
//==============================================
================================
void bubble_sort ( std:: vector < int>& data)
{
// Go through vector repeatedly
for( Vec_Idx limit = data. size (); limit > 0; limit--
)
data [ idx + 1]
sort_lib.h
/**
* @brief Application to run sorting algorithms on random int
data
*
* @author Dale Haverstock
* @date 2012-04-19
*/
#ifndef SORT_LIB_H
#define SORT_LIB_H
//==============================================
================================
#include <vector>
//==============================================
================================
struct Options
{
// Option values
int _seed;
int _data_size;
int _mod;
bool _output_data;
bool _output_sorted_data;
bool _bubble_sort;
bool _selection_sort;
bool _quick_sort;
// Defaults
Options()
: _seed(0),
_data_size(0),
_mod(0),
_output_data(false),
_output_sorted_data(false),
_bubble_sort(false),
_selection_sort(false),
_quick_sort(false)
{ }
};
//==============================================
================================
void selection_sort(std::vector<int>&);
void quick_sort(std::vector<int>&);
void bubble_sort(std::vector<int>&);
#endif

More Related Content

PDF
Building source code level profiler for C++.pdf
PDF
Industry - Program analysis and verification - Type-preserving Heap Profiler ...
PDF
HPC Application Profiling and Analysis
PDF
Analyzing ECP Proxy Apps with the Profiling Tool Score-P
PPTX
HPC Application Profiling & Analysis
ODT
(3) cpp abstractions more_on_user_defined_types_exercises
PDF
How to make a large C++-code base manageable
PDF
TIP1 - Overview of C/C++ Debugging/Tracing/Profiling Tools
Building source code level profiler for C++.pdf
Industry - Program analysis and verification - Type-preserving Heap Profiler ...
HPC Application Profiling and Analysis
Analyzing ECP Proxy Apps with the Profiling Tool Score-P
HPC Application Profiling & Analysis
(3) cpp abstractions more_on_user_defined_types_exercises
How to make a large C++-code base manageable
TIP1 - Overview of C/C++ Debugging/Tracing/Profiling Tools

Similar to CS 23001 Computer Science II Data Structures & AbstractionPro.docx (20)

PPTX
Basic C++ 11/14 for Python Programmers
PDF
To write a program that implements the following C++ concepts 1. Dat.pdf
PPTX
Effective C++
PDF
Gsp 125 final exam guide
DOC
GSP 125 Doing by learn/newtonhelp.com
DOC
GSP 125 Perfect Education/newtonhelp.com
DOC
Gsp 125 Future Our Mission/newtonhelp.com
DOC
GSP 125 Become Exceptional/newtonhelp.com
DOC
Gsp 125 Massive Success / snaptutorial.com
DOC
GSP 125 Technology levels--snaptutorial.com
DOC
Gsp 125 Enthusiastic Study / snaptutorial.com
DOCX
Gsp 125 Education Organization -- snaptutorial.com
DOCX
GSP 125 Exceptional Education - snaptutorial.com
DOC
GSP 125 Education Specialist / snaptutorial.com
PDF
Beyond Breakpoints: A Tour of Dynamic Analysis
DOCX
GSP 125 RANK Education for Service--gsp125rank.com
PDF
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
DOCX
GSP 125 Enhance teaching - snaptutorial.com
DOCX
GSP 125 Effective Communication/tutorialrank.com
DOCX
GSP 125 Enhance teaching/tutorialrank.com
Basic C++ 11/14 for Python Programmers
To write a program that implements the following C++ concepts 1. Dat.pdf
Effective C++
Gsp 125 final exam guide
GSP 125 Doing by learn/newtonhelp.com
GSP 125 Perfect Education/newtonhelp.com
Gsp 125 Future Our Mission/newtonhelp.com
GSP 125 Become Exceptional/newtonhelp.com
Gsp 125 Massive Success / snaptutorial.com
GSP 125 Technology levels--snaptutorial.com
Gsp 125 Enthusiastic Study / snaptutorial.com
Gsp 125 Education Organization -- snaptutorial.com
GSP 125 Exceptional Education - snaptutorial.com
GSP 125 Education Specialist / snaptutorial.com
Beyond Breakpoints: A Tour of Dynamic Analysis
GSP 125 RANK Education for Service--gsp125rank.com
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
GSP 125 Enhance teaching - snaptutorial.com
GSP 125 Effective Communication/tutorialrank.com
GSP 125 Enhance teaching/tutorialrank.com
Ad

More from faithxdunce63732 (20)

DOCX
Assignment DetailsScenario You are member of a prisoner revie.docx
DOCX
Assignment DetailsScenario You are an investigator for Child .docx
DOCX
Assignment DetailsScenario You are a new patrol officer in a .docx
DOCX
Assignment DetailsScenario Generally, we have considered sexual.docx
DOCX
Assignment DetailsPower’s on, Power’s Off!How convenient is.docx
DOCX
Assignment DetailsIn 1908, playwright Israel Zangwill referred to .docx
DOCX
Assignment DetailsPart IRespond to the following.docx
DOCX
Assignment DetailsPlease discuss the following in your main post.docx
DOCX
Assignment DetailsPennsylvania was the leader in sentencing and .docx
DOCX
Assignment DetailsPart IRespond to the followingReview .docx
DOCX
Assignment DetailsPart IRespond to the following questio.docx
DOCX
Assignment DetailsPart IRespond to the following questions.docx
DOCX
Assignment DetailsOne thing that unites all humans—despite cultu.docx
DOCX
Assignment DetailsMN551Develop cooperative relationships with.docx
DOCX
Assignment DetailsInfluence ProcessesYou have been encourag.docx
DOCX
Assignment DetailsIn this assignment, you will identify and .docx
DOCX
Assignment DetailsFinancial statements are the primary means of .docx
DOCX
Assignment DetailsIn this assignment, you will identify a pr.docx
DOCX
Assignment DetailsHealth information technology (health IT) .docx
DOCX
Assignment DetailsDiscuss the followingWhat were some of .docx
Assignment DetailsScenario You are member of a prisoner revie.docx
Assignment DetailsScenario You are an investigator for Child .docx
Assignment DetailsScenario You are a new patrol officer in a .docx
Assignment DetailsScenario Generally, we have considered sexual.docx
Assignment DetailsPower’s on, Power’s Off!How convenient is.docx
Assignment DetailsIn 1908, playwright Israel Zangwill referred to .docx
Assignment DetailsPart IRespond to the following.docx
Assignment DetailsPlease discuss the following in your main post.docx
Assignment DetailsPennsylvania was the leader in sentencing and .docx
Assignment DetailsPart IRespond to the followingReview .docx
Assignment DetailsPart IRespond to the following questio.docx
Assignment DetailsPart IRespond to the following questions.docx
Assignment DetailsOne thing that unites all humans—despite cultu.docx
Assignment DetailsMN551Develop cooperative relationships with.docx
Assignment DetailsInfluence ProcessesYou have been encourag.docx
Assignment DetailsIn this assignment, you will identify and .docx
Assignment DetailsFinancial statements are the primary means of .docx
Assignment DetailsIn this assignment, you will identify a pr.docx
Assignment DetailsHealth information technology (health IT) .docx
Assignment DetailsDiscuss the followingWhat were some of .docx
Ad

Recently uploaded (20)

PDF
3rd Neelam Sanjeevareddy Memorial Lecture.pdf
PDF
O7-L3 Supply Chain Operations - ICLT Program
PPTX
master seminar digital applications in india
PPTX
PPH.pptx obstetrics and gynecology in nursing
PPTX
Microbial diseases, their pathogenesis and prophylaxis
PDF
Anesthesia in Laparoscopic Surgery in India
PPTX
Cell Types and Its function , kingdom of life
PDF
Mark Klimek Lecture Notes_240423 revision books _173037.pdf
PDF
VCE English Exam - Section C Student Revision Booklet
PPTX
The Healthy Child – Unit II | Child Health Nursing I | B.Sc Nursing 5th Semester
PPTX
Pharma ospi slides which help in ospi learning
PPTX
IMMUNITY IMMUNITY refers to protection against infection, and the immune syst...
PDF
ANTIBIOTICS.pptx.pdf………………… xxxxxxxxxxxxx
PDF
102 student loan defaulters named and shamed – Is someone you know on the list?
PDF
Pre independence Education in Inndia.pdf
PDF
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
PDF
01-Introduction-to-Information-Management.pdf
PPTX
Pharmacology of Heart Failure /Pharmacotherapy of CHF
PDF
STATICS OF THE RIGID BODIES Hibbelers.pdf
PDF
Module 4: Burden of Disease Tutorial Slides S2 2025
3rd Neelam Sanjeevareddy Memorial Lecture.pdf
O7-L3 Supply Chain Operations - ICLT Program
master seminar digital applications in india
PPH.pptx obstetrics and gynecology in nursing
Microbial diseases, their pathogenesis and prophylaxis
Anesthesia in Laparoscopic Surgery in India
Cell Types and Its function , kingdom of life
Mark Klimek Lecture Notes_240423 revision books _173037.pdf
VCE English Exam - Section C Student Revision Booklet
The Healthy Child – Unit II | Child Health Nursing I | B.Sc Nursing 5th Semester
Pharma ospi slides which help in ospi learning
IMMUNITY IMMUNITY refers to protection against infection, and the immune syst...
ANTIBIOTICS.pptx.pdf………………… xxxxxxxxxxxxx
102 student loan defaulters named and shamed – Is someone you know on the list?
Pre independence Education in Inndia.pdf
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
01-Introduction-to-Information-Management.pdf
Pharmacology of Heart Failure /Pharmacotherapy of CHF
STATICS OF THE RIGID BODIES Hibbelers.pdf
Module 4: Burden of Disease Tutorial Slides S2 2025

CS 23001 Computer Science II Data Structures & AbstractionPro.docx

  • 1. CS 23001 Computer Science II: Data Structures & Abstraction Project #4 Spring 2015 Objectives: · Develop and use a Tree ADT (n-ary) · Apply and use tree traversal algorithms · Manipulate trees by inserting and deleting nodes · Apply and use STL Problem: Build a program profiler. Construct a program to instrument C++ source code to support program profiling. It is often important to determine how many times a function or statement is executed. This is useful not only for debugging but for determining what parts of a program may need to be optimized. This process is called profiling. That is, a execution profile presents how many times each part of a program is executed using a given set of input data (or for some run time scenario). To compute a profile, statements need to be added to the code that keep track of how many times a function or statement is executed. The process of adding these statements is called instrumenting the code. To implement a profiler one must first parse the source code and generate an Abstract Syntax Tree (AST) of the code. Each node of the AST describes the syntactic category of the code stored within it (function, statement, while-statement, etc.). So at the top level is a syntactic category corresponding to a program, class, or function (such as in the case of a main). Under that are sub-trees that further detail the syntactic categories of each part of the code. Such things as declarations,
  • 2. parameter lists, while-statement, and expression statements will describe the various parts of the program. After the AST is generated it can then be traversed and the appropriate syntactic structures can be found that need to be instrumented. Once a construct is found, say a function, new code can be inserted that keeps track of how many times that function is executed. The most difficult part of constructing a profiler is correctly parsing the source code. Unfortunately, C++ is notoriously difficult to parse. So here we will use a parsing tool called src2srcml. This tool reads in C++ code and marks up the code with XML tags (e.g., block, if, while, condition, name, etc). That is, the output is an AST in XML. The XML representation is called srcML (source code markup language). A number of srcML data files are provided for the project. However, you can use your own program as input. To run srcML on wasp or hornet you will first need to set a PATH variable so the command can be found. You need to execute the command: export PATH=/local/opt/srcml/bin:$PATH It is best if you insert this line into your .bash_profile file in your home directory on wasp/hornet. Then to generate the srcML file for your own code use the following: src2srcml main.cpp -o main.cpp.xml Use the following for a list of all options: src2srcml --help More information about srcML can be found at www.srcML.org including a list of all the tag names (see Getting Started). You can also download srcML if you want it on your own machine.
  • 3. Your program will read in srcML files (in XML) and build an internal representation of the AST as a tree data structure. When using XML this internal representation is typically called a Document Object Model (DOM). A set of classes defining the data structure (DOM) is in shared (ASTree.hpp and ASTree.cpp). This part of the project is partially implemented (i.e., the read and write work). The given code compiles and runs. The program currently is able to read in a srcML file and construct the internal tree representation. It can also write the code (without XML) back out from the internal tree representation. Your job will be to complete the implementation and build the insturmenter for the profiler. The specification for the profiler is as follows: · The program will take as input a list of files that are to be profiled. The first file in the list will be the main body. · The program will instrument all the files to keep track of each function and statement executed in the program. · The program will also instrument the main body with two additional parts. The first is a set of global profiling variables. Second, at the end of the main body the results of the profiling data will be printed to an output file (or the screen if none is supplied). · Profile how many times each function or method in the supplied files is executed. Keep track of this by the filename, line number, and function name. · Profile how many times each statement is executed. Keep track of this by filename and line number. Include all statements ending with a semicolon (e.g., assignments, function calls) and all statements within loops, if/else, and case statement. · Do not count break, return, goto, or throw statements. · Do not count declaration statements. · Do not count statement in for-loop specifications. For example, don't count the i=0, i==n, or ++i in for (i=0; i==n; ++i).
  • 4. · Do not count conditions (but see challenge). That is, only count statements in the bodies of if-stmts or loop-stmts and not how many times the condition is executed. · You do not need to worry about following any formating style (indentation, etc.) for the inserted code. · Output: For each file print out, ordered by line number, the counts for each line and function. In short, your profiler program will read in source code and write out source code that has been insturmented. Then you will compile and run the insturmented version of the code to get the profile information. Requirements: · Part 1 - 30 pts · Implementation: · Read the code given in ASTree.hpp/cpp, profile.hpp/cpp, and main.cpp under shared. You will be required to add code and comments to these files. You are free to modify them as you see fit. · The provided code works (compiles and runs) and the read and write are implemented. · Implement the necessary 1) destructor, 2) copy constructor, 3) swap, and 4) assignment operator for the ASTree class. There are comments pointing out which methods still need to be implemented. · The code uses STL and you may use STL in your solution, including std::string. · Testing: · Test all the methods you implement by providing code that calls all the methods. · Use the provided makefile: make profiler · Part 2 - 30 pts · Implementation: · Use the provided profile ADT (profile.hpp/cpp). This is a simple ADT that uses the STL map data type. It is a map of (string X int). With the string being the function name and line
  • 5. number and the integer being the count of times that line/function was executed. · To profile the program you will need to create a profile object for each file (as given on the command line) to keep track of statements and functions. These will be inserted as code into the main as global variable declarations. The main is the first file given in the input. · All profile objects need to be declared in the main and for each additional file you will need to include profile.hpp and declare the file's profile object as external, for example extern foo_cpp; · Your profiler only needs to work on cpp files. You do not need to insturment header files (.h, .hpp). · For debugging there is a flag called TAGS in ASTree.hpp. If you set this to true the tags of the abstract syntax tree will be printed. This gives a view of the data structure. · Implement the functionality to insert profile declarations into the main file. You will need this for part 3. For example given the following main: · · //File main1.cpp · #include <iostream> · · int main() { · int i = 0; · while (i < 10) { · ++i; · std::cout << i; · } · return 0; } · The profiler will need to insert something like the following lines of code, minus comments (in red): · · //File main1.cpp · #include <iostream>
  • 6. · · #include "profile.hpp" //include your profile ADT · profile main1_cpp("main1.cpp"); //Profile object for counting lines in main1.cpp · · int main() { · int i = 0; · while (i < 10) { · ++i; · std::cout << i; · } · return 0; } · Testing: · Test the profile ADT. · Test the insertion of code into the main. · Part 3 - 40 pts · Implementation: · For every function, insert a line of code to update the corresponding file profile object given the function name and line number. The line number is used to provide a unquie map index for overloaded functions. This will add one to the corresponding map element. Insert this code as the first line in the function, right after the { is fine. You may assume there are no nested functions. · For every line of code (as defined above) add a line of code after it that updates the correct file profile object given the line number. Use the __LINE__ macro for this. This macro returns an integer and you will need to convert this value to a string for use in your profile ADT. · You may ASSUME all loops and conditionals have a block. That is, no single line bodies. For example, there will always be a block after a loop as in for (i=0; i==n; ++i) { x=x+1; } versus no block as in for (i=0; i==n; ++i) x=x+1;. · Lastly, you will need to add statements to the end of the main
  • 7. to print out the profile data. This should go just before the return. You may assume there is only one return in the main. This report should print each item in the map (function or line number) followed by the counts. · Your profiler only needs to work on cpp files. You do not need to insturment header files (.h, .hpp). · You should send the profiler output for each input file to a new file. Prefix a "p-" to the begining of the orginal file name. For example: p-main.cpp or p-ASTree.cpp · Given profiler main1.cpp foo.cpp the final code will look something like the following for file p-main1.cpp: · · //File: main1.cpp · #include <iostream> · · #include "profile.hpp" · profile foo_cpp("foo.cpp"); · profile main1_cpp("main1.cpp"); · · int main() { main1_cpp.count(__LINE__, "main"); · int i; · i = 0; main1_cpp.count(__LINE__); · while (i < 10) { · ++i; main1_cpp.count(__LINE__); · std::cout << i; main1_cpp.count(__LINE__); · } · std::cout << foo_cpp << std::endl; · std::cout << main1_cpp << std::endl; · return 0; } · And p-foo.cpp · · //File foo.cpp · · #include "profile.hpp" · extern profile foo_cpp;
  • 8. · · int foo() { foo_cpp.count(__LINE__, "foo"); · int i; · i = 0; foo_cpp.count(__LINE__); · return i; } · Testing: · Your profiler application must be able to work with the provided source code, a sorting application. · Run the application for all three algorithm and compare the profiles. · ./sorting -bs -sz 100 -od -osd · The makefile can build the profiler, sort, and profiled sort (p- sort). · Challenge - 5 pts extra credit · Profile all conditionals. · Count the number of times the conditional in a while, if, for, repeat, or switch is executed. · For example, given the following code: · · i = 0; //Line 1 · while (i < 10) { //Line 2 · ++i; //Line 3 } · If this code is run only one time, it will have Line 1 executing 1 time, Line 2 (the conditional) executing 11 times, and Line 3 executing 10 times. · These should be stored by file and line number but in a separate profile object (conditionals) for each file. · Hint: use operator&& or operator, · Other Requirements: · You must have a separate specification file (.hpp), implementation file (.cpp), and main file. · Your program will be graded on programming and commenting style as well as the implementation of your ADT.
  • 9. · Include all source code files in svn. · See the grading policy for other requirements. ASTree.cppASTree.cpp/* * ASTree.cpp * Abstract Syntax Tree * * Created by Jonathan Maletic on 11/8/11. * Copyright 2013 Kent State University. All rights reserved. * * Modified by: * */ #include"ASTree.hpp" ///////////////////////////////////////////////////////////////////// // Copy constructor for srcML // srcML::srcML(const srcML& actual){ tree =newASTree(*(actual.tree)); } ///////////////////////////////////////////////////////////////////// // Constant time swap for srcML // void srcML::swap(srcML& b){ std::string t_header = header; header = b.header; b.header = t_header; ASTree*temp = tree; tree = b.tree;
  • 10. b.tree = temp; } ///////////////////////////////////////////////////////////////////// // Assignment for srcML // srcML& srcML::operator=(srcML rhs){ swap(rhs); return*this; } ///////////////////////////////////////////////////////////////////// // Reads in and constructs a srcML object. // std::istream&operator>>(std::istream& in, srcML& src){ char ch; if(!in.eof()) in >> ch; src.header = readUntil(in,'>'); if(!in.eof()) in >> ch; if(src.tree)delete src.tree; src.tree =newASTree(category, readUntil(in,'>')); src.tree->read(in); return in; } ///////////////////////////////////////////////////////////////////// // Prints out a srcML object // std::ostream&operator<<(std::ostream& out,const srcML& src){ if(TAGS) out <<"<"<< src.header <<">"<< std::endl; src.tree->print(out,0); return out; }
  • 11. ///////////////////////////////////////////////////////////////////// // Adds in the includes and profile variables // void srcML::mainHeader(std::vector<std::string>& profileName s){ tree->mainHeader(profileNames); } ///////////////////////////////////////////////////////////////////// // Adds in the includes and profile variables // void srcML::fileHeader(std::vector<std::string>& profileNames ){ tree->fileHeader(profileNames); } ///////////////////////////////////////////////////////////////////// // Adds in the report to the main. // void srcML::mainReport(std::vector<std::string>& profileName s){ tree->mainReport(profileNames); } ///////////////////////////////////////////////////////////////////// // Inserts a function.count() into each function body. // void srcML::funcCount(){ tree->funcCount(); } ///////////////////////////////////////////////////////////////////// // Inserts a filename.count() for each statement.
  • 12. // void srcML::lineCount(const std::string& profilename){ tree->lineCount(profilename); } ///////////////////////////////////////////////////////////////////// // Constructs a category, token, or whitespace node for the tree. // ASTree::ASTree(nodes t,const std::string& s){ nodeType = t; switch(nodeType){ case category: tag = s; break; case token: text = unEscape(s); break; case whitespace: text = s; break; } } /// /// NOTE: Can implement destructor implemented in .h file or h ere. ///
  • 13. ///////////////////////////////////////////////////////////////////// // Copy Constructor for ASTree // ASTree::ASTree(constASTree& actual){ //NEED TO IMPLEMENT } ///////////////////////////////////////////////////////////////////// // Constant time swap for ASTree // voidASTree::swap(ASTree& b){ //NEED TO IMPLEMENT } ///////////////////////////////////////////////////////////////////// // Assignment for ASTree // ASTree&ASTree::operator=(ASTree rhs){ swap(rhs); return*this; } ///////////////////////////////////////////////////////////////////// // Returns an this->child[i] where (this->child[i]- >tag == tagName) // ASTree*ASTree::getChild(std::string tagName){ std::list<ASTree*>::iterator ptr = child.begin(); while(((*ptr)->tag != tagName)&&(ptr != child.end())){ ++ptr; } return*ptr;
  • 14. } ///////////////////////////////////////////////////////////////////// // Returns the full name of a <name> node. // std::string ASTree::getName()const{ std::string result; if(child.front()->tag !="name"){ result = child.front()->text;//A simple name (e.g., main) }else{//A complex name (e.g., stack::push). result = child.front()->child.front()->text; result +="::"; result += child.back()->child.front()->text; } return result; } ///////////////////////////////////////////////////////////////////// // Adds in the includes and profile variables in a main file. // voidASTree::mainHeader(std::vector<std::string>& profileNam es){ //NEED TO IMPLEMENT //Skip down a couple lines. //For each file profile name, add a new node with a profile // declaration. //Also, add in the profile declaration for functions and the //include for profile.hpp }
  • 15. ///////////////////////////////////////////////////////////////////// // Adds in the includes and profile variables for non-main files // voidASTree::fileHeader(std::vector<std::string>& profileNames ){ //NEED TO IMPLEMENT //Skip down a couple lines. //For each file profile name, add a new node with a profile // extern declaration. //Also, add in the extern declaration for functions and the //include for profile.hpp } ///////////////////////////////////////////////////////////////////// // Adds in the report to the main. // Assumes only one return at end of main body. // voidASTree::mainReport(std::vector<std::string>& profileName s){ //NEED TO IMPLEMENT //Find the function with name main and then start from the end. //Find the main - function with name of "main" //Then start from the end() of this function and iterate // backwards until you find a return stmt. You'll want // to insert the report statements before this return. }
  • 16. ///////////////////////////////////////////////////////////////////// // Adds in a line to count the number of times each function is e xecuted. // Assumes no nested functions. // voidASTree::funcCount(){ //NEED TO IMPLEMENT // Check for function, constructor, destructor. // Find the function name and insert the count. } ///////////////////////////////////////////////////////////////////// // Adds in a line to count the number of times each statement is executed. // No breaks, returns, throw etc. // Assumes all construts (for, while, if) have { }. // voidASTree::lineCount(const std::string& profileNames){ //NEED TO IMPLEMENT // Check for expr_stmt and call } ///////////////////////////////////////////////////////////////////// // Read in and construct ASTree // REQUIRES: '>' was pre temp = readUntil(in, '>'); if(temp[0]=='/'){ closeTag = temp;
  • 17. break;//Found close tag, stop recursion } subtree =newASTree(category, temp);//New subtree subtree->read(in);//Read it in in.get(ch); child.push_back(subtree);//Add it to child }else{//Found a token temp = std::string(1, ch)+ readUntil(in,'<');//Read it in. std::vector<std::string> tokenList = tokeniree); } ch ='<'; } } return in; } ///////////////////////////////////////////////////////////////////// // Print an ASTree // REQUIRES: indent >= 0 // std::ostream&ASTree::print(std::ostream& out,int indent)const{ if(TAGS) out << std::setw(indent)<<" "; if(TAGS) out <<"<"<< tag <<">"<< std::endl; for(std::list<ASTree*>::const_iterator i = child.begin(); i != chi ld.end();++i){ switch((*i)->nodeType){ /////////////////// // Utilities // bool isStopTag(std::string tag){ if(tag =="decl_stmt")returntrue; if(tag =="argument_list")returntrue; if(tag =="init")returntrue; if(tag =="condition")returntrue;
  • 18. if(tag =="cpp:include")returntrue; if(tag =="comment type"block"")returntrue; if(tag =="comment type"line"")returntrue; if(tag =="macro")returntrue; returnfalse; } ///////////////////////////////////////////////////////////////////// // Reads until a key is encountered. Does not inclutVal == "<" // std::string unEscape(std::string s){ std::size_t pos =0; while((pos = s.find("&gt;"))!= s.npos){ s.replace(pos,4,">");} while((pos = s.find("&lt;"))!= s.npos){ s.replace(pos,4,"<");} while((pos = s.find("&amp;"))!= s.npos){ s.replace(pos,5,"&");} return s; } ///////////////////////////////////////////////////////////////////// // Given: s == " a + c " // RetVal == {" ", "a", " ", "+", "c", " "} // std::vector<std::string> tokenize(const std::string& s){ std::vector<std::string> result; std::string temp =""; unsigned i =0; while(i < s.length()){ while(isspace(s[i])&&(i < s. temp =""; } } return result; }
  • 19. ASTree.hpp /* * ASTree.hpp * Abstract Syntax Tree * * Created by Jonathan Maletic on 11/8/11. * Copyright 2013 Kent State University. All rights reserved. * * Modified by: * */ #ifndef INCLUDES_ASTree_H_ #define INCLUDES_ASTree_H_ #include <list> #include <vector> #include <iostream> #include <iomanip> #include <cassert> #include <algorithm> #include <string> class ASTree; enum nodes {category, token, whitespace}; const bool TAGS = false; bool isStopTag (std::string); std::string readUntil (std::istream&, char); std::string unEscape (std::string); std::vector<std::string> tokenize (const std::string& s); ////////////////////////////////////////////////////////////////////////
  • 20. // An ASTree is either a: // -Syntactic category node // -Token node // -Whitespace node // // CLASS INV: if (nodeType == category) than (child != 0) && (text == "") // if ((nodeType == token) || (nodeType == whitespace)) then (child == 0) && (text != "") // class ASTree { public: ASTree () {}; ASTree (nodes t) : nodeType(t) {}; ASTree (nodes t, const std::string&); ~ASTree () {}; //NEED TO IMPLEMENT ASTree (const ASTree&); void swap (ASTree&); ASTree& operator= (ASTree); ASTree* copyASTree(); ASTree* getChild (std::string); std::string getName () const; void mainHeader(std::vector<std::string>&); void fileHeader(std::vector<std::string>&); void mainReport(std::vector<std::string>&); void funcCount (); void lineCount (const std::string&); std::ostream& print (std::ostream&, int) const; std::istream& read (std::istream&); private: nodes nodeType; //Category, Token, or Whitespace std::string tag, //Category: the tag name and closeTag; // closing tag.
  • 21. std::list<ASTree*> child; //Category: A list of subtrees. std::string text; //Token/Whitespace: the text. }; //////////////////////////////////////////////////////////////////////// // srcML is an internal data structure for a srcML input file. // CLASS INV: Assigned(tree) // class srcML { public: srcML () : tree(0) {}; ~srcML () {delete tree;} srcML (const srcML&); void swap (srcML&); srcML& operator= (srcML); void mainHeader(std::vector<std::string>&); void fileHeader(std::vector<std::string>&); void mainReport(std::vector<std::string>&); void funcCount (); void lineCount (const std::string&); friend std::istream& operator>>(std::istream&, srcML&); friend std::ostream& operator<<(std::ostream&, const srcML&); private: std::string header; ASTree* tree; }; #endif
  • 22. main.cppmain.cpp/* * main.cpp * Profiler * * Created by Jonathan Maletic on 11/8/11. * Copyright 2013 Kent State University. All rights reserved. * * Requires main.cpp first, followed by other files. * * Modified by: * */ #include<iostream> #include<fstream> #include<vector> #include<string> #include<algorithm> #include"ASTree.hpp" #include"profile.hpp" // // Reads a srcML file into an internal data structure. // Then prints out the data structure. int main(int argc,char*argv[]){ if(argc <2){ std::cerr <<"Error: One or more input files are required."<< s td::endl; std::cerr <<" The main must be the first argument follow ed by any other .cpp files. For example:"<< std::endl; std::cerr <<"profiler main.cpp.xml file1.cpp.xml file2.cpp.xm
  • 23. l"<< std::endl << std::endl; return(1); } srcML code;//The source code to be profiled. std::vector<std::string> files;//The list of file names (without .xml) std::vector<std::string> profileNames;//The list of profile nam es to be used. for(int i =1; i < argc;++i){ std::string filename = argv[i]; files.push_back(filename); filename = filename.substr(0, filename.find(".xml"));//Remov e .xml std::replace(filename.begin(), filename.end(),'.','_');// Change . to _ profileNames.push_back(filename); } std::ifstream inFile(files[0].c_str());//Read in the main. inFile >> code; inFile.close(); code.mainHeader(profileNames);//Add in main header info code.mainReport(profileNames);//Add in the report code.funcCount();//Count funciton invocations code.lineCount(profileNames[0]);//Count line invocations std::string outFileName ="p-"+ files[0]; outFileName = outFileName.substr(0, outFileName.find(".xml" ));//Remove .xml std::ofstream outFile(outFileName.c_str()); outFile << code << std::endl; outFile.close();
  • 24. for(unsigned i =1; i < files.size();++i){//Read in the rest of the f iles. inFile.open(files[i].c_str()); inFile >> code; inFile.close(); code.fileHeader(profileNames);//Add in file header info code.funcCount();//Count funciton invocations code.lineCount(profileNames[i]);//Count line invocations outFileName ="p-"+ files[i]; outFileName = outFileName.substr(0, outFileName.find(".xm l"));//Remove .xml outFile.open(outFileName.c_str()); outFile << code << std::endl; outFile.close(); } return0; } Makefile #============================================== ============================== # Make file for Profiler # # CS II Kent State University # # J. Maletic 2015 ##################################################### ##########
  • 25. # Variables CPP = clang++ CPP_OPTS = -g -Wall -W -Wunused -Wuninitialized -Wshadow -std=c++11 ##################################################### ########## # The first rule is run if only make is typed msg: @echo 'Targets are:' @echo ' profiler:' @echo ' sort:' @echo ' p-sort:' @echo ' clean:' ##################################################### ########## profiler : main.o ASTree.o $(CPP) $(CPP_OPTS) -o profiler main.o ASTree.o main.o : main.cpp ASTree.hpp $(CPP) $(CPP_OPTS) -c main.cpp ASTree.o : ASTree.hpp ASTree.cpp $(CPP) $(CPP_OPTS) -c ASTree.cpp #============================================== ================ # sort sort : sort.o sort_lib.o $(CPP) $(CPP_OPTS) -o sort sort.o sort_lib.o sort.o: sort_lib.h sort.cpp $(CPP) $(CPP_OPTS) -c sort.cpp sort_lib.o: sort_lib.h sort_lib.cpp
  • 26. $(CPP) $(CPP_OPTS) -c sort_lib.cpp #============================================== ================ # p-sort # p-sort.cpp # p-sort_lib.cpp p-sort : profile.o p-sort.o p-sort_lib.o $(CPP) $(CPP_OPTS) -o p-sort profile.o p-sort.o p- sort_lib.o p-sort.o: profile.hpp sort_lib.h p-sort.cpp $(CPP) $(CPP_OPTS) -c p-sort.cpp p-sort_lib.o: profile.hpp sort_lib.h p-sort_lib.cpp $(CPP) $(CPP_OPTS) -c p-sort_lib.cpp profile.o: profile.hpp profile.cpp $(CPP) $(CPP_OPTS) -c profile.cpp ##################################################### ########## #This will clean up everything via "make clean" clean: rm -f profiler rm -f sort rm -f *.o rm -f p-* profile.cppprofile.cpp/* * profile.cpp *
  • 27. * Created by Jonathan Maletic on 3/29/2012. * Copyright 2012 Kent State University. All rights reserved. * * Modified by: * */ #include"profile.hpp" //////////////////////////////////////////////////////////////////////// // Prints out the profile. // // TODO: Very simple output, need to make it into columns with nice headings. // std::ostream&operator<<(std::ostream& out,const profile& p){ for(std::map<std::string,int>::const_iterator i = p.item.begin(); i != p.item.end();++i){ out << i->first <<" "<< i->second << std::endl; } return out; } ////////////////////////////////////////////////////////// // PRE: n >= 0 // POST: Returns a text version of a positive integer long std::string intToString(int n){ assert(n >=0); std::string result; if(n ==0)return"0"; while(n >0){
  • 28. result =char(int('0')+(n %10))+ result; n = n /10; } return result; } profile.hpp /* * profile.hpp * * Created by Jonathan Maletic on 3/29/2012. * Copyright 2012 Kent State University. All rights reserved. * * Modified by: * */ #ifndef INCLUDES_PROFILE_H_ #define INCLUDES_PROFILE_H_ #include <iostream> #include <cassert> #include <string> #include <map> #include <algorithm> std::string intToString(int); //////////////////////////////////////////////////////////////////////// // A map of line numbers or line number function names and the number // of times each was called. // //
  • 29. class profile { public: profile () {}; void count (const int line, const std::string& fname) { item[intToString(line) + " " + fname] += 1; } void count (const int line) { item[intToString(line)] += 1; } friend std::ostream& operator<< (std::ostream&, const profile&); private: std::map<std::string, int> item; //Map of items and their counts }; #endif simple.cppsimple.cpp////////////////////////////////////////////////////////// ////////// // File: simple.cpp // Creation: 4/2013 // Programmer: Dr. J. Maletic // // Description: Simple program for testing profiler // // #include<iostream> int search(int tbl[],int n,int key){ int result =-1; for(int i =0; i < n;++i){ if(key == tbl[i]){ result = i;
  • 30. } } return result; } int main(){ int lst[5]={2,4,6,8,10}; std::cout << search(lst,5,6); std::cout << std::endl; std::cout <<"Done"; std::cout << std::endl; return0; } simple.cpp.xml //////////////////////////////////////////////////////////////////// // File: simple.cpp // Creation: 4/2013 // Programmer: Dr. J. Maletic // // Description: Simple program for testing profiler // // # include <iostream> int search ( int tbl [], int n, int key) { int result = -1; for ( int i = 0; i < n; ++ i) { if ( key == tbl [ i]) { result = i; }
  • 31. } return result; } int main () { int lst [ 5] = { 2, 4, 6, 8, 10}; std:: cout << search ( lst, 5, 6); std:: cout << std:: endl; std:: cout << "Done"; std:: cout << std:: endl; return 0; } sort.cppsort.cpp/** * @brief Application to run sorting algorithms on random int d ata * * @author Dale Haverstock * @date 2012-04-19 */ //============================================== ================================ #include"sort_lib.h" #include<iostream> #include<iomanip> #include<vector> #include<cstdlib> //============================================== ================================
  • 32. // Using declarations using std::string; using std::vector; using std::cout; using std::cerr; //============================================== ================================ // Function declarations void process_command_line(Options& opts,int argc,char* argv[ ]); void generate_random_data(vector<int>& data,int size,int seed,i nt mod); void output_data(const vector<int>&); void output_usage_and_exit(const string& cmd); void output_error_and_exit(const string& msg); //============================================== ================================ int main(int argc,char* argv[]) { // Options container Options opts; // Get values from the command line, opts may be changed process_command_line(opts, argc, argv); // Generate data vector<int> data; generate_random_data(data, opts._data_size, opts._seed, opts. _mod); // Output data before sorting if(opts._output_data) { cout <<"nData Before: "; output_data(data);}
  • 33. // Sort, if a sort was specified, there is no default if(opts._quick_sort){ quick_sort(data);} if(opts._selection_sort){ selection_sort(data);} if(opts._bubble_sort){ bubble_sort(data);} if(!opts._quick_sort && !opts._selection_sort && !opts._bubble_sort ) { output_error_and_exit("No sort specified.");} // Output data after sorting if(opts._output_sorted_data) { cout <<"nData After: "; output_data(data);} return0; } //============================================== ================================ void generate_random_data(vector<int>& vec,int size,int seed,i nt mod) { // Resize vector vec.resize(size); // Set random number generator seed srandom(static_cast<unsignedint>(seed)); // Put random values in vector for(vector<int>::size_type idx =0; idx < vec.size();++idx) { if(mod){ vec[idx]= random()% mod;} else{ vec[idx]= random();} } } //==============================================
  • 34. ================================ void output_data(const vector<int>& vec) { // Number of columns, column width constint cols =7; constint width =10; // Output vector elements for(vector<int>::size_type idx =0; idx < vec.size();++idx) { // Output newline to end row if(!(idx % cols)) { cout <<"n";} cout << std::setw(width)<< vec[idx]<<" "; } cout <<'n'; } //============================================== ================================ // Note: // * No check for C-string to int conversion success // void process_command_line(Options& opts,int argc,char* argv[ ]) { // Useage message if no command line args if(argc ==1) { output_usage_and_exit(argv[0]);} // Go through the argumets for(int idx =1; idx < argc;++idx) { // Standard library string from C-string
  • 35. string opt(argv[idx]); // Process the option if(opt =="-h"){ output_usage_and_exit(argv[0]);} if(opt =="-qs"){ opts._quick_sort =true;} if(opt =="-ss"){ opts._selection_sort =true;} if(opt =="-bs"){ opts._bubble_sort =true;} if(opt =="-od"){ opts._output_data =true;} if(opt =="-osd"){ opts._output_sorted_data =true;} if(opt =="-sz") { if(idx +1< argc){++idx; opts._data_size = atoi(argv[idx]);} else{ output_error_and_exit("Value for - sz option is missing.");} } if(opt =="-rs") { if(idx +1< argc){++idx; opts._seed = atoi(argv[idx]);} else{ output_error_and_exit("Value for - rs option is missing.");} } if(opt =="-mod") { if(idx +1< argc){++idx; opts._mod = atoi(argv[idx]);} else{ output_error_and_exit("Value for - mod option is missing.");} } if((opt !="-h")&& (opt !="-qs")&& (opt !="-ss")&& (opt !="-bs")&& (opt !="-od")&& (opt !="-osd")&& (opt !="-sz")&& (opt !="-rs")&& (opt !="-mod"))
  • 36. { output_error_and_exit(string("Error: Bad option: ")+ opt); } } } //============================================== ================================ void output_usage_and_exit(const string& cmd) { cout << "Usage: "<< cmd <<" [options]n" " Options:n" " -sz int The number of data itemsn" " -rs int The random number generator seedn" " -mod int The mod value for random numbersn" " -od Output data to be sortedn" " -osd Output sorted datan" " -qs Use quick sortn" " -ss Use selection sortn" " -bs Use bubble sortn" " -h This messagen" "n" " A sort must be specified, there is no default sort.n" " If more than 1 sort is specified then the first sortn" " specified from the following order will be done.n" " 1. quickn" " 2. selectionn" " 3. bubblen"; exit(0); } //============================================== ================================ void output_error_and_exit(const string& msg)
  • 37. { cerr <<"Error: "<< msg <<"n"; exit(1); } sort.cpp.xml /** * @brief Application to run sorting algorithms on random int data * * @author Dale Haverstock * @date 2012-04-19 */ //============================================== ================================ # include "sort_lib.h" # include <iostream> # include <iomanip> # include <vector> # include <cstdlib> //============================================== ================================ // Using declarations using std:: string; using std:: vector; using std:: cout; using std:: cerr;
  • 38. //============================================== ================================ // Function declarations void process_command_line ( Options& opts, int argc, char* argv []); void generate_random_data ( vector < int>& data, int size, int seed, int mod); void output_data ( const vector < int>&); void output_usage_and_exit ( const string& cmd); void output_error_and_exit ( const string& msg); //============================================== ================================ int main ( int argc, char* argv []) { // Options container Options opts; // Get values from the command line, opts may be changed process_command_line ( opts, argc, argv); // Generate data vector < int> data; generate_random_data ( data, opts. _data_size, opts. _seed, opts. _mod); // Output data before sorting if ( opts. _output_data) { cout << "nData Before: "; output_data ( data); } // Sort, if a sort was specified, there is no default if ( opts. _quick_sort) { quick_sort ( data); } if ( opts. _selection_sort) { selection_sort ( data); } if ( opts. _bubble_sort) { bubble_sort ( data); } if ( ! opts. _quick_sort &&
  • 39. ! opts. _selection_sort && ! opts. _bubble_sort ) { output_error_and_exit ( "No sort specified."); } // Output data after sorting if ( opts. _output_sorted_data) { cout << "nData After: "; output_data ( data); } return 0; } //============================================== ================================ void generate_random_data ( vector < int>& vec, int size, int seed, int mod) { // Resize vector vec. resize ( size); // Set random number generator seed srandom ( static_cast<unsigned int>(seed)) ; // Put random values in vector for ( vector < int>:: size_type idx = 0; idx < vec. size (); ++ idx) { if ( mod) { vec [ idx] = random () % mod; } else { vec [ idx] = random (); } } } //============================================== ================================ void output_data ( const vector < int>& vec)
  • 40. { // Number of columns, column width const int cols = 7; const int width = 10; // Output vector elements for ( vector < int>:: size_type idx = 0; idx < vec. size (); ++ idx) { // Output newline to end row if ( ! ( idx % cols) ) { cout << "n"; } cout << std:: setw ( width) << vec [ idx] << " "; } cout << 'n'; } //============================================== ================================ // Note: // * No check for C-string to int conversion success // void process_command_line ( Options& opts, int argc sort_lib.cppsort_lib.cpp/** * @brief Application to run sorting algorithms on random int d ata * * @author Dale Haverstock * @date 2012-04-19 */ // sort library
  • 41. // //============================================== ================================ #include"sort_lib.h" #include<vector> //============================================== ================================ // Make shorter type names typedef std::vector<int>::size_type Vec_Idx; //============================================== ================================ // Function declarations, uppercase so those stand out void quick_sort(std::vector<int>& data,int left,int right); void SWAP(int& n1,int& n2); bool LESS_THAN(int n1,int n2); bool GREATER_THAN(int n1,int n2); //============================================== ================================ void quick_sort(std::vector<int>& data) { // Do nothing if empty vector if(data.size()==0) {return;} // Do the sort quick_sort(data,0, data.size()-1); } //============================================== ================================ // The unsigned ints cause problems here, jdx may go to -1. // Subscripts are cast so there are no warnings.
  • 42. void quick_sort(std::vector<int>& data,int left,int right) { // Calculate the pivot int pivot = data[Vec_Idx((left + right)/2)]; // Partition int idx = left, jdx = right; while(idx <= jdx){ while(LESS_THAN(data[Vec_Idx(idx)], pivot)) idx++; while(GREATER_THAN(data[Vec_Idx(jdx)], pivot)) jdx--; if(idx <= jdx) { SWAP(data[Vec_Idx(idx)], data[Vec_Idx(jdx)]); idx++; jdx--; } } // Recurse if(left < jdx) { quick_sort(data, left, jdx);} if(idx < right) { quick_sort(data, idx, right);} } //============================================== ================================ void selection_sort(std::vector<int>& data) { // Do nothing if empty vector (note unsigned 0 - 1 is a big number)
  • 43. if(data.size()==0) {return;} // Index of last element in vector, also last in unsorted part Vec_Idx last = data.size()-1; // Do the sort while(last >0) { // Find greatest in unsorted part Vec_Idx idx_of_greatest =0; for(Vec_Idx idx =0; idx <= last;++idx) { if( LESS_THAN(data[idx_of_greatest], data[idx])) { // Remember as new greatest so far idx_of_greatest = idx; } } // Swap last in unsorted with greatest in unsorted part SWAP(data[last], data[idx_of_greatest]); // Increase sorted part --last; } } //============================================== ================================ void bubble_sort(std::vector<int>& data) { // Go through vector repeatedly for(Vec_Idx limit = data.size(); limit >0; limit--) { // Go through vector once, swap element and next element if out
  • 44. of order for(Vec_Idx idx =0; idx < limit -1; idx++) { if( LESS_THAN(data[idx +1], data[idx])) { SWAP(data[idx],data[idx +1]); } } } } //============================================== ================================ // This is here so the number of calls can be counted. void SWAP(int& n1,int& n2) { std::swap(n1, n2); } //============================================== ================================ // This is here so the number of calls can be counted. bool LESS_THAN(int n1,int n2) { return n1 < n2; } //============================================== ================================ // This is here so the number of calls can be counted. bool GREATER_THAN(int n1,int n2) { return n1 > n2; }
  • 45. sort_lib.cpp.xml /** * @brief Application to run sorting algorithms on random int data * * @author Dale Haverstock * @date 2012-04-19 */ // sort library // //============================================== ================================ # include "sort_lib.h" # include <vector> //============================================== ================================ // Make shorter type names typedef std:: vector < int>:: size_type Vec_Idx; //============================================== ================================ // Function declarations, uppercase so those stand out void quick_sort ( std:: vector < int>& data, int left, int right); void SWAP ( int& n1, int& n2); bool LESS_THAN ( int n1, int n2); bool GREATER_THAN ( int n1, int n2);
  • 46. //============================================== ================================ void quick_sort ( std:: vector < int>& data) { // Do nothing if empty vector if ( data. size () == 0) { return; } // Do the sort quick_sort ( data, 0, data. size () - 1); } //============================================== ================================ // The unsigned ints cause problems here, jdx may go to -1. // Subscripts are cast so there are no warnings. void quick_sort ( std:: vector < int>& data, int left, int right) { // Calculate the pivot int pivot = data [ Vec_Idx ( ( left + right) / 2)]; // Partition int idx = left, jdx = right; while ( idx <= jdx) { while ( LESS_THAN ( data [ Vec_Idx ( idx)], pivot)) idx++; while ( GREATER_THAN ( data [ Vec_Idx ( jdx)], pivot)) jdx--; if ( idx <= jdx) {
  • 47. SWAP ( data [ Vec_Idx ( idx)], data [ Vec_Idx ( jdx)]); idx++; jdx--; } } // Recurse if ( left < jdx) { quick_sort ( data, left, jdx); } if ( idx < right) { quick_sort ( data, idx, right); } } //============================================== ================================ void selection_sort ( std:: vector < int>& data) { // Do nothing if empty vector (note unsigned 0 - 1 is a big number) if ( data. size () == 0) { return; } // Index of last element in vector, also last in unsorted part Vec_Idx last = data. size () - 1; // Do the sort while ( last > 0) { // Find greatest in unsorted part Vec_Idx idx_of_greatest = 0; for ( Vec_Idx idx = 0; idx <= last; ++ idx) { if ( LESS_THAN ( data [ idx_of_greatest],
  • 48. data [ idx]) ) { // Remember as new greatest so far idx_of_greatest = idx; } } // Swap last in unsorted with greatest in unsorted part SWAP ( data [ last], data [ idx_of_greatest]); // Increase sorted part -- last; } } //============================================== ================================ void bubble_sort ( std:: vector < int>& data) { // Go through vector repeatedly for( Vec_Idx limit = data. size (); limit > 0; limit-- ) data [ idx + 1] sort_lib.h /** * @brief Application to run sorting algorithms on random int data * * @author Dale Haverstock * @date 2012-04-19 */ #ifndef SORT_LIB_H #define SORT_LIB_H
  • 49. //============================================== ================================ #include <vector> //============================================== ================================ struct Options { // Option values int _seed; int _data_size; int _mod; bool _output_data; bool _output_sorted_data; bool _bubble_sort; bool _selection_sort; bool _quick_sort; // Defaults Options() : _seed(0), _data_size(0), _mod(0), _output_data(false), _output_sorted_data(false), _bubble_sort(false), _selection_sort(false), _quick_sort(false) { } }; //============================================== ================================ void selection_sort(std::vector<int>&); void quick_sort(std::vector<int>&);