250 likes | 576 Views
程序设计实习 作业解答(下). 2011-5. 作业八 : 自己编写排序函数 自己编写一个能对任何类型的数组进行排序的 mysort 函数,用法和 qsort 类似,使得下面程序能够将数组 an 元素按个位数从小到大排序
E N D
程序设计实习作业解答(下) 2011-5
作业八:自己编写排序函数自己编写一个能对任何类型的数组进行排序的mysort函数,用法和qsort类似,使得下面程序能够将数组an元素按个位数从小到大排序作业八:自己编写排序函数自己编写一个能对任何类型的数组进行排序的mysort函数,用法和qsort类似,使得下面程序能够将数组an元素按个位数从小到大排序 #include <iostream>#include <stdlib.h>using namespace std;int MyCompare( const void * elem1, const void * elem2 ) { unsigned int * p1, * p2; p1 = (unsigned int *) elem1; p2 = (unsigned int *) elem2; return (* p1 % 10) - (* p2 % 10 ); }#define NUM 5int main(){ unsigned int an[NUM] = { 8,123,11,10,4 }; mysort( an,NUM,sizeof(unsigned int), MyCompare); for( int i = 0;i < NUM; i ++ ) printf("%d ",an[i]); return 0;}
void mysort(void * a, int num,int size, int (* pfun)( const void *, const void * )) { char * p = (char*) a; for( int i = 0;i < num - 1;i ++ ) for( int j = i + 1; j < num ; j ++ ) if( pfun( p + i * size, p + j * size ) > 0 ) { char c; for( int k = 0; k < size; k ++ ) { c = p[ i * size+k]; p[ i * size+k] = p[ j*size+k]; p[ j*size+k] = c; } } }
或者: typedef int ( * PCOMPAREFUN )( const void *, const void * ) ; void mysort(void * a, int num,int size, PCOMPAREFUN pfun) { char * p = (char*) a; for( int i = 0;i < num - 1;i ++ ) for( int j = i + 1; j < num ; j ++ ) if( pfun( p + i * size, p + j * size ) > 0 ) { char c; for( int k = 0; k < size; k ++ ) { c = p[i * size+k]; p[i * size+k] = p[j*size+k]; p[j*size+k] = c; } } }
模板作业— 作业九 1. CLinkList是一个带表头节点的单链表的类模板。带表头节点的单链表的特点是:当链表为空时,表中仍有一个节点,即表头节点。请完整写出CLinkList类模板中列出的AppendNode 和PrintList成员函数,使得下面程序的输出结果是: 0,1,2,3, 0,1,2,3,9,10,11, 注意: 1)不得调用任何库函数,库模板,不得使用static关键字,不得使用除NULL 以外的任何常量 2)不得为Node和CLinkList模板添加任何成员 3)不得添加任何全局变量,不得添加其他函数
template<class D> CLinkList<D>::CLinkList() { pHead = new Node<D>; pHead->next = NULL; }; int main() { CLinkList<int> l; for( int i = 0;i < 4;i ++) l.AppendNode(i); l.PrintList(); cout << endl; for( i = 9;i < 12;i ++) l.AppendNode(i); l.PrintList(); } #include <iostream.h> template <class D> class Node { public: D data; Node * next; }; template<class D> class CLinkList { private: Node<D> * pHead; public: CLinkList(); void AppendNode( D data); void PrintList(); };
Answer template<class D> void CLinkList<D>::AppendNode( D data) { Node<D> * p = pHead; while( p->next ) p = p->next; p->next = new Node<D>; p = p->next; p->data = data; p->next = NULL; } template<class D> void CLinkList<D>::PrintList() { Node<D> * p = pHead; while( p->next ) { cout << p->next->data << ","; p = p->next; } }
2 填空使程序能编译通过,并写出运行的输出结果 #include <iostream.h> template <___class T__> //(a) class myclass { T i; public: myclass (T a) { i = a; } void show( ) { cout << i << endl; } }; int main() { myclass<__char *_> obj("This"); //(b) obj.show(); } 该程序输出结果为:_____This______ //(c) 模板作业— 作业九
3 下面的程序输出是: TomHanks 请填空。注意,不允许使用任何常量。 #include <iostream> #include <string> using namespace std; template <class T> class myclass { __T * p___; int nSize; public: myclass ( ___T * a_____, int n) { p = new T[n]; for( int i = 0;i < n;i ++ ) p[i] = a[i]; nSize = n; } 模板作业— 作业九 ~myclass( ) { delete [] p; } void Show() { for( int i = 0;i < nSize;i ++ ) { cout << p[i]; } } }; int main() { char * szName = "TomHanks"; myclass<char > obj(____szName,strlen(szName)___); obj.Show(); }
作业十 • 写一个自己的 CMyostream_iterator 模板,使之能和 ostream_iterator 模板达到一样的效果 • Answer: • template <class T> • class CMyostream_iterator{ • private: • ostream & o; • const char * s; • public: • CMyostream_iterator( ostream & output, const char * sz):o(output),s(sz){ } • void operator++() { }; • void operator=(const T & val ){ • o << val << s; • } • CMyostream_iterator & operator * ( ) { • return * this; • } • };
copy 的源代码: template<class _II, class _OI> inline _OI copy(_II _F, _II _L, _OI _X) { for (; _F != _L; ++_X, ++_F) *_X = *_F; return (_X); } 要支持copy函数必须重载三个运算符:*,=,++ vs 2008(2010) 上面copy 的源比较复杂,不是上面的样子,所以此题在vs2008(2010)上的做法不要求
vs2008解法: template <class T,class T2> class CMyostream_iterator :public iterator<T2,T>{ private: ostream & o; const char * s; public: CMyostream_iterator( ostream & output, const char * sz):o(output),s(sz){ } void operator++() { }; void operator=(const T & val ){ o << val << s; } CMyostream_iterator & operator * ( ) { return * this; } };
int main() { int a[5] = {1,2,3,4,5}; char b[6]; CMyostream_iterator<int,int> output(cout,"*"); vector<int> v(a,a+5); copy(v.begin(),v.end(),output); }
1 看程序写结果 #include <vector> #include <iostream> using namespace std; class A { private : int nId; public: A(int n) { nId = n; cout << nId << " contructor" << endl; }; A( const A & a ) { nId = a.nId ; cout << nId << " copy constructor" << endl; } ~A( ) { cout << nId << " destructor" << endl; } }; int main() { vector<A*> vp; vp.push_back(new A(1)); vp.push_back(new A(2)); vector<A> v; v.push_back (3); } STL— 作业十一 1 contructor 2 contructor 3 contructor 3 copy constructor 3 destructor 3 destructor
2下面的程序输出结果为: Tom,Jack,Mary,John, 请填空 程序: template <_______ , _______> class MyClass { T array[T2]; public: MyClass( T * begin ) { copy( begin, begin + T2, array); } STL— 作业十一 void List() { T * i; for( i = array; i != array + T2;i ++) cout << * i << "," ; } }; int main() { string array[4] = { "Tom","Jack","Mary","John"}; _____________________ ; obj.List(); } class T,int T2 MyClass<string,4> obj(array)
3下面的程序输出结果为: 1 2 6 7 8 9 请填空 int main() { int a[] = {8,7,8,9,6,2,1}; ___________________; for( int i = 0;i < 7;i ++ ) ___________________; ostream_iterator<int> o(cout," "); copy( v.begin(),v.end(),o); } STL— 作业十一 set<int >v v.insert(a[i])
4下面的程序输出结果为: Tom,Jack,Mary,John, 请填空 程序: #include <vector> #include <iostream> #include <string> using namespace std; template <class T> class MyClass { vector<T> array; public: MyClass ( T * begin,int n ):array(n) { copy( begin, begin + n, array.begin()); } STL— 作业十一 void List() { ________________________; for( i = array.begin(); i != array.end();i ++) cout << * i << "," ; } }; int main() { string array[4] = { "Tom","Jack","Mary","John"}; _________________________; obj.List(); } vector<T>::iterator i; MyClass<string> obj( array,4);
5下面的程序输出结果为: A::Print: 1 B::Print: 2 B::Print: 3 请填空 程序: template <class T> void PrintAll( const T & c ) { T::const_iterator i; for( i = c.begin(); i != c.end(); i ++ ) _______________________; }; STL— 作业十一 class A { protected: int nVal; public: A(int i):nVal(i) { } virtual void Print() { cout << "A::Print: " << nVal << endl; } }; class B:public A { public: B(int i):A(i) { } void Print() { cout << "B::Print: " << nVal << endl; } }; int main() { __________________; v.push_back( new A(1)); v.push_back (new B(2)); v.push_back (new B(3)); PrintAll( v); } (*i)->Print() vector<A*> v
1下面的程序输出结果为: 5*3*4*2*1* 1*2*3*4*5* 1*2*9*4*5* 请填空 using namespace std; template <class T> class MyClass:public list<T>{ public: ____________________ (int n) { iterator i; int k = 0; for( ___________________) { if( k == n) return _______________; k ++; } } STL— 作业十一 T& operator[] i=begin();i != end(); i ++ * i list<T>(n) MyClass(int n):___________________ { } }; int main() { MyClass<int> obj(5); int a[] = { 5, 3, 4, 2,1 }; copy( a, a + 5, obj.begin()); ostream_iterator<int> output(cout,"*"); copy( obj.begin(),obj.end(),output); cout << endl; obj.sort(); copy( obj.begin(),obj.end(),output); cout << endl; obj[2] = 9; copy( obj.begin(),obj.end(),output); }
标准矩形问题 • 其边平行于坐标轴 • 给定不重复的 n 个整点(横、纵坐标都是整数的点),求从这n个点中任取4点作为顶点所构成的四边形中,有多少个是标准矩形。 输入数据: 第一行是点的数目 其后每一行都代表一个点,由两个整数表示,第一个是x坐标,第二个是y坐标 输出要求: 输出标准矩形的数目
struct Point { int x; int y; Point( int x_,int y_):x(x_),y(y_) { } }; bool operator < ( const Point & p1, const Point & p2) { if( p1.y < p2.y ) return true; else if( p1.y == p2.y ) return p1.x < p2.x; else return false; } int main() { int t; int x,y; cin >> t; vector<Point> v; while( t -- ) { cin >> x >> y; v.push_back(Point(x,y)); } _____________________; vector<Point>::iterator i,j; int nTotalNum = 0; sort(v.begin(),v.end())
for( i = v.begin(); i < v.end() - 1;i ++ ) for(___________; ___________; _________) { if(binary_search( v.begin(),v.end(), Point( j->x, i->y)) && ___________________________________________ && ____________________________________________ && ______________________________________________ ) nTotalNum ++; } cout << _________________; }; j = i + 1 j < v.end() j ++ binary_search( v.begin(),v.end(),Point( i->x, j->y)) i->x != j->x i->y != j->y nTotalNum / 2
MyMax模板的作用与求数组或向量中的最大元素有关,而且下面程序的输出结果是:MyMax模板的作用与求数组或向量中的最大元素有关,而且下面程序的输出结果是: 5 136 请补出马克斯删掉的那部分代码。 • *MyMax模板 • 不准使用除 true 和 false 以外的任何常量,并且不得假设 true的值是1或任何值 • 不得使用任何库函数或库模板(包括容器和算法) • 不得使用 static 关键字 。 • 提示:copy函数模板的第三个参数是传值的 template <class T> class MyMax { public: T * pMax; //指向用于存放最大值的变量 bool bFirst; //记录最大值时会用到的标记 MyMax (T * p):bFirst(true),pMax(p) { }; //开头 //…… //结尾 };
class A { public: int i; A( int n) :i(n) { }; A() { }; }; bool operator < ( const A & a1, const A & a2) { return a1.i < a2.i ; } ostream & operator<< ( ostream & o, const A & a) { o << a.i; return o; } int main() { A a[5] = {A(1),A(5),A(3),A(4),A(2)}; int b[9] = {1,5,30,40,2,136,80,20,6}; int nMax; A aMax; MyMax<A> outputa( & aMax); copy(a,a+5,outputa); cout << outputa() << endl; MyMax<int> output( & nMax); copy(b,b+9,output); cout << output() << endl; }
//需要实现支持copy函数的三个运算符重载,以及()算符//需要实现支持copy函数的三个运算符重载,以及()算符 MyMax & operator * () { return * this; } void operator ++( ) {} void operator = ( T & obj) { if( bFirst) { * pMax = obj; bFirst = false; } else { if( * pMax < obj ) * pMax = obj; } } T operator() () { return * pMax; } 上面是dev中的解法,vs2008的解法,参见前面的 Cmyostream_iterator 作业