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();
}
来源:https://www.cnblogs.com/gary-guo/p/6286493.html