1. 程式人生 > 實用技巧 >使用自定義的簡單順序表實現一元多項式的構造,計算值和加減

使用自定義的簡單順序表實現一元多項式的構造,計算值和加減

1、實現簡單的順序表

2、使用順序表實現一元多項式的構造

一、實現簡單的順序表

#include "ElemType.h"
#include "stdlib.h"



#ifndef DATASTRUCTURE_SQLIST_H
#define DATASTRUCTURE_SQLIST_H

#endif //DATASTRUCTURE_SQLIST_H

/**
 * 線性表的順序表示和實現(陣列)
 */
//操作成功
#define OK 1
//操作錯誤
#define ERROR 0
//操作異常
#define OVERFLOW -2
//定義元素型別,int可使用基本資料型別和使用者自定義資料型別替換,根據使用場景選擇
typedef int Status ; /** * 順序表的儲存結構 */ //predefine(預定義) constant(常量) maxn(n的最大值) #define MAXN 100 typedef struct { ElemType *elems; //儲存空間的基地址 int length; //線性表當前長度 }SqList;//sequence(序列) List(列表) /** * 順序表(順序結構的線性表)的基本操作的實現 */ /** * 構造一個空的順序表L * 演算法描述:開闢空間,設定順序表長度為零,返回操作結果 * @param L 指向順序表的指標L * @return 操作結果狀態碼
*/ Status initList(SqList *L){ //為順序表分配一個大小為MAXN的陣列空間 if(L==NULL) //printf a flag printf("this is a flag\n"); ; L->elems = (ElemType *)malloc(sizeof(ElemType)*MAXN); //儲存分配失敗,返回OVERFLOW,表示操作異常狀態 if(!L->elems) return OVERFLOW; //設定順序表長度為零 L->length = 0; //構造順序表成功,返回OK
return OK; } /** * 取順序表L中第i個元素elem * 演算法描述:判斷i是否大於等於1且小於順序表長度,返回ElemType陣列下標為i-1的元素 * @param L 指向順序表的指標L * @param i 要獲取的元素在順序表中的位置 * @return 操作結果狀態碼 */ Status getElem(SqList *L, int i, ElemType *e){ //如果i值不合法,返回ERROR表示操作錯誤 if(i < 1 || i > L->length){ return ERROR; } //將陣列的第i個元素的賦值給e指向的記憶體 *e = L->elems[i-1]; //操作成功,返回OK return OK; } /** * 查詢元素在順序表中的位置 * 演算法描述:查詢順序表中和元素e相同的元素出現的位置,若沒有和e匹配的元素,返回0 * @param L 指向順序表的指標L * @param e 要查詢的元素 * @return 元素在順序表中的位置 */ int indexOf(SqList *L, ElemType e){ for (int i = 0; i < L->length; ++i) { //查詢成功, 下標為i的元素是順序表的第i+1個元素,返回i+1 if(e == L->elems[i]){ return i+1; } } //查詢失敗,返回0 return 0; } /** * 在順序表L的第i個位置插入元素e,順序表長度加1 * 演算法描述:若i小於1或者i大於順序表L的當前長度加1,返回ERROR, * 若儲存空間已滿,返回ERROR,首先需要將順序表位置為n~i的元素依次後移,再在順序表位置i上插入元素e,順序表的長度加1 * @param L 指向順序表的指標L * @param i 插入位置i * @param e 要插入的元素e * @return 返回操作結果狀態碼 */ Status insertElem(SqList *L, int i, ElemType e){ //若i小於1或者i大於線性表L的當前長度,返回ERROR if(i < 1 || i > L->length + 1) return ERROR; //如果儲存空間已滿,返回ERROR if(L->length == MAXN) return ERROR; //將線性表位置為n~i的元素依次後移 for (int j = L->length; j >= i; --j) { L->elems[j] = L->elems[j-1]; } //在順序表位置i上插入元素e L->elems[i-1] = e; //線順序表的長度加1 ++L->length; return OK; } /** * 刪除順序表L上位置為i的元素,順序表長度減1 * 演算法描述:若i小於1或者i大於順序表L的當前長度,返回ERROR, * 將順序表位置為i+1~n的元素依次前移,順序表的長度減1 * @param L 指向順序表的指標L * @param i 刪除位置i * @return 返回操作結果狀態碼 */ Status deleteElem(SqList *L, int i){ //若i小於1或者i大於順序表L的當前長度,返回ERROR if(i < 1 || i > L->length) return ERROR; //將線性表位置為i+1~n的元素依次前移 for (int j = i; j < L->length; ++j) { L->elems[j-1] = L->elems[j]; } //順序表的長度減1 --L->length; return OK; } Status clearList(SqList *L){ L->length = 0; }

二、使用順序表實現一元多項式的構造

一元多項式的ADT(Abstract Data Type)

ADT UnaryPoly{
    資料物件:D = {p0, p1, ... , pn| n(-N, p(-R}
    資料關係:R = {<p0, p1, ..., pn>| p0是一元n次多項式P(之後簡稱P)的0次項的係數, p1是P的1次項的係數, ..., pn是P的n次項的係數}
    基本操作:
    create(&P, p0, p1, ..., pn)
    操作結構:構造一元n次多項式P
    calculate(&ans, P, x)
    初始條件:P是一元n次多項式, x是實數
    操作結構:確定P的元,計算一元n次多項式的值並返回
    add(&P, P1, P2)
    初始條件:P1, P2是一元多項式
    操作結果:返回P1, P2的和
    sub(&P, P1, P2)
    初始條件:P1, P2是一元多項式
    操作結果:返回P1, P2的差
}ADT UnaryPoly;

使用順序表的基本操作實現一元多項式的基本操作

#include<stdio.h>
#include "SqList.h"
#include<math.h>
#include<algorithm>

using namespace std;



/**
 * 使用順序表實現一元多項式
 */

/**
 * 實現一元多項式的基本操作
 */

/**
 * 根據長度為n的係數陣列p構造一元n次多項式L, 若n < 0 , 輸入不合法, 返回ERROR
 * @param L 指向一元被建立的一元多項式的指標
 * @param p 一元多項式L0到n次項的係數陣列的基址
 * @param n 一元多項式L的最高次數
 * @return 操作結果狀態碼
 */
Status create(SqList *L, double *p, int n) {
    //若n < 0 , 輸入不合法, 返回ERROR
    if (n < 0)return ERROR;
    //初始化順序表,得到一張空表,如果初始化失敗,返回OVERFLOW
    if (initList(L) != OK) {
        return OVERFLOW;
    }
    //依次插入係數陣列p下標為0, 1, ..., n-1的元素到順序表的第1, 2, ..., n個位置,如果插入失敗,返回ERROR
    for (int i = 0; i <= n; ++i) {
        if (insertElem(L, i + 1, p[i]) != OK) {
            return ERROR;
        }
    }
    //構造一元多項式成功,返回OK
    return OK;
}

/**
 * 對於確定的元為x的一元多項式L, 計算其值v
 * 若L不存在(未初始化), 返回ERROR
 * @param v 一元多項式的值
 * @param L 指向一元多項式的指標
 * @param x 給定的一元多項式的未知數的值
 * @return 操作結果狀態碼
 */
Status calculate(double *v, SqList *L, double x) {
    //L不存在(未初始化), 返回ERROR
    if (L == NULL) return ERROR;
    //設定一元多項式的初始值為0,然後依次累加每項的值並返回
    *v = 0;
    double *p = new double ;
    for (int i = 0; i < L->length; ++i) {
        //若取值失敗,返回ERROR
        if (getElem(L, i + 1, p) != OK) return ERROR;
        *v += pow(x, i) * (*p);
    }
    //計算成功返回OK
    return OK;
}

/**
 * 求和
 * 兩個一元多項式L1,L2求和,返回和L
 * @param L1    指向被加一元多項式L1的指標
 * @param L2    指向加一元多項式L2的指標
 * @param L     指向一元多項式L1與L2之和的指標
 * @return      操作結果狀態碼
 */

Status add(SqList *L1, SqList *L2,SqList *L) {
    //L1, L2未初始化, 返回ERROR
    if (L1 == NULL || L2 == NULL) return ERROR;
    //初始化失敗,返回OVERFLOW
    if(initList(L)!=OK) return OVERFLOW;
    //初始化成功,進行多項式求和
    int len = max(L1->length,L2->length);
    for (int i = 0; i < len; ++i) {
        //設定和多項式L的次數為i的項的係數為零
        double p = 0;
        double *p1 =new double ;
        //若L1包含次數為i的項,即L1的第i+1個元素,使多項式L的次數為i的係數加上L1對應次數項的係數
        if(i<L1->length){
            //獲取元素失敗,返回ERROR
            if(getElem(L1,i+1,p1)!=OK) return ERROR;
            p += *p1;
        }

        //若L2包含次數為i的項,即L2的第i+1個元素,使多項式L的次數為i的係數加上L2對應次數項的係數
        if(i<L2->length){
            //獲取元素失敗,返回ERROR
            if(getElem(L2,i+1,p1)!=OK) return ERROR;
            p += *p1;
        }

        //和多項式新增係數為p,次數為i的項作為第i+1一個元素
        if(insertElem(L,i+1,p)!=OK)return ERROR;
    }
    return OK;
}


/**
 * 求差
 * 兩個一元多項式L1,L2求差,返回和L
 * @param L1    指向被減一元多項式L1的指標
 * @param L2    指向減一元多項式L2的指標
 * @param L     指向一元多項式L1與L2之差的指標
 * @return      操作結果狀態碼
 */

Status sub(SqList *L1, SqList *L2,SqList *L) {
    //L1, L2未初始化, 返回ERROR
    if (L1 == NULL || L2 == NULL) return ERROR;
    //初始化失敗,返回OVERFLOW
    if(initList(L)!=OK) return OVERFLOW;
    //初始化成功,進行多項式求和
    int len = max(L1->length,L2->length);
    for (int i = 0; i < len; ++i) {
        //設定和多項式L的次數為i的項的係數為零
        double p = 0;
        double *p1 = new double ;
        //若L1包含次數為i的項,即L1的第i+1個元素,使多項式L的次數為i的係數加上L1對應次數項的係數
        if(i<L1->length){
            //獲取元素失敗,返回ERROR
            if(getElem(L1,i+1,p1)!=OK) return ERROR;
            p += *p1;
        }

        //若L2包含次數為i的項,即L2的第i+1個元素,使多項式L的次數為i的係數減去L2對應次數項的係數
        if(i<L2->length){
            //獲取元素失敗,返回ERROR
            if(getElem(L2,i+1,p1)!=OK) return ERROR;
            p -= *p1;
        }

        //和多項式新增係數為p,次數為i的項作為第i+1一個元素
        if(insertElem(L,i+1,p)!=OK)return ERROR;
    }
    return OK;
}

測試一元多項式的基本操作的功能

int main() {
    double p1[] = {1,2,1};
    double p2[] = {1,0,4,3};
    SqList *L1,*L2;
    L1 = new SqList ;
    L2 = new SqList ;
    if(create(L1,p1,2)!=OK)return 0;
    if(create(L2,p2,3)!=OK)return 0;
    int x = 3;
    double *v1,*v2,*v;
    v1 = new double ;
    v2 = new double ;
    v = new double ;
    if(calculate(v1,L1,x)!=OK)return 0;
    if(calculate(v2,L2,x)!=OK)return 0;
    //printf a flag
    printf("%lf\n",*v1);
    printf("%lf\n", *v2);
    SqList *L = new SqList ;
    if(add(L1,L2,L)!=OK)return 0;
    if(calculate(v,L,x)!=OK)return 0;
    printf("%lf\n", *v);
    if(clearList(L)!=OK)return 0;
    if(sub(L1,L2,L)!=OK)return 0;
    if(calculate(v,L,x)!=OK)return 0;
    printf("%lf\n", *v);
    return 0;
}

測試結果