• 7、群体类和群体数据的组织-2.线性群体


    1、线性群体的概念

    线性群体中的元素次序与其位置关系是对应的。在线性群体中,又可按照访问元素的不同方法分为直接访问、顺序访问和索引访问。

     对可直接访问的线性群体,我们可以直接访问群体中的任何一个元素,而不必首先访问该元素之前的元素。

    对顺序访问的线性群体,只能按元素的排列顺序从头开始依次访问各个元素。

    还有两种特殊的线性群体--栈和队列。

    2、直接访问群体---数组类

    针对静态数组的缺陷,我们来设计一个动态数组类模板Array,它由任意多个位置连续的,类型相同的元素组成,其元素个数可在程序运行是改变。

    a、数组类

    数组类模板Aarray的声明和实现都在shuzu.h文件中,程序清单如下:

    #ifndef ARRAY_CLASS #define ARRAY_CLASS

    #include<iostream>

    #include<cstdlib>

    using namespace std;

    #ifndef NULL

    const int NULL=0;

    #endif    //NULL

    //错误类型集合,共有三种类型的错误:数组大小错误、内存分配错误和下标越界 e

    num ErrorType {  invalidArraySize,memoryAllocationError,indexOutOfRange };

    //错误信息

    char *errorMsg[] = {  "Invalid array size", "Memory allocation error", "Invalid index:" };

    //数组类模板声明

    template <class T>

    class Array {

    private:  T* alist; //T类型指针,用于存放动态分配的数组内存首地址

     int size;//数组大小  

    void Error(ErrorType error, int badIndex = 0)const;//错误处理函数

    public:  Array(int sz = 50);    //构造函数  

    Array(const Array<T>& A);//拷贝构造函数

     ~Array(void);//析构函数

     Array<T>& operator=(const Array<T>& rhs);//重载“=”使数组对象可以整体赋值  

    T& operator[](int i);//重载"[]",使Array对象可以起到C++普通数组的作用  

    operator T* (void)const;//重载T*,使Array对象可以起到C++普通数组的作用  

    int ListSize(void) const;//取数组的大小  

    void Resize(int sz);//修改数组的大小

    };

    //以下为类成员函数的定义

    //模板函数Error实现输出错误信息的功能

    template <class T>

    void Array<T>::Error(ErrorType error, int badIndex)const

    {  cout << errorMsg[error];//根据错误类型,输出相应的错误信息

     if (error == indexOutOfRange)   

    cout << badIndex;//如果是下标越界错误,输出错误的下标  

    cout << endl;  exit(1); }

    //构造函数

    template <class T> Array<T>::Array(int sz)

    {  if (sz <= 0)   //sz为数组大小  

     Error(invalidArraySize);  

    size = sz;

     alist = new T[size];//动态分配size个T类型的元素空间  

    if (alist == NULL)

    //如果分配内存不成功,输出错误信息  

     Error(memoryAllocationError); };

    //析构函数

    template <class T> Array<T>::~Array(void)

    {  delete[] alist; }

    //拷贝构造函数

    template <class T> Array<T>::Array(const Array<T>& X)

    {  //从对象X取得数组大小,并赋值给当前对象的成员

     int n = X.size;

     size = n;  //为对象申请内存并进行出错检查  

    alist = new T[n];//动态分配n个T类型的元素空间

     if (alist == NULL)//如果分配内存不成功,输出错误信息

     {   Error(memoryAllocationError);  }  //从对象X复制数组元素到本对象  

    T* srcptr = X.alist;//x.alist是对象X的数组首地址

     T* destptr = alist;//alist是本对象中的数组首地址

     while (n--)   *destptr++ = *srcptr++;

    } //重载"="运算符,将对象rhs赋值给本对象。实现对象的整体赋值

    template<class T> Array<T>& Array<T>::operator=(const Array<T>& rhs)

    {  int n = rhs.size;//取rhs的数组大小  //如果本对象中数组大小与rhs不同,则删除数组原有内存,然后重新分配

     if (size != n)

     {   delete[] alist;//删除数组原有内存  

     alist = new T[n];//重新分配n个元素的内存  

     if (alist == NULL)//如果分配内存不成功,输出错误信息   

     Error(memoryAllocationError);  

     size = n;//记录本对象的数组大小  

    }  

    //从rhs向本对象复制元素  

    T* destptr = alist;  

    T* srcptr = rhs.alist;

     while (n--)   

    *destptr++ = *srcptr++;

     return *this;//返回当前对象的引用

    }

    //重载下标运算符,实现与普通数组一样通过下标访问元素,并且具有越界检查功能

    template<class T> T& Array<T>::operator[](int n)

    {

     if (n<0 || n>size - 1)//检查下标是否越界   

    Error(indexOutOfRange,n);  

    return alist[n];//返回下标为n的数组元素

    }

    //重载指针转换运算符,将Array类的对象名转换为T类型的指针,指向当前对象中的私有数组,

    //因而可以像使用普通数组首地址一样使用Array类的对象名

    template <class T> Array<T>::operator T *(void) const

    {  return alist;//返回当前对象中私有数组的首地址 }

    //取当前数组的大小

    template<class T> int Array<T>::ListSize(void)const {  return size; }

    //将数组大小修改为sz

    template <class T> void Array<T>::Resize(int sz)

    {  if (sz <= 0)  //检查是否sz<=0   

    Error(invalidArraySize);

     if (sz == size)  //如果指定的大小与原有大小一样,什么也不做  

     return;  

    T* newlist = new T[sz];//申请新的数组内存  

    if (newlist == NULL) //测试申请内存是否申请成功   

    Error(memoryAllocationError);

     int n = (sz <= size) ? sz : size;//将sz与size中较小的一个赋值给n  //将原有数组中前n个元素复制到新数组中  

    T* srcptr = alist;//原数组alist的首地址  

    T* destptr = newlist;//新数组newlist的首地址  

    while (n--)  //复制数组元素  

    {   *destptr++ = *srcptr++;  }  

    delete[] alist;//删除原数组  

    alist = newlist;//使alist指向新数组  

    size = sz;//更新sz } #endif//ARRAY_CLASS

     zhishu.cpp

    #include<iostream>

    #include<iomanip>

    #include"shuzu.h"

    using namespace std;

    int main()

    {  

    Array<int> A(0);  //用来存放质数的数组,出师状态有10个元素

     int n;  

    int primecount = 0, i, j;

     cout << "Enter a value>=2 as upper limit for prime numbers:";  

    cin >> n;

     A[primecount++] = 2;//2是一个质数

     for (i = 3; i < n; i++)  {   

    //如果质数表满了,便再申请分配10个元素的空间  

     if (primecount == A.ListSize())  

     {    A.Resize(primecount + 10);   }   

    //大于2的偶数不是质数,因此略过本次循环的后继部分,进入下一次循环  

     if (i % 2 == 0)    

    continue;   

    //检查3,5,7,...,i/2是否i的因子  

     j = 3;  

     while (j <= i / 2 && i%j != 0)  

      j += 2;   //若上述参数均不为i的因子,则i为质数   

    if (j>i / 2)    

    A[primecount++] = i;  

    }  

    for (i = 0; i < primecount; i++)//输出质数

     {   

    cout << setw(5) << A[i];  

     if ((i + 1) % 10 == 0)//每输出10个数换行一次   

     cout << endl;  

    }  

    cout << endl;

     getchar();  

    getchar();

    }

  • 相关阅读:
    自己动手编写一个网络图片爬虫
    使用maven构建项目的注意事项
    maven 构建一个web项目
    构建简单的Maven工程,使用测试驱动的方式开发项目
    像Maven一样构建java项目的目录,更好的管理java工程的源码
    Tomcat源码导入eclipse的步骤
    [HNOI2012] 矿场搭建
    UVA10641 Barisal Stadium 照亮体育馆
    CSP-J/S(NOIP PJ/TG) 游记
    [BalticOI 2011 Day1] Switch the Lamp On
  • 原文地址:https://www.cnblogs.com/gary-guo/p/6286493.html
Copyright © 2020-2023  润新知