Showing posts with label Vector. Show all posts
Showing posts with label Vector. Show all posts

Tuesday, 22 March 2011

Reading Files into Vector

Thought of this while trying to create a parser. The intention is to read a complete text file into a vector and then use this vector for other operations. This program shows how to read from a text file into vectors.

The input file is as follows:

Line num 1

Another line

Line number 3

4th Line!

**%** Last line **%**

Program as follows:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include <iostream>
#include <vector>
#include <fstream>
#include <string>

using namespace
std;

int
main()
{

vector<std::string> lines;
lines.reserve(5000); //Assuming that the file to read can have max 5K lines

string fileName("test.txt");

ifstream file;
file.open(fileName.c_str());

if
(!file.is_open())
{

cerr<<"Error opening file : "<<fileName.c_str()<<endl;
return
-1;
}


//Read the lines and store it in the vector
string line;
while
(getline(file,line))
{

lines.push_back(line);
}


file.close();

//Dump all the lines in output
for(unsigned int i = 0; i < lines.size(); i++)
{

cout<<i<<". "<<lines[i]<<endl;
}


return
0;
}




Output as follows:

Tuesday, 22 February 2011

A generic sort program with 'functors' and 'templates'

Picked up this question from here and made a program out of it. It may be a good idea to quickly brush functors and templates if required.

The program sorts the input Vector provided regardless of the type.




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace
std;

class
Int
{

public
:
Int() {x_ = 0;}
Int(const int &x) {x_ = x;}
int
getID (void) {return x_;}
int
x_;
};


class
Str
{

public
:
Str() {x_ = "";}
Str(const string &x) {x_ = x;}
string getID (void) {return x_;}
string x_;
};


template
<typename Object> class Comparator {
public
:
bool
operator()(const Object &o1, const Object &o2) const
{

return
(const_cast<Object&>(o1).getID() < const_cast<Object&>(o2).getID());
}


bool
operator()(const Object *o1, const Object *o2) const {
return
(o1->getID() < o2->getID());
}
};


template
<typename VecObject> void Display(VecObject v)
{

VecObject::iterator it;
for
(it = v.begin(); it != v.end(); ++it)
{

cout<<it->getID()<<", ";
}

cout<<endl;
}


int
main()
{

vector<Int> objects1;
objects1.push_back(Int(3));
objects1.push_back(Int());
objects1.push_back(Int(77));

//print the output
cout<<"objects1 before sort = ";
Display(objects1);
std::sort(objects1.begin(), objects1.end(), Comparator<Int> ());
cout<<"objects1 after sort = ";
Display(objects1);

std::vector<Str> objects2;
objects2.push_back(Str("Hello Hello"));
objects2.push_back(Str("apple?"));
objects2.push_back(Str());
objects2.push_back(Str("1 Jump"));

//print the output
cout<<"objects2 before sort = ";
Display(objects2);
std::sort(objects2.begin(), objects2.end(), Comparator<Str> ());
cout<<"objects2 after sort = ";
Display(objects2);

return
0;
}




The output is as follows:

Wednesday, 30 June 2010

Example of Permutations in C++

Example of how you can let the Algorithm class generate permutations of String



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>

using namespace
std;

int
main()
{

string someString="ABC";
vector<string> someVector;

someVector.push_back(someString);

string::iterator itBegin = someString.begin();
string::iterator itEnd = someString.end();

while
(next_permutation(itBegin, itEnd)) //std::next_permutation defined in algorithm
{
someVector.push_back(string(itBegin, itEnd));
}

copy(someVector.begin(), someVector.end(), ostream_iterator<string>(cout, "\n"));

return
0;
}



The output is as follows:


Wednesday, 26 May 2010

std::search example on vector and string

Continuing from last weeks theme, here is a simple example of std::search.




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include <iostream>
#include <vector>
#include <string>
#include <algorithm> //needed for std::search

using namespace
std;

bool
isOdd(int i)
{

return
((i%2)==1);
}


int
main()
{

vector<int> v1;
v1.push_back(88);
v1.push_back(99);
v1.push_back(22);
v1.push_back(33);
v1.push_back(44);
v1.push_back(55);
v1.push_back(66);
v1.push_back(77);

//Demonstrating Search - Matching Case
vector<int> v2;
v2.push_back(22);
v2.push_back(33);
v2.push_back(44);

vector<int>::const_iterator it = search(v1.begin(), v1.end(), v2.begin(), v2.end());
if
(it != v1.end())
{

cout<<"Found: "<<*it<<endl;
cout<<"Position = "<<it - v1.begin() + 1<<endl;
}

else

{

cout<<"Not Found"<<endl;
cout<<"Position = -1"<<endl;
}


//Demonstrating Search - Non-Matching Case
vector<int> v3;
v3.push_back(22);
v3.push_back(33);
v3.push_back(444); //non matching

it = search(v1.begin(), v1.end(), v3.begin(), v3.end());
if
(it != v1.end())
{

cout<<"Found: "<<*it<<endl;
cout<<"Position = "<<it - v1.begin() + 1<<endl;
}

else

{

cout<<"Not Found"<<endl;
cout<<"Position = -1"<<endl;
}


//Use the search to find strings
string s1="Hello, this is Zahid";

//Matching case
string s2="Zahid";

string::const_iterator it2 = search(s1.begin(), s1.end(), s2.begin(), s2.end());
if
(it2 != s1.end())
{

cout<<"Found: "<<*it2<<endl;
cout<<"Position = "<<it2 - s1.begin() + 1<<endl;
}

else

{

cout<<"Not Found"<<endl;
cout<<"Position = -1"<<endl;
}


//Non-Matching case
string s3="None";

it2 = search(s1.begin(), s1.end(), s3.begin(), s3.end());
if
(it2 != s1.end())
{

cout<<"Found: "<<*it2<<endl;
cout<<"Position = "<<it2 - s1.begin() + 1<<endl;
}

else

{

cout<<"Not Found"<<endl;
cout<<"Position = -1"<<endl;
}


return
0;
}






The output is as follows:

Wednesday, 19 May 2010

std::find and std::find_if for finding information in vectors

Here is a simple program that demonstrates how to use find and find_if with vectors.




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include <iostream>
#include <vector>
#include <algorithm> //needed for std::find

using namespace
std;

bool
isOdd(int i)
{

return
((i%2)==1);
}


int
main()
{

vector<int> v1;
v1.push_back(88);
v1.push_back(99);
v1.push_back(22);
v1.push_back(33);
v1.push_back(44);
v1.push_back(55);
v1.push_back(66);
v1.push_back(77);

//Demonstrating Find - Find number 55 and its position, if present
vector<int>::const_iterator it = find(v1.begin(), v1.end(), 55);
if
(it != v1.end())
{

cout<<"Found: "<<*it<<endl;
cout<<"Position = "<<it - v1.begin() + 1<<endl;
}

else

{

cout<<"Not Found"<<endl;
cout<<"Position = -1"<<endl;
}


//Demonstrating Find IF - Find the first Odd number and its position
it = find_if(v1.begin(), v1.end(), isOdd);
if
(it != v1.end())
{

cout<<"Found: "<<*it<<endl;
cout<<"Position = "<<it - v1.begin() + 1<<endl;
}

else

{

cout<<"No Odd Numbers Found"<<endl;
cout<<"Position = -1"<<endl;
}


return
0;
}






The output is as follows:

Wednesday, 14 April 2010

C++ example of 'transform'

From the CPP Reference:
#include
  1. output_iterator transform( input_iterator start, input_iterator end, output_iterator result, UnaryFunction f );
  2. output_iterator transform( input_iterator start1, input_iterator end1, input_iterator2 start2, output_iterator result, BinaryFunction f );
The transform algorithm applies the function f to some range of elements, storing the result of each application of the function in result.

The first version of the function applies f to each element in [start,end) and assigns the first output of the function to result, the second output to (result+1), etc.

The second version of the transform works in a similar manner, except that it is given two ranges of elements and calls a binary function on a pair of elements.

Here is an example that is modified from C++ Reference:




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Program to show how transform works in C++

#include<iostream>
#include<vector>
#include<algorithm> //for the transform() function

using namespace
std;

int
increase (int i) { return ++i; }
int
sum (int i, int j) { return i+j; }

int
main()
{

int
someNums[] = {10,20,30,40,50}; //Array of 5 values
//Another way to initialise a vector using the iterator constructor
vector<int> vectorOne (someNums, someNums + sizeof(someNums) / sizeof(int));
vector<int> vectorTwo;
vector<int>::iterator it;

cout<<"vectorOne elements are : ";
for
(unsigned int i = 0; i < vectorOne.size(); ++i)
cout<<vectorOne[i]<<" ";
cout<<endl;

vectorTwo.resize(vectorOne.size()); //allocate space

//OutputIterator transform ( InputIterator first1, InputIterator last1,
// OutputIterator result, UnaryOperator op );
std::transform(vectorOne.begin(), vectorOne.end(), vectorTwo.begin(), increase);

cout<<"\nAfter transform with increase:"<<endl;
cout<<"vectorOne elements are : ";
for
(unsigned int i = 0; i < vectorOne.size(); ++i)
cout<<vectorOne[i]<<" ";
cout<<endl;
cout<<"vectorTwo elements are : ";
for
(unsigned int i = 0; i < vectorTwo.size(); ++i)
cout<<vectorTwo[i]<<" ";
cout<<endl;

//OutputIterator transform ( InputIterator1 first1, InputIterator1 last1,
// InputIterator2 first2, OutputIterator result,
// BinaryOperator binary_op );
transform (vectorOne.begin(), vectorOne.end(), vectorTwo.begin(), vectorOne.begin(), sum);

cout<<"\nAfter transform with sum:"<<endl;
cout<<"vectorOne elements are : ";
for
(unsigned int i = 0; i < vectorOne.size(); ++i)
cout<<vectorOne[i]<<" ";
cout<<endl;
cout<<"vectorTwo elements are : ";
for
(unsigned int i = 0; i < vectorTwo.size(); ++i)
cout<<vectorTwo[i]<<" ";
cout<<endl;

return
0;
}





The output is as follows:

Wednesday, 31 March 2010

Deleting of Vectors content to avoid memory leaks

Its interesting how deleting of vectors can sometimes be a problem as people tend to make simple mistakes that can cause crash and waste useful hours to debug.

The following code shows my approach to deleting of vectors. I am sure there are better approaches. In case you know one please share.




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Program to demonstrate a simple way to delete vector and memory
//associated with it.

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include<iostream>
#include <crtdbg.h>
#include<vector>

#ifdef _DEBUG
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif

using namespace
std;

int
main()
{

_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF _CRTDBG_LEAK_CHECK_DF );
vector<int *> someVector;
for
(int i = 0; i < 5; i++)
{

int
* x = new int(i * 15);
someVector.push_back(x);
}


//now we need to delete the elements of the vector else it will generate memory leaks
//This is one simple and safe approach
while (!someVector.empty())
{

vector<int *>::iterator it = someVector.begin();
if
(*it) //Additional safety in case a NULL pointer was stored
delete (*it); //because *it = *int - Only the contents are deleted
someVector.erase(it);
}


return
0;
}





You can check my old post on how to see if memory leaks are there. This program shows another approach but the results are the same

No output needed.

You can read more about this approach of detecting memory leaks on the MSDN site here.

Wednesday, 24 February 2010

The power of 'typedef' in C++

C++ allows the definition of our own types based on other existing data types. We can do this using the keyword typedef, whose format is:

typedef existing_type new_type_name ;

where existing_type is a C++ fundamental or compound type and new_type_name is the name for the new type we are defining.

For example:
typedef char C;
typedef unsigned int WORD;
typedef char * pChar;
typedef char field [50];

There are many scenarios where using typedef's are very advantageous. The following program is written based on the reasons for using typedef's as defined by Herb Sutter in his book "More Exceptional C++"



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Program showing the advantages of using typedefs in C++

#include<iostream>
#include<map>
#include<vector>
#include<list>
#include<assert.h>

using namespace
std;

//Comment/Uncomment as required
//#define USING_MAPS
#define USING_OTHER_STL

//5 - Portability: Useful if different users want to use different STL classes
#if defined USING_MAPS
typedef map<int,int> table; //1 - Typeability: table is easier to type
#else
//4 - Flexibility: In future you could replace a map by a vector for example
typedef vector<int> table;
//typedef list<int> table;
#endif

typedef
table::iterator tableIter;

//map<int,int> multiplicationTableTill10(int num); - not very readable
table multiplicationTableTill10(int num); //2 - Readability: Easier to read

int
main()
{

int
i = 1;
table t = multiplicationTableTill10(7);
for
(tableIter t_iter = t.begin(); t_iter != t.end(); ++t_iter, ++i)
{

#if defined USING_MAPS
cout<<"7 * "<<i<<" = "<<t[i]<<endl;
#elif defined USING_OTHER_STL
cout<<"7 * "<<i<<" = "<<*t_iter<<endl;
#else
assert(0);
#endif
}
return
0;
}


typedef
int Multiplier; //int is also now written as Multiplier

//This program creates a multiplication table of the number input from 1 to 10
table multiplicationTableTill10(int num)
{

table t;
tableIter t_iter;
//3 - Communication: Multiplier is more meaningful then int in the case below
for(Multiplier i = 1; i <= 10; i++)
{

#if defined USING_MAPS
t[i] = num * i;
#elif defined USING_OTHER_STL
t_iter = t.end();
t.insert(t_iter, num * i);
#else
assert(0);
#endif
}
return
t;
}






The Output is as follows:



More information on Typedefs:


Sunday, 8 March 2009

More on Vector Manipulation

This is slightly advanced vector manipulation program


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This program shows advanced vector manipulation
#include<iostream>
#include<vector>

using namespace
std;

//This method prints the vector
void printer(vector<int> v)
{

unsigned int
i;
cout << "Size = " << v.size() << endl;
cout << "Contents = ";
for
(i = 0; i <v.size(); i++)
cout<<v[i]<<" ";
cout<<endl;
}


//Overloaded method same as above but takes pointers
void printer(vector<int*> v)
{

unsigned int
i;
cout << "\nOverloaded Method " << endl;
cout << "Size = " << v.size() << endl;
cout << "Contents = ";
for
(i = 0; i <v.size(); i++)
cout<<*v[i]<<" ";
cout<<endl;
}


int
main()
{

vector<int> v1(5, 1);
cout<<"** Original **"<<endl;
printer(v1);

unsigned int
i;
//Modifying the list above
for(i = 0; i < v1.size(); i++)
v1[i] = i + 3;
cout<<"\n** Modified **"<<endl;
printer(v1);

vector<int>::iterator it;
//Inserting in the list after the first element '0' and after the 4th elem '9 9 9 9'
it = v1.begin();
it += 1;
v1.insert(it,0);
it = v1.begin(); //Crash if you dont do this
it += 5; //Because we inserted '0', 4th element has become 5th.
v1.insert(it, 4, 9);
cout<<"\n** After Insert **"<<endl;
printer(v1);

//Testing Pop back - removes element from the end
v1.pop_back();
v1.pop_back();
cout<<"\n** After couple of Pop back's **"<<endl;
printer(v1);

//New Vector
cout<<endl<<"\n********** NEW *************"<<endl;
vector<int*> v2;
int
*a=new int(5);
int
*b=new int(6);
int
*c=new int(7);
int
*d=new int(11);
v2.push_back(a);
v2.push_back(b);
v2.push_back(c);
printer(v2);
cout<<"\ntwo pop_back and a push_back"<<endl;
v2.pop_back();
v2.pop_back();
v2.push_back(d);
printer(v2);
cout<<"\nClear Vector two"<<endl;
v2.clear();
printer(v2);

return
0;
}




The output is as follows:

Saturday, 7 March 2009

Basic Vector Manipulation

Here is an example of basic vector manipulation




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy

//This program shows how to create vectors, check size and capacity,

//change the value of the elements and finally clear the vector

#include <iostream>

#include <vector>



using namespace
std;



int
main()

{


//Create a vector called vectorOne

vector<int> vectorOne; //Note size is 0

//Resize to 3 with default value 7

vectorOne.resize(3,7);

//Print the output to see the resize

cout<<"Test 1"<<endl;

for
(unsigned i=0;i<vectorOne.size();i++)

{


cout<<"Element: "<<i<<" Value: "<<vectorOne.at(i)<<endl;

}




//Resize further to 7 and new values default to 4

vectorOne.resize(7,4);

cout<<"\nTest 2"<<endl;

for
(unsigned i=0; i<vectorOne.size(); i++)

{


cout<<"Element: "<<i<<" Value: "<<vectorOne.at(i)<<endl;

}




//Check what the size and capacity of the vector is

cout<<endl;

cout<<"Size of vectorOne is: "<<vectorOne.size()<<endl;

cout<<"Capacity of vectorOne is: "<<vectorOne.capacity()<<endl;



//Lets modify the values of these vectors

for(unsigned i=0,j=22;i<vectorOne.size();i++,j+=i)

{


vectorOne.at(i)=j;

}




cout<<"\nTest 3"<<endl;

for
(unsigned i=0; i<vectorOne.size(); i++)

{


cout<<"Element: "<<i<<" Value: "<<vectorOne.at(i)<<endl;

}




//Use reserve to reallocate vectorOne with enough storage for 10 elements

vectorOne.reserve(10);

cout<<"\nSize of vectorOne is: "<<vectorOne.size()<<endl;

cout<<"Capacity of vectorOne is: "<<vectorOne.capacity()<<endl;



//Try resizing to 15 and dont add any default values for the new elements

vectorOne.resize(15);

cout<<"\nSize of vectorOne is: "<<vectorOne.size()<<endl;

cout<<"Capacity of vectorOne is: "<<vectorOne.capacity()<<endl;



//Remove all elements of the vector

vectorOne.clear();

cout<<"\nVector Cleared"<<endl;

cout<<"Size of vectorOne is: "<<vectorOne.size()<<endl;

cout<<"Capacity of vectorOne is: "<<vectorOne.capacity()<<endl;

cout<<endl;



return
0;

}


The output of the program is as follows: