1.5节中有对vector的简单介绍,所以就写了一个程序,用于表达书上运用vector的思想:
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <string>
using namespace std;
//备注:这里用到rand当然不好,因为rand并不是一个真正的随机数。
void getNum(vector< vector<int> > &ivvec, int &firstNum, int &secondNum, int &thirdNum)
{
int randomSeq = 0; //随机的序列
int randomBegin = 0; //随机序列中随机的第一个元素的索引
randomSeq = rand() % 6;
randomBegin = rand() % 6;
firstNum = ivvec[randomSeq][randomBegin];
secondNum = ivvec[randomSeq][randomBegin + 1];
thirdNum = ivvec[randomSeq][randomBegin + 2];
}
int main(void)
{
int arrFib[8] = {1, 1, 2, 3, 5, 8, 13, 21};
vector<int> iFibVec(arrFib, arrFib + 8);
int arrLuc[8] = {1, 3, 4, 7, 11, 18, 29, 47};
vector<int> iLucVec(arrLuc, arrLuc + 8);
int arrPel[8] = {1, 2, 5, 12, 29, 70, 169, 408};
vector<int> iPelVec(arrPel, arrPel + 8);
int arrTri[8] = {1, 3, 6, 10, 15, 21, 28, 36};
vector<int> iTriVec(arrTri, arrTri + 8);
int arrSqu[8] = {1, 4, 9, 16, 25, 36, 49, 64};
vector<int> iSquVec(arrSqu, arrSqu + 8);
int arrPen[8] = {1, 5, 12, 22, 35, 51, 70, 92};
vector<int> iPenVec(arrPen, arrPen + 8);
vector< vector<int> > ivvec;
ivvec.push_back(iFibVec);
ivvec.push_back(iLucVec);
ivvec.push_back(iPelVec);
ivvec.push_back(iTriVec);
ivvec.push_back(iSquVec);
ivvec.push_back(iPenVec);
//从ivvec中提取三个随机的数
bool bTry = true; //用户想再次尝试
const int maxTries = 5; //最多尝试次数
int numTries = 0; //用户尝试的次数
int numRight = 0; //用户正确的次数
while (bTry)
{
int firstNum = 0;
int secondNum = 0;
int thirdNum = 0;
getNum(ivvec, firstNum, secondNum, thirdNum);
cout << "the first number is: " << firstNum << "\nand the second number is: " << secondNum << endl;
cout << "please enter the third number: ";
int userNum = 0;
cin >> userNum;
string userSelect;
if (userNum == thirdNum)
{
numRight++;
numTries++;
cout << "you are right.do you want to try another numbers?(N/n to break, another continue)" << endl;
cin >> userSelect;
}
else
{
if (numTries > maxTries)
{
cout << "sorry, you have tried max times." << endl;
break;
}
numTries++;
cout <<"you are wrong. do you wang to try another numbers?(N/n to break, another continue)" << endl;
cin >> userSelect;
}
if ((userSelect == "n") || (userSelect == "N"))
{
break;
}
}
cout << "the rate success is: " << (numRight * 1.0 / numTries) * 100 << "%" << endl;
return 0;
}
在第二章中讲述如何编写函数,举了Fibonacci函数的例子:
#include <iostream>
using namespace std;
bool fibon_elem(int, int &);
int main(void)
{
int pos;
cout << "please enter a position:";
cin >> pos;
int elem;
if (fibon_elem(pos, elem))
{
cout << "element #" << pos<< " is " << elem << endl;
}
else
{
cout << "sorry. could not calculate element#" << pos << endl;
}
return 0;
}
bool fibon_elem(int pos, int &elem)
{
if ((pos <= 0) || (pos > 1024))
{
elem = 0;
return false;
}
elem = 1;
int n_2 = 1;
int n_1 = 1;
for (int ix = 3; ix <= pos; ix++)
{
elem = n_1 + n_2;
n_2 = n_1;
n_1 = elem;
}
return true;
}
调用一个函数:
#include <iostream>
#include <vector>
using namespace std;
void display(vector<int> ivec);
void swap(int &val1, int &val2);
void bubble_sort(vector<int> &ivec);
int main(void)
{
int ia[8] = {8, 34, 3, 13, 1, 21, 5, 2};
vector<int> ivec(ia, ia + 8);
cout << "vector before sort" << endl;
display(ivec);
bubble_sort(ivec);
cout << "vector after sort:" << endl;
display(ivec);
return 0;
}
void display(vector<int> ivec)
{
for (int ix = 0; ix < ivec.size(); ix++)
{
cout << ivec[ix] << " ";
}
cout << endl;
}
void swap(int &val1, int &val2)
{
int temp;
temp = val1;
val1 = val2;
val2 = temp;
}
void bubble_sort(vector<int> &ivec)
{
for (int ix = 0; ix < ivec.size(); ix++)
{
for (int jx = ix + 1; jx < ivec.size(); jx++)
{
if (ivec[ix] > ivec[jx])
{
swap(ivec[ix], ivec[jx]);
}
}
}
}
关于如何提供默认参数值:
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
void swap(int &val1, int &val2, ofstream *ofil = 0);
template<typename T>
void bubble_sort(vector<int> &ivec, T *ofil = 0);
void display(vector<int> &ivec, ostream &os = cout);
int main(void)
{
int ia[8] = {8, 7, 6, 5, 4, 3, 2, 1};
vector<int> ivec(ia, ia + 8);
cout << "before sort:" << endl;
display(ivec);
bubble_sort<ostream>(ivec, &cout);
cout << "after sort:" << endl;
display(ivec, cout);
return 0;
}
void display(vector<int> &ivec, ostream &os)
{
for (int ix = 0; ix < ivec.size(); ix++)
{
os << ivec[ix] << " ";
}
os << endl;
}
void swap(int &val1, int &val2, ofstream *ofil)
{
int temp;
temp = val1;
val1 = val2;
val2 = temp;
if (ofil != 0)
{
(*ofil) << "swap " << val1 << " and " << val2 << endl;
}
}
template<typename T>
void bubble_sort(vector<int> &ivec, T *ofil /* = 0 */)
{
for (int ix = 0; ix < ivec.size(); ix++)
{
for (int jx = ix + 1; jx < ivec.size(); jx++)
{
if (ivec[ix] > ivec[jx])
{
if (ofil != 0)
{
(*ofil) << "about to call swap! ix: " << ix
<< " jx: " << jx << "\tswapping :" << ivec[ix] << " with " << ivec[jx] << endl;
}
swap(ivec[ix], ivec[jx]);
}
}
}
}
使用局部静态对象:
#include <iostream>
#include <vector>
using namespace std;
vector< int > fibon_seq(int size);
int main(void)
{
vector< int > ivec;
ivec = fibon_seq(10);
ivec = fibon_seq(5);
for (int ix = 0; ix < ivec.size(); ix++)
{
cout << ivec[ix] << " ";
}
cout << endl;
return 0;
}
vector< int > fibon_seq(int size)
{
static vector< int > elems;
for (int ix = elems.size(); ix < size; ix++)
{
if ((ix == 0) || (ix == 1))
{
elems.push_back(1);
}
else
{
elems.push_back(elems[ix - 1] + elems[ix - 2]);
}
}
return elems;
}
函数指针的作用,增加灵活性:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void fun1(int iValue)
{
cout << iValue << endl;
}
void fun2(float fValue)
{
cout << fValue << endl;
}
void fun3(string sValue)
{
cout << sValue << endl;
}
template<typename funType>
void fun(void (*subfun)(funType), funType val)
{
(*subfun)(val);
}
int main(void)
{
fun<int>(fun1, 12);
fun<float>(fun2, 12.3);
fun<string>(fun3, "hello world");
return 0;
}
第三章介绍设计泛型算法的时候,自己就先设计了一下,运行了还可以,当然,用到了函数指针的思想:
#include <iostream>
#include <vector>
using namespace std;
template<typename T>
bool lessThan(T val, T maxValue)
{
return (val < maxValue);
}
template<typename IteratorType, typename T>
vector< T > less_than_10(IteratorType first, IteratorType last, bool (*fun)(T,T ), T maxValue)
{
vector< T > ivec;
for ( ; first != last; first++ )
{
if (fun(*first, maxValue))
{
ivec.push_back(*first);
}
}
return ivec;
}
int main(void)
{
vector< int > ivec;
vector< int > ivecres;
for ( int i = 0; i < 20; i++)
{
ivec.push_back(i);
}
ivecres = less_than_10<vector<int>::iterator, int>(ivec.begin(), ivec.end(), lessThan, 10);
for (int i = 0; i < ivecres.size(); i++)
{
cout << ivecres[i] << " ";
}
return 0;
}
然而,书本上提供了一种仿函数和配接器的能力,来完成这个泛型的算法:
当然,书上的方法更好:
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
using namespace std;
template<typename InputIterator, typename OutputIterator,
typename ElemType, typename Comp>
OutputIterator
filter(InputIterator first, InputIterator last,
OutputIterator at, const ElemType val, Comp pred)
{
while ((first = find_if(first, last, bind2nd(pred, val))) != last)
{
cout << "found value: " << *first << endl;
*at++ = *first++;
}
return at;
}
int main(void)
{
vector<int> ivec;
for (int i = 0; i < 20; i++)
{
ivec.push_back(i);
}
vector<int> ivec2;
filter(ivec.begin(), ivec.end(), back_inserter(ivec2), 10, less<int>());
for (int i = 0; i < ivec2.size(); i++)
{
cout << ivec2[i] << " ";
}
cout << endl;
return 0;
}
书上讲到输入输出流的时候,我就写了一个例子:
#include <iostream>
#include <iterator>
#include <string>
using namespace std;
int main(void)
{
copy(istream_iterator<string>(cin), istream_iterator<string>(), ostream_iterator<string>(cout, " "));
return 0;
}
我只能说,这个例子太美了。
第四章中如何实现一个class,第一个例子就是stack,编写如下:
stack.h
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Stack{
public:
bool push(const string);
bool pop(string &elem);
bool peek(string &elem);
bool empty();
bool full();
bool find(string elem);
int count(string elem);
int size(){
return _stack.size();
}
private:
vector<string> _stack;
};
stack.cpp
#include "Stack.h"
inline bool Stack::empty()
{
return _stack.empty();
}
inline bool Stack::full()
{
return _stack.size() == _stack.max_size();
}
bool Stack::push(const string elem)
{
if (full())
{
return false;
}
_stack.push_back(elem);
return true;
}
bool Stack::pop(string &elem)
{
if (empty())
{
return false;
}
elem = _stack.back();
_stack.pop_back();
return true;
}
bool Stack::peek(string &elem)
{
if (empty())
{
return false;
}
elem = _stack.back();
return true;
}
bool Stack::find(string elem)
{
return ::find(_stack.begin(), _stack.end(), elem) != _stack.end();
}
int Stack::count(string elem)
{
return ::count(_stack.begin(), _stack.end(), elem);
}
在进行类的设计的时候,有一点要注意就是:析构函数,赋值操作符重载,复制构造函数三者同存同亡,是个好的设计理念。
第四章里面设计了一个类,但是我怎么都是弄混了,于是自己写了这个类,当然和书上的不同,但是运行的结果是一样的:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Triangular{
public:
Triangular( int length = 1, int beg_pos = 1)
{
_length = length;
_beg_pos = beg_pos;
for (int i = beg_pos; i < beg_pos + length; i++)
{
sivec.push_back(i * (i + 1) / 2);
}
}
int beg_pos() const
{
return _beg_pos;
}
int length() const
{
return _length;
}
void show() const
{
for (int i = 0; i < sivec.size(); i++)
{
cout << sivec[i] << " ";
}
}
int sum() const
{
int sum = 0;
for (int i = 0; i < sivec.size(); i++)
{
sum += sivec[i];
}
return sum;
}
private:
int _length;
int _beg_pos;
vector<int> sivec;
};
ostream& operator<<(ostream &os, Triangular &rhs)
{
os << "( " << rhs.beg_pos() << " , " << rhs.length() << " ) ";
rhs.show();
return os;
}
int main(void)
{
Triangular tr(4);
cout << tr << "--sum of elements:" << tr.sum() << endl;
Triangular tr2(4, 3);
cout << tr2 << "--sum of elements:" << tr2.sum() << endl;
Triangular tr3(4, 8);
cout << tr3 << "--sum of elements:" << tr3.sum() << endl;
return 0;
}
在第四章的中间部分,有一个问题提出是如何设计iterator class,于是自己照着书上的方法写了一下,发现可以运行,就粘贴上来了。当然,代码的构架方面和书上的意义,只是编写方式不同而已:
triangular_iterator.h:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Triangular_iterator{
public:
Triangular_iterator(int index) : _index(index - 1){}
bool operator==(const Triangular_iterator&) const;
bool operator!=(const Triangular_iterator&) const;
int operator*() const;
Triangular_iterator& operator++();
Triangular_iterator operator++(int);
private:
void check_integrity() const;
int _index;
};
class Triangular{
friend Triangular_iterator;
public:
Triangular( int length = 1, int beg_pos = 1)
{
_length = length;
_beg_pos = beg_pos;
_elems.clear();
//这里进行了一次折中的运算。因为iterator要求_elems必须为static,
//但是static的性质导致_elems的值每次都在原基础上增加,所以进行clear操作
for (int i = beg_pos; i < beg_pos + length; i++)
{
_elems.push_back(i * (i + 1) / 2);
}
}
typedef Triangular_iterator iterator;
Triangular_iterator begin()
{
return Triangular_iterator(1); //这里进行了特殊的修改,为了符合我自己编写代码的习惯,符合_elems为static并且每次都变的情况。
}
Triangular_iterator end()
{
return Triangular_iterator(1 + _length);
}
int beg_pos() const
{
return _beg_pos;
}
int length() const
{
return _length;
}
static void show()
{
for (int i = 0; i < _elems.size(); i++)
{
cout << _elems[i] << " ";
}
}
static int sum()
{
int sum = 0;
for (int i = 0; i < _elems.size(); i++)
{
sum += _elems[i];
}
return sum;
}
static void gen_elements(int index)
{
for (int i = _elems.size(); i < index; i++)
{
_elems.push_back(i * (i + 1) / 2);
}
}
private:
int _length;
int _beg_pos;
static vector<int> _elems;
};
vector<int> Triangular::_elems;
ostream& operator<<(ostream &os, Triangular &rhs)
{
os << "( " << rhs.beg_pos() << " , " << rhs.length() << " ) ";
rhs.show();
return os;
}
inline bool Triangular_iterator::operator==(const Triangular_iterator &rhs) const
{
return _index == rhs._index;
}
inline bool Triangular_iterator::operator!=(const Triangular_iterator &rhs) const
{
return !(*this == rhs);
}
inline int Triangular_iterator::operator*() const
{
check_integrity();
return Triangular::_elems[_index];
}
inline void Triangular_iterator::check_integrity() const
{
if (_index >= Triangular::_elems.size())
{
Triangular::gen_elements(_index + 1);
}
}
inline Triangular_iterator& Triangular_iterator::operator++()
{
++_index;
check_integrity();
return *this;
}
inline Triangular_iterator Triangular_iterator::operator++(int)
{
Triangular_iterator tmp = *this;
++_index;
check_integrity();
return tmp;
}
main.cpp:
#include "Triangular_iterator.h"
int main(void)
{
Triangular tr(32);
cout << tr << "--sum of elements:" << tr.sum() << endl;
Triangular tr2(4, 3);
cout << tr2 << "--sum of elements:" << tr2.sum() << endl;
Triangular tr3(4, 8);
cout << tr3 << "--sum of elements:" << tr3.sum() << endl;
Triangular tr4(20, 12);
Triangular::iterator it = tr4.begin();
Triangular::iterator end_it = tr4.end();
cout << "triangular series of " << tr4.length() << " elements\n";
cout << tr4 << endl;
while (it != end_it)
{
cout << *it << " ";
++it;
}
cout << endl;
return 0;
}
关于仿函数:
#include <iostream>
#include <vector>
using namespace std;
class LessThan{
public:
LessThan( int val ) : _val(val){}
int comp_val() const {return _val;}
void comp_val( int nval ){ _val = nval;}
bool operator()( int value ) const
{
return value < _val;
}
private:
int _val;
};
int count_less_than( const vector<int> &vec, int comp )
{
LessThan lt(comp);
int count = 0;
for ( int ix = 0; ix < vec.size(); ix++ )
{
if ( lt( vec[ix] ) )
{
++count;
}
}
return count;
}
int main(void)
{
vector< int > ivec;
for ( int i = 0; i < 20; i++ )
{
ivec.push_back(i);
}
cout << count_less_than( ivec, 10 ) << endl;
return 0;
}
第五章面向对象编程风格中,刚开头举了一个图书馆的例子,代码如下:
#include <iostream>
#include <string>
using namespace std;
class LibMat{
public:
LibMat()
{
cout << "LibMat::Libmat() default constructor!\n";
}
virtual ~LibMat()
{
cout << "LibMat::~LibMat() default destructor!\n";
}
virtual void print() const
{
cout << "LibMat::print() -- I am a LibMat object!\n";
}
};
class Book : public LibMat{
public:
Book(const string &title, const string &author)
:_title(title), _author(author)
{
cout << "Book::Book( " << _title << " , "
<< _author << " ) constructor\n";
}
virtual ~Book()
{
cout << "Book::~Book() destructor!\n";
}
virtual void print() const
{
cout << "Book::print() -- I am a Book object!\n"
<< "My title is: " << _title << "\n"
<< "My author is: " << _author << endl;
}
const string &title() const
{
return _title;
}
const string &author() const
{
return _author;
}
protected:
string _title;
string _author;
};
class AudioBook : public Book{
public:
AudioBook( const string &title,
const string &author, const string &narrator)
:Book(title, author),
_narrator(narrator)
{
cout << "audiobook:audiobook( " << _title
<< " , " << _author
<< " ," << _narrator
<< " ) constructor\n";
}
~AudioBook()
{
cout << "audiobook::~audiobook() destructor!\n";
}
virtual void print() const
{
cout << "AudioBook::print() -- I am an AudioBook object!\n"
<< "My title is: " << _title << "\n"
<< "My author is: " << _author << "\n"
<< "My narrator is: " << _narrator << endl;
}
const string &narrator() const
{
return _narrator;
}
protected:
string _narrator;
};
void print(const LibMat &mat)
{
cout << "in global print(): about to print mat.print()\n";
mat.print();
}
int main(void)
{
AudioBook ab("随遇而安","孟非", "good");
print(ab);
return 0;
}
在进行类的继承和多态的问题上,书上讲了一个非常好的例子:
num_sequence.h:
#include <iostream>
using namespace std;
class num_sequence{
public:
virtual ~num_sequence(){}
virtual int elem(int pos) const = 0;
virtual const char* what_am_i() const = 0;
static int max_elems()
{
return _max_elems;
}
virtual ostream& print(ostream &os = cout) const = 0;
protected:
virtual void gen_elems(int pos) const = 0;
bool check_integrity(int pos, int size) const;
const static int _max_elems = 1024;
};
bool num_sequence::check_integrity(int pos, int size) const
{
if (pos <= 0 || pos > _max_elems)
{
cerr << "!! invalid position: " << pos
<< " cannot honor request\n";
return false;
}
if (pos > size)
gen_elems(pos);
return true;
}
ostream& operator<<(ostream &os, const num_sequence &ns)
{
return ns.print(os);
}
Fibonacci.h:
#include "num_sequence.h"
#include <iostream>
#include <vector>
using namespace std;
class Fibonacci : public num_sequence{
public:
Fibonacci(int len = 1, int beg_pos = 1)
:_length(len), _beg_pos(beg_pos){}
virtual int elem(int pos) const;
virtual const char* what_am_i() const { return "Fibonacci";}
virtual ostream& print(ostream &os = cout) const;
int length() const{return _length;}
int beg_pos() const {return _beg_pos;}
protected:
virtual void gen_elems(int pos) const;
int _length;
int _beg_pos;
static vector<int> _elems;
};
vector<int> Fibonacci::_elems;
int Fibonacci::elem(int pos) const
{
if (!check_integrity(pos, _elems.size()))
{
return 0;
}
if (pos > _elems.size())
Fibonacci::gen_elems(pos);
return _elems[pos - 1];
}
void Fibonacci::gen_elems(int pos) const
{
if (_elems.empty())
{
_elems.push_back(1);
_elems.push_back(1);
}
if (_elems.size() <= pos)
{
int ix = _elems.size();
int n_2 = _elems[ix - 2];
int n_1 = _elems[ix - 1];
for (; ix <= pos; ++ix)
{
int elem = n_2 + n_1;
_elems.push_back(elem);
n_2 = n_1;
n_1 = elem;
}
}
}
ostream& Fibonacci::print(ostream &os) const
{
int elem_pos = _beg_pos - 1; //之所以要减1,是因为索引是从0开始的
int end_pos = elem_pos + _length;
if (end_pos > _elems.size())
Fibonacci::gen_elems(end_pos);
while (elem_pos < end_pos)
{
os << _elems[elem_pos++] << " ";
}
return os;
}
main.cpp:
#include <iostream>
#include "Fibonacci.h"
using namespace std;
int main(void)
{
Fibonacci fib;
cout << fib << endl;
Fibonacci fib2(4);
cout << fib2 << endl;
Fibonacci fib3(8, 12);
cout << fib3 << endl;
return 0;
}
第六章的模板和第七章的异常不看了。还好吧,一步步来,不急。
接下去就慢慢的工作,然后看完《C++ Primer》,《the C++ programming language》和《C和指针》。
今年下半年不求什么,只要把这四本书看完就可以了。
顺便看50本的额外小说,加油。
工作就好好工作。