chapter 2_arrays

chapter 2_arrays



一、多项式抽象数据类型

1、多项式的ADT定义

class Polynomial
{
private:
    int degree;                 //degree<=MaxDegree
    float coef[MaxDegree+1];    //系数数组
public:
    Polynomial();                       //构造函数
    float Eval(float x);                //计算多项式数值
    Polynomial Add(Polynomial ploy);    //多项式加法
    Polynomial Mult(Polynomial poly);   //多项式乘法
};

若degree<<MaxDegree,coef[ ]的大多位置不会被占用,可以做出如下改进

class Polynomial
{
private:
    int degree;     //degree<=MaxDegree
    float *coef; 	//系数数组
	...
};

若为稀疏多项式,则仅存储非零项,可以做出如下改进

class Term				//数组元素
{
    friend Polynomial;
private:
    float coef;			//系数
    int exp;			//指数
    ...
}
class Polynomial		//数组
{
    Term* termArray;    //非零项数组
    int terms;          //非零项数
    int capacity;       //最大容量
    ...
};

2、计算多项式数值

float Polynomial::Eval(float x)
{
    int temp=0;
    for(int i=0;i<this->terms;i++)
    {
        temp+=this->termArray[i].coef*pow(x,this->termArray[i].exp);
    }
    return temp;
}

3、多项式加法

void Polynomial::TailInsertTerm(float coef,int exp) //尾插节点
{
    if(this->terms==this->capacity){   //及时扩容
        this->capacity*=2;
        Term* tempTerm=new Term[this->capacity];
        for(int i=0;i<this->terms;i++)tempTerm[i]=this->termArray[i];
        delete[]this->termArray;                                    
        this->termArray=tempTerm;          
    }    
    this->termArray[terms].exp=exp;
    this->termArray[terms++].coef=coef;
}
Polynomial Polynomial::Add(Polynomial poly)
{
    Polynomial tempPoly;
    int aPos=0,bPos=0;                          //记录this->terms与poly的下标
    while(aPos<this->terms&&bPos<poly.terms)
    {
        if(this->termArray[aPos].exp==poly.termArray[bPos].exp){
            if(this->termArray[aPos].coef+poly.termArray[bPos].coef!=0)     //指数相同且系数和非0   
                tempPoly.TailInsertTerm(this->termArray[aPos].coef+poly.termArray[bPos].coef,this->termArray[aPos].exp);
            aPos++,bPos++;
        }
        else if(this->termArray[aPos].exp<poly.termArray[bPos].exp)         //存入指数更小的系数
            tempPoly.TailInsertTerm(this->termArray[aPos].coef,this->termArray[aPos].exp),aPos++;
        else
            tempPoly.TailInsertTerm(poly.termArray[bPos].coef,poly.termArray[bPos].exp),bPos++;
    }
    while(aPos<this->terms&&tempPoly.terms<=tempPoly.capacity)              //拷贝数组剩余元素
    {
        tempPoly.TailInsertTerm(this->termArray[aPos].coef,this->termArray[aPos].exp),aPos++;
    }
    while(bPos<poly.terms&&tempPoly.terms<=tempPoly.capacity)               //拷贝数组剩余元素
    {
        tempPoly.TailInsertTerm(poly.termArray[bPos].coef,poly.termArray[bPos].exp),bPos++;
    }
    return tempPoly;
}

4、多项式乘法

void Polynomial::InsertTerm(float coef,int exp)     //插入节点
{
    if(this->terms==this->capacity){   				//及时扩容
        this->capacity*=2;
        Term* tempTerm=new Term[this->capacity];
        for(int i=0;i<this->terms;i++){
            tempTerm[i]=this->termArray[i];
        }
        delete[]this->termArray;                                    
        this->termArray=tempTerm;          
    }  
    int idx=this->terms;                            //标记插入节点位置
    for(int i=0;i<this->terms-1;i++){
        if(this->termArray[i].exp==exp){
            idx=i;break;
        }
        if(this->termArray[i].exp<exp&&this->termArray[i+1].exp>exp){
            idx=i+1;break;
        }
    }
    if(this->termArray[0].exp>=exp)idx=0;
    if(this->termArray[terms-1].exp==exp)idx=terms-1;
    if(this->termArray[idx].exp==exp){               //查找到指数相同节点
        this->termArray[idx].coef+=coef;
        if(this->termArray[idx].coef==0){            //若系数和为零
            for(int i=idx;i<this->terms-1;i++)this->termArray[i]=this->termArray[i+1];
            this->terms--;
        }
    }
    else{                                            //未查找到指数相同节点
        for(int i=this->terms;i>idx;i--){
            this->termArray[i]=this->termArray[i-1];
        }
        this->termArray[idx].exp=exp;
        this->termArray[idx].coef=coef;
        this->terms++;
    }
}
Polynomial Polynomial::Mult(Polynomial poly)
{
    Polynomial tempPoly;
    int coef=0,exp=0;
    for(int i=0;i<this->terms;i++){
        for(int j=0;j<poly.terms;j++){
            coef=this->termArray[i].coef*poly.termArray[j].coef;
            exp=this->termArray[i].exp+poly.termArray[j].exp;
            tempPoly.InsertTerm(coef,exp);
        }
    }
    return tempPoly;
}

二、稀疏矩阵

1、稀疏矩阵的ADT定义

class MatrixTerm			//稀疏矩阵元素
{
    friend SparseMatrix;
private:
    int row;    			//行
    int col;    			//列
    int value;  			//元素数值
};
class SparseMatrix			//稀疏矩阵
{
private:
    MatrixTerm* termArray;  //非零项数组
    int rows;               //总行数
    int cols;               //总列数
    int terms;              //非零项数
    int capacity;           //最大容量
public:
    SparseMatrix(int r,int c,int t);    //创建一个有r行c列,可以容纳t个非0项的SparseMatrix
    SparseMatrix Transpose();           //矩阵转置
    SparseMatrix Add(SparseMatrix matrix);   //矩阵加法
    SparseMatrix Mult(SparseMatrix matrix);  //矩阵乘法
};

2、矩阵转置

SparseMatrix SparseMatrix::Transpose()
{
    SparseMatrix temp=SparseMatrix(this->cols,this->rows,this->terms);
    if(this->terms)    {
        int counter=0;
        for(int i=0;i<this->cols;i++){
            for(int j=0;j<this->terms;j++){
                if(this->termArray[j].col==i){
                    temp.termArray[counter].row=i;
                    temp.termArray[counter].col=this->termArray[j].row;
                    temp.termArray[counter++].value=this->termArray[j].value;
                }
            }
        }
    }
    return temp;
}

在terms达到rowscols的数量级时,Transpose的运行时间达到O(rowcol^2),用时过长,以下给出快速转置的方法

SparseMatrix SparseMatrix::FastTranspose()
{
    SparseMatrix temp=SparseMatrix(this->cols,this->rows,this->terms);
    if(terms>0){
        int* rowStart=new int[this->cols]{};
        int* rowSize=new int[this->cols]{};
        for(int i=0;i<this->terms;i++)rowSize[this->termArray[i].col]++;
        for(int i=1;i<this->cols;i++)rowStart[i]=rowStart[i-1]+rowSize[i-1];
        for(int i=0;i<this->terms;i++){
            temp.termArray[rowStart[this->termArray[i].col]++]=this->termArray[i];
            swap(temp.termArray[rowStart[this->termArray[i].col]-1].col,temp.termArray[rowStart[this->termArray[i].col]-1].row);
        }
        delete[]rowSize;
        delete[]rowStart;
    }
    return temp;
}

3、矩阵加法

void SparseMatrix::TailInsertTerm(int row,int col,int value)
{
    if (this->terms == this->capacity)
    {
        this->capacity *= 2;
        MatrixTerm* tempTerm = new MatrixTerm[this->capacity];
        for (int i = 0; i < this->terms; i++) {
        tempTerm[i] = this->termArray[i];
        }
        delete[]this->termArray;
        this->termArray = tempTerm;
    }
    this->termArray[terms].row=row;
    this->termArray[terms].col=col;
    this->termArray[terms].value=value;
    this->terms++;
}

SparseMatrix SparseMatrix::Add(SparseMatrix matrix)
{
    if(this->rows!=matrix.rows||this->cols!=matrix.cols){
        throw"Incompatible matrices";
    }
    SparseMatrix tempSparseMatrix{this->rows,matrix.cols,0};
    int apos=0,bpos=0;
    while(apos<this->terms&&bpos<matrix.terms)
    {
        if(this->termArray[apos].row<matrix.termArray[bpos].row){
            tempSparseMatrix.InsertTerm(this->termArray[apos].row,this->termArray[apos].col,this->termArray[apos].value);apos++;
        }
        else if(this->termArray[apos].row>matrix.termArray[bpos].row){
            tempSparseMatrix.InsertTerm(matrix.termArray[bpos].row,matrix.termArray[bpos].col,matrix.termArray[bpos].value);bpos++;
        }
        else if(this->termArray[apos].col<matrix.termArray[bpos].col){
            tempSparseMatrix.InsertTerm(this->termArray[apos].row,this->termArray[apos].col,this->termArray[apos].value);apos++;
        }
        else if(this->termArray[apos].col>matrix.termArray[bpos].col){
            tempSparseMatrix.InsertTerm(matrix.termArray[bpos].row,matrix.termArray[bpos].col,matrix.termArray[bpos].value);bpos++;
        }
        else{
            tempSparseMatrix.InsertTerm(matrix.termArray[bpos].row,matrix.termArray[bpos].col,this->termArray[apos].value+matrix.termArray[bpos].value);apos++,bpos++;
        }
    }
    while(apos<this->terms)
    {
        tempSparseMatrix.InsertTerm(this->termArray[apos].row,this->termArray[apos].col,this->termArray[apos].value);apos++;
    }
    while(bpos<matrix.terms)
    {
        tempSparseMatrix.InsertTerm(matrix.termArray[bpos].row,matrix.termArray[bpos].col,matrix.termArray[bpos].value);bpos++;
    }
    return tempSparseMatrix;
}

4、矩阵乘法

void SparseMatrix::InsertTerm(int row, int col, int value)	
{
    if (this->terms == this->capacity)	//及时扩容
    {
        this->capacity *= 2;
        MatrixTerm* tempTerm = new MatrixTerm[this->capacity];
        for (int i = 0; i < this->terms; i++) {
        tempTerm[i] = this->termArray[i];
        }
        delete[]this->termArray;
        this->termArray = tempTerm;
    }
    if(row==this->termArray[terms-1].row&&col==this->termArray[terms-1].col){    //与前项位置相同
        this->termArray[terms-1].value+=value;
        if(!this->termArray[terms-1].value)this->terms--;    //系数和为零            
    }
    else{    //与前面项位置不同
        this->termArray[terms].row = row;
        this->termArray[terms].col = col;
        this->termArray[terms].value = value;
        this->terms++;
    }
}

SparseMatrix SparseMatrix::Mult(SparseMatrix matrix)
{
    if(this->cols!=matrix.rows){
        throw"Incompatible matrices";
    }
    SparseMatrix tempSparseMatrix{ this->rows,matrix.cols,0};
    matrix=matrix.FastTranspose();
    for (int i = 0; i < this->terms; i++) {
        for (int j = 0; j < matrix.terms; j++) {
            if(this->termArray[i].col==matrix.termArray[j].col){
                tempSparseMatrix.InsertTerm(this->termArray[i].row, matrix.termArray[j].row, this->termArray[i].value * matrix.termArray[j].value);
            }
        }
    }
    return tempSparseMatrix;
}

三、字符串抽象数据类型

1、字符串的ADT定义

class String 
{
private:
    char* str;
public:
    String(char* init,int m);
    bool operator==(string t);      //判断*this字符串是否等于t
    bool operator!();               //若*this为空返回true
    int Length();                   //返回字符数目
    int Find(String pat);           //字符串匹配
    String Concat(String t);        //将t连接为*this字符串的后缀
    String Substr(int i,int j);     //返回i到j-i+1共计j个字符串
};

2、字符串匹配

int String::Find(String pat)
{
    for(int start=0;start<=Length()-pat.Length();start++){
        int j;
        for(j=0;j<pat.Length()&&str[start+j]==pat.str[j];j++){
            if(j==pat.Length()-1){
                return start;
            }
        }
    }
    return -1;
}

KMP(Knuth-Morris-Pratt)算法
当文本串与模式串不匹配时,无需从头重复遍历,可以直接跳转
时间复杂度为O(n+m),其中n是文本串(this->str)的长度,m是模式串(pat.str)的长度

/*
  s ...a  b  c  a  ?  ?  ...
pat	   a  b  c  a  b  c  a  c  a  b
  i	   0  1  2  3  4  5  6  7  8  9
  f	  -1 -1 -1  0  1  2  3 -1  0  1
*/
void String::FailureFunction()	//获取失配函数
{
    this->f=new int[this->Length()];
    f[0]=-1;
    for(int i=1;i<this->Length();i++)
    {
        if(this->str[i]==this->str[f[i-1]+1]){
            this->f[i]=this->f[i-1]+1;
        }
        else{
            this->f[i]=-1;
        }
    }
}

int String::FastFind(String pat)
{
    int posP=0,posS=0;
    while(posP<pat.Length()&&posS<this->Length()){
        if(this->str[posS]==pat.str[posP])
            posS++,posP++;
        else{
            if(posP==0)
                posS++;
            else{
                posP=pat.f[posP-1]+1;
            }
        }
    }
    if(posP=pat.Length())
        return posS-posP;
    return -1;
}

四、多维数组

一维数组a[m1]
Loc[i]=a+i
二维数组a[m1][m2]
Loc[i,j]=a+i* m2+j
三维数组a[m1][m2][m3]
Loc[i,j,k]=a+i* m2* m3+j* m3+k

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值