C++题目练习10

C++题目练习10

10.1 模板练习:数组最大值

设计一个函数模板,实现从int、long long、char、double、string类型的数组找出最大值元素。
提示:可用类型参数传递数组、用非类型参数传递数组大小。

#include <iostream>
#include <string>
using namespace std;

template<typename T>

T findMax(T *a, int n) {
	T max;
	max = a[0];
  
	for (int i = 1; i < n; i++) {
		if (max < a[i])
			max = a[i];
	}
	return max;
}


int main() {
	int n;
	cin >> n;
	int *a = new int[n];
	for ( int i = 0; i < n; i++ )
		cin >> a[i] ;
	cout << "1 " << findMax( a, n ) << endl;
	delete[] a;

	cin >> n;
	string *b = new string[n];
	for ( int i = 0; i < n; i++ )
		cin >> b[i] ;
	cout << "2 " << findMax( b, n ) << endl;
	delete[] b;

	cin >> n;
	long long *c = new long long[n];
	for ( int i = 0; i < n; i++ )
		cin >> c[i] ;
	cout << "3 " << findMax( c, n ) << endl;
	delete[] c;

	cin >> n;
	double *d = new double[n];
	for ( int i = 0; i < n; i++ )
		cin >> d[i] ;
	cout << "4 " << findMax( d, n ) << endl;
	delete[] d;

	return 0;
}


10.2 设计模板类 MyStack

请按要求实现一个 MyStack 类模板,要求实现数据的封装和各种常用操作。
约定:

  1. 数据成员为私有属性,包括:
  • data :一个指针,指向存放栈元素的空间,栈元素类型为 T
  • tt : 指示栈顶位置
  • siz : 当前栈空间的大小
  1. 成员函数为公有属性,包括:
  • 默认构造函数,完成初始化动作,栈空间的默认大小是 100 。
  • 带一个参数 s 的构造函数,s 表示栈空间的初始大小。
  • 析构函数:负责释放动态申请的内存。
  • 拷贝构造函数,实现深拷贝。
  • top( &v ),函数返回如果为真,参数 v 带回栈顶元素的值;函数返回如果为假,参数 v 的值没有变化。
  • pop(),如果栈不空,弹走栈顶元素;如果栈空,没有动作。
  • push( v ),如果栈已满,没有动作;如果栈未满,参数 v 的值进栈。
  • size(),返回当前栈内元素个数,如果栈空,返回 0 。
  • 重载 流插入运算符 << :如果栈不空,自栈底到栈顶,输出栈内元素,每个元素后跟一个空格;如果栈空,没有输出。
  • 重载 赋值运算符 = :将一个栈对象赋值给另一个栈对象,要实现深拷贝
  • 重载 等于比较运算符 == : a 和 b 两个栈对象,当栈 a 的元素 与 栈 b 的元素个数相同且所有对应位置的元素相等时,表达式 a == b 为真

请实现上述功能。
完成 MyStack类 的 数据成员 以及 各成员函数 的实现。

#include<cstdio>
#include <iostream>
using namespace std;

template<typename T>
class MyStack {
   public:
    // 无参默认构造函数
    MyStack();

    // 带一个参数 int s 的构造函数
    MyStack( unsigned s );

    // 拷贝构造函数
    MyStack( const MyStack &b );

    // 析构函数
    ~MyStack();

    // 读取栈顶元素的值,赋值给 v
    bool top( T& v );

    // 弹出栈顶元素
    void pop();

    // 压v进栈
    bool push( const T& v );

    // 当前栈内元素个数
    unsigned size();

    // 重载 流插入运算符 <<
    friend ostream & operator<< ( ostream &out, const MyStack& a ) {
        if(a.data == nullptr || a.tt == -1)
		  return out;
		for(int i = 0;i<a.tt+1;i++)
		 out<< a.data[i] <<" ";
         out<<endl;
		return out; 
    }

    // 重载 赋值运算符 =
    MyStack & operator = ( const MyStack& b );

    // 等于 比较运算符 ==
    bool operator == ( const MyStack& b );

private:
    T *data;
    int tt;
    unsigned siz;
};

template<typename T>
MyStack<T>::MyStack()
{
	siz=100;
	data=new T[siz];
	tt=-1;
}

template<typename T>
MyStack<T>::MyStack(unsigned s)
{
	siz = s;
	data = new T[siz];
	tt=-1;
}

template<typename T>
MyStack<T>::MyStack(const MyStack &b)
{
	data  = new T[b.siz];
	siz = b.siz;
	for(int i =0;i<b.tt+1;i++)
	{
		data[i] = b.data[i];
	}
	tt = b.tt;
}
template<typename T>
MyStack<T>::~MyStack()
{
	if(data != nullptr)
	  delete[]data;
}

template<typename T>
bool MyStack<T>::top(T &v)
{
	if(tt == -1)
	 return false;
	v = data[tt];
	return true;
}

template<typename T>
void MyStack<T>::pop()
{
	if(tt == -1)
	{
		return;
	}
	tt--;
}

template<typename T>
bool MyStack<T>::push(const T &v)
{
	if(tt==siz-1)
	 return false;
	tt++;
	data[tt] = v;
	return true;
}

template<typename T>
unsigned MyStack<T>::size()
{
	return tt+1;
}

template<typename T>
MyStack<T> &MyStack<T>::operator=(const MyStack &b)
{
	if(this == &b)
	{
		return *this;
	}
	if(data!=nullptr)
	{
		delete[]data;
	}
	data = new T[b.siz];
	siz = b.siz;
	for(int i=0;i<b.tt+1;i++)
	{
		data[i] = b.data[i];
	}
	tt = b.tt;
	return *this;
 } 
 template<typename T>
 bool MyStack<T>::operator==(const MyStack &b)
 {
 	if(this == &b)
 	 return true;
 	if(tt != b.tt)
 	 return false;
 	for(int i=0;i<tt+1;i++)
 	{
 		if(data[i]!=b.data[i])
 		 return false;
	 }
	 return true;
  } 
int main() {

    int si;
    cin >> si;
    MyStack<int> s1( si );  // 创建一个栈空间大小为 si 的栈 s1

    int command;
    int c, v;

    cin >> command;  // 读入命令个数
    while( command -- ) {
        cin >> c;  // 读入一条命令
        switch( c ) {
        case 1:  // 进栈
            cin >> v;
            s1.push( v );
            break;
        case 2:  // 出栈
            s1.pop();
            break;
        case 3:  // 读取栈顶元素
            if( s1.top( v ) )  // 如果返回为真,说明成功读取栈顶元素
                cout << v << endl;  // 输出之
            break;
        case 4:  // 栈内元素的个数
            cout << s1.size() << endl;
            break;
        case 5:  // 利用重载的 流插入运算符 输出 栈s1
            cout << s1; // 笔记:换行符要放在 operator<<运算符重载函数里面输出,否则会造成PE
            break;
        }
    }

    MyStack<int> s2( s1 );  // 利用拷贝构造函数创建一个新对象 s2
    cin >> command;
    while( command -- ) {
        cin >> c;
        switch( c ) {
        case 1:  // 进栈
            cin >> v;
            s2.push( v );
            break;
        case 2:  // 出栈
            s2.pop();
            break;
        case 3:  // 读取栈顶元素
            if( s2.top( v ) )  // 如果返回为真,说明成功读取栈顶元素
                cout << v << endl;  // 输出之
            break;
        case 4:  // 栈内元素的个数
            cout << s2.size() << endl;
            break;
        case 5:  // 利用重载的 流插入运算符 输出 栈s2
            cout << s2;
            break;
        }
    }

    if( s1 == s2 )  // 利用重载的 等于比较运算符 判断 s1 == s2 是否为真
        cout << "yes" << endl;
    else
        cout << "no" << endl;

    MyStack<int> s3;  // 调用默认构造函数创建一个新对象 s3
    s3 = s1;  // 赋值运算符

    if( s3 == s1 )  // 利用重载的 等于比较运算符 判断 s3 == s1 是否为真
        cout << "yes" << endl;
    else
        cout << "no" << endl;

    cin >> command;
    while( command -- ) {
        cin >> c;
        switch( c ) {
        case 1:  // 进栈
            cin >> v;
            s3.push( v );
            break;
        case 2:  // 出栈
            s3.pop();
            break;
        case 3:  // 读取栈顶元素
            if( s3.top( v ) )  // 如果返回为真,说明成功读取栈顶元素
                cout << v << endl;  // 输出之
            break;
        case 4:  // 栈内元素的个数
            cout << s3.size() << endl;
            break;
        case 5:  // 利用重载的 流插入运算符 输出 栈s3
            cout << s3;
            break;
        }
    }

    return 0;
}

10.3 模版类Array

请实现一个模版类 Array ,实现可以直接访问的线性群体,包括:私有数据成员:

  • T* list;    /// 用于存放动态分配的数组内存首地址
  • int siz;    /// 数组大小。为了避免与 size 同名而高亮显示,特意减少一个字符

成员函数:

  • 构造函数 : Array( int sz = 10 )
  • 拷贝构造函数 : Array( const Array<T> &a )
  • 析构函数 : ~Array()
  • 重载赋值运算符 operator = : operator = ( const Array<T> &rhs )
  • 重载 下标运算符[] ,用于 左值: operator [] ( int i )
  • 重载 下标运算符[] 常函数,用于 右值 : operator [] ( int i ) const
  • 重载到 T* 类型的转换 :operator T * ()
  • 取数组的大小 : getSize()
  • 修改数组的大小 : resize( int sz )
#include <iostream>
#include <cassert>
#include <iomanip>
using namespace std;

template<class T>
class Array
{
	private:
		T *list;
		int siz;
	public:
		Array(int sz = 10)
		{
			siz = sz;
			list = new T[siz];
		}
		Array(const Array<T>&a)
		{
			siz = a.siz;
			list = new T[siz];
			for(int i = 0;i<siz;i++)
			{
				list[i] = a.list[i];
			}
		}
		~Array()
		{
			delete[] list;
			
		}
		Array<T>& operator = (const Array<T> &rhs)
		{
			if(this != &rhs)
			{
				delete[] list;
				siz = rhs.siz;
				list = new T[siz];
				for(int i = 0;i<siz;i++)
				{
					list[i] = rhs.list[i];
				}
			}
			return *this;
		}
		T& operator[](int i)
		{
			assert(i>=0 && i<siz);
			return list[i];
		}
		const T& operator[](int i) const {
        assert(i >= 0 && i < siz);
        return list[i];
    }

    operator T*() {
        return list;
    }

    int getSize(){
        return siz;
    }

    void resize(int sz) {
        T* newList = new T[sz];
        for (int i = 0; i < min(siz, sz); i++) {
            newList[i] = list[i];
        }
        delete[] list;
        list = newList;
        siz = sz;
    }
};

/// read() 用于验证 重载的指针转换运算符
void read( double *p, int n ) {
    for ( int i = 0; i < n; i++ )
        cin >> p[i];
}

int main() {
    int n;
    cin >> n;
    
    Array<double> da(n);    /// 创建一个 double类型元素 的 对象da
    read( da, n );
    
    /// 输出 Array类的 对象da 全部元素
    for ( int i = 0; i < da.getSize(); i++ )
        cout << da[i] << ' ';
    cout << endl;
    
    Array<int> prime(5);    /// 创建一个 int类型元素 的 对象prime
    /// 求 [2, n] 的全部素数,存放到 prime 中

    int cnt = 0; /// 统计当前找到的素数的个数
    cin >> n;  /// 读入范围

    for ( int i = 2; i <= n; i ++ ) {   /// 检查 i 是否能被比它小的素数整除
        bool isPrime = true;
        for ( int j = 0; j < cnt; j ++ )
            /// 若 i 被 prime[j] 整除,说明 i 不是质数
            if ( i % prime[j] == 0 ) {
                isPrime = false;
                break;
            }

        if ( isPrime ) {
            if ( cnt == prime.getSize() )   /// 当装满了
                prime.resize( cnt * 2 );    /// 空间扩大一倍
            prime[ cnt ++ ] = i;
        }
    }
    
    for ( int i = 0; i < cnt; i ++ )
        cout << setw(8) << prime[i];
    cout << endl;
    
    return 0;
}


 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值