【C语言X数据结构】用静态链表实现的多项式计算器,加减乘除求导求值,输入输出样样在行!(完整代码+注释)

循环冗余校验码(Cyclic Redundancy Check,CRC) CRC是一种基于多项式运算的高效错误检测编码方法。通过选择合适的生成多项式,CRC能够以较低的计算和传输开销,实现对数据的有效错误检测。理解CRC的技术原理有助于在实际应用中正确地实现和使用CRC算法,确保数据通信和存储的可靠性。模 2 运算是二进制中的一种运算规则,主要使用异或(XOR)操作代替加法和减法,且没有进位。模 2 乘法是普通的二进制乘法,没有进位或更高的数位。模 2 运算特别适合应用于数字通信中的错误检测、编码理论等领域,因为它能有效简化二进制数据的处理。 阅读详情

目录

实验要求

完整代码

逻辑设计



哈喽各位好,我是李博轩,一个刚转到计算机的大二学生。这个标题是随手打上去的,感觉还蛮顺口,就这样了。

这个学期在学【数据结构与算法】,而这是我面对的第一个实验题。因为大一不在计算机,编程能力落后于人,这个作业也花了很多时间和精力。总之,下面把题目要求和代码附上,希望得到各位的指点。

实验要求

        以动态或者静态链表存储一元多项式,在此基础上按要求完成对一元多项式的运算。(为保证多项式的值的准确性,多项式的系数可以用分数表示,涉及到两个分数相除时,结果也可以用分数表示。)

1. 能够输入多项式(可以按各项的任意输入顺序,建立按指数降幂排列的多项式)和输出多项式(按指数降幂排列),以文件形式输入和输出,并显示。

2. 能够给出计算两个多项式加法、减法、乘法和除法运算的结果多项式,除法运算的结果包括商多项式和余数多项式。

3. 能够计算一元多项式的 k 阶导函数。

4. 能够计算多项式在某一点 x=x0 的值,其中 x0是一个浮点型常量,返回结果为浮点数。

5. 要求尽量减少乘法和除法运算中间结果的空间占用和结点频繁的分配与回收操作。(提示:利用循环链表结构或者可用空间表的思想,把循环链表表示的多项式返还给系统或者可用空间表,从而解决上述问题)。 


 完整代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAXSIZE 4096
#define MAXLEN 256
typedef struct{
    int numerator;  //分子
    int denumerator;//分母
    int index; //指数
}elemtype;
typedef struct{
    elemtype val;
    int next;   //下一结点的指针
}LISTNODE;
LISTNODE SPACE[MAXSIZE];    //储存池
typedef int position, head; //表头和指针
head av = 0, L;
//初始化存储池
head load[MAXLEN] = {-1};
head save[MAXLEN] = {-1};
int loaded = 0; //是否已经加载
head cursor_s1 = -1;   //游标1
head cursor_s2 = -1;   //游标2
int cursor_save = 0; //保存用
int cursor_load = 0; //加载用
int number_load = 0;   //加载数量
int number_save = 0;   //结果数量
char cursor_menu = '9';    //菜单
//初始化菜单
void Init(){    //DONE!
    printf("正在初始化中...\n");
    //链接结点
    int i;
    for(i=0; i<MAXSIZE-1; i++){
        SPACE[i].val.numerator = 0;
        SPACE[i].val.denumerator = 1;
        SPACE[i].val.index = 0;
        SPACE[i].next = i+1;
    }
    //设定表尾
    SPACE[i].val.numerator = 0;
    SPACE[i].val.denumerator = 1;
    SPACE[i].val.index = 0;
    SPACE[i].next = -1;
    //表示可用线性表
    av = 0;
};
//获得可用空间
position GetNode(){ //DONE!!
    position p;
    if(SPACE[av].next==-1){
        p = -1;
        printf("可用空间为空!\n");
    }else{
        p = SPACE[av].next;
        SPACE[av].next = SPACE[p].next;
    }
    return p;
};
//回收可用空间
void FreeNode(position p){  //DONE!
    SPACE[p].next = SPACE[av].next;
    SPACE[av].next = p;
};
//创建链表
head Create(void){  //DONE!
    head p;
    if(SPACE[av].next==-1){
        p = -1;
        printf("创建链表时可用空间不足!\n");
    }
    else{
        p = GetNode();
        position q = GetNode();
        SPACE[p].next = q;
        SPACE[q].next = -1;
    }
    return p;
};
//链表插入
void Insert(elemtype x,position p){ //DONE!
    position q = GetNode();
    SPACE[q].val = x;
    SPACE[q].next = SPACE[p].next;
    SPACE[p].next = q;
};
//链表删除
void Delete(position p){    //DONE! (注:删除当前而非下一位)
    if(SPACE[p].next!=-1){
        position q = SPACE[p].next;
        SPACE[p].next = SPACE[q].next;
        SPACE[p].val = SPACE[q].val;
        FreeNode(q);
    }
};
//找到末尾元素
position End(head p){   //DONE!!
    position q = p;
    while(SPACE[SPACE[q].next].next!=-1){
        q = SPACE[q].next;
    }
    return q;
};
//找到起始元素
position First(head p){ //DONE!!
//清空链表
    return SPACE[p].next;
};
head Destory(head L){   //DONE!!
    position p =First(L);
    position q = p;
    while(SPACE[p].next!=-1){
        q = p;
        p = SPACE[p].next;
        FreeNode(q);
    }
};
//复制链表
head Copy(head L){  //DONE!!
    head newone = Create();
    position p =First(L);
    while(SPACE[p].next!=-1){
        Insert(SPACE[p].val,End(newone));
        p = SPACE[p].next;
    }
    return newone;
};

void MENU(void);    //陈列功能
void DISPLAY(void); //显示全部多项式
void SELECT(void);  //重新选择多项式
void COLLECT(void); //加载结果多项式
void SAVE(void); //保存输出多项式

head INPUT(void);
void LOAD(FILE* STR);
void SHOW(head L);
void LAST(void);

head PLUS(head L1,head L2);
head SUBTRACT(head L1,head L2);
head MULTIPLY(head L1,head L2);
void DIVIDE(head L1,head L2);
head DERIVALTIVE(head L);
double VALUE(head L,double x);
void CLEAR(head L);
head ZERO();

elemtype fractionPlus(elemtype a,elemtype b);
elemtype fractionSubtract(elemtype a,elemtype b);
elemtype fractionMultiply(elemtype a,elemtype b);
elemtype fractionDivide(elemtype a,elemtype b);
elemtype fractionGCD(elemtype x);

int main(){
    Init();
    MENU();
    FILE *str;
    str = fopen("INPUT.txt","r");
    if(str == NULL){
        printf("打开文件失败!");
        exit(0);
    }
    LOAD(str);
    DISPLAY();
    SELECT();
    while(cursor_menu!='0'){
        getchar();
        printf("请选择功能:");
        scanf("%c",&cursor_menu);
        switch (cursor_menu){
            case 'A':{
                DISPLAY();
            }break;
            case 'B':{
                SELECT();
            }break;
            case 'C':{
                head newone = INPUT();
                printf("输入为:\n");
                SHOW(newone);
                load[number_load] = newone;
                number_load ++;
                save[cursor_save] = newone;
                cursor_save++;
                number_load = cursor_load;
            }break;
            case 'D':{
                COLLECT();
                number_load = cursor_load;
            }break;
            case 'E':{
                SAVE();
            }break;
            case 'F':{
                LAST();
            }break;
            case 'H':{
                MENU();
            }break;
            case '1':{
                head newone = PLUS(load[cursor_s1],load[cursor_s2]);
                printf("和为:\n");
                SHOW(newone);
                save[cursor_save] = newone;
                cursor_save++;
            }break;
            case '2':{
                head newone = SUBTRACT(load[cursor_s1],load[cursor_s2]);
                printf("差为:\n");
                SHOW(newone);
                save[cursor_save] = newone;
                cursor_save++;
            }break;
            case '3':{
                head newone = MULTIPLY(load[cursor_s1],load[cursor_s2]);
                printf("积为:\n");
                SHOW(newone);
                save[cursor_save] = newone;
                cursor_save++;
            }break;
            case '4':{
                DIVIDE(load[cursor_s1],load[cursor_s2]);
            }break;
            case '5':{
                head newone = DERIVALTIVE(load[cursor_s1]);
                printf("导数为:\n");
                SHOW(newone);
                save[cursor_save] = newone;
                cursor_save++;
            }break;
            case '6':{
                printf("请输入求值的点:");
                double x;
                scanf("%lf",&x);
                VALUE(load[cursor_s1],x);
            }break;
        }
    }
    printf("正在关机...\n");
    fclose(str);
}
head INPUT(void){   //DONE!!
    printf("请按照“系数分子/系数分母 指数”的顺序输入多项式,分母为0结束:\n");
    printf("例:-1/2 2 3/1 4 4/1 3 3/2 5 1/0 1\n");
    int fz, fm, zh;
    head newone = Create();
    int count = 0;
    while(1){
        scanf("%d/%d %d",&fz,&fm,&zh);
        if(fm == 0) break;
        count += 1;
        elemtype x;
        x.numerator = fz;
        x.denumerator = fm;
        x.index = zh;
        Insert(x,End(newone));
    }
    for(int i=0; i<count-1;i++){
        position p = SPACE[newone].next;
        for(int j=0; j<count-1-i;j++){
            if((SPACE[p].val.index)<(SPACE[SPACE[p].next].val.index)){
                elemtype temp = SPACE[p].val;
                SPACE[p].val = SPACE[SPACE[p].next].val;
                SPACE[SPACE[p].next].val = temp;
            }
            p = SPACE[p].next;
        }
    }
    CLEAR(newone);
    return newone;
}
void LOAD(FILE* STR){   //DONE!!
    if(loaded == 0){
        printf("正在从文件中读取多项式...\n");
        fscanf(STR,"%d",&number_load);
        printf("读取到%d个多项式!!\n",number_load);
        cursor_load = 0;
        int fz, fm, zh;
        while(cursor_load < number_load && number_load < MAXLEN){
            head newone = Create();
            int count = 0;
                while(1){
                    fscanf(STR,"%d/%d %d",&fz,&fm,&zh);
                    if(fm == 0) break;
                    elemtype x;
                    x.numerator = fz;
                    x.denumerator = fm;
                    x.index = zh;
                    Insert(x,End(newone));
                    count ++;
                }
                for(int i=0; i<count-1;i++){
                    position p = First(newone);
                    for(int j=0; j<count-1-i;j++){
                        if((SPACE[p].val.index)<(SPACE[SPACE[p].next].val.index)){
                            elemtype temp = SPACE[p].val;
                            SPACE[p].val = SPACE[SPACE[p].next].val;
                            SPACE[SPACE[p].next].val = temp;
                        }
                        p = SPACE[p].next;
                    }
                }
            load[cursor_load] = newone;
            cursor_load ++;
        }
        loaded = 1;
        return;
    }
    else printf("多项式已加载!\n");
}
void SHOW(head L){  //DONE!!
    position p = First(L);
    printf("\t\t");
    while(SPACE[p].next!=-1){
        if(SPACE[p].val.index==0){
            printf("(%d/%d)",SPACE[p].val.numerator,SPACE[p].val.denumerator);
        }else{
            printf("(%d/%d) x^%d",SPACE[p].val.numerator,SPACE[p].val.denumerator,SPACE[p].val.index);
        }
        if(SPACE[SPACE[p].next].next!=-1) printf(" + ");
        p = SPACE[p].next;
    }
    printf("\n");
}
head PLUS(head L1,head L2){ //DONE!!
    head newone = Create();
    head List1 = Copy(L1);
    head List2 = Copy(L2);
    //SHOW(List1);
    //SHOW(List2);
    position p1 = First(List1);
    position p2 = First(List2);
    while(SPACE[p1].next!=-1&&SPACE[p2].next!=-1){
        if(SPACE[p1].val.index>SPACE[p2].val.index){
            elemtype x = SPACE[p1].val;
            Insert(x,End(newone));
            p1 = SPACE[p1].next;
        }
        else if(SPACE[p1].val.index<SPACE[p2].val.index){
            elemtype x = SPACE[p2].val;
            Insert(x,End(newone));
            p2 = SPACE[p2].next;
        }
        else if(SPACE[p1].val.index==SPACE[p2].val.index){
            elemtype x = fractionPlus(SPACE[p1].val,SPACE[p2].val);
            Insert(x,End(newone));
            p1 = SPACE[p1].next;
            p2 = SPACE[p2].next;
        }
        else{
            printf("ERROR WHEN PLUS!!\n");
        }
    }
    SPACE[End(newone)].next = (SPACE[p1].next==-1)?p2:p1;
    CLEAR(newone);
    return newone;
}
head SUBTRACT(head L1,head L2){ //DONE!!
    head newone = Create();
    head List1 = Copy(L1);
    head List2 = Copy(L2);
    //SHOW(List1);
    //SHOW(List2);
    position p1 = First(List1);
    position p2 = First(List2);
    while(SPACE[p1].next!=-1&&SPACE[p2].next!=-1){
        elemtype x = SPACE[p1].val;
        elemtype y = SPACE[p2].val;
        if(SPACE[p1].val.index>SPACE[p2].val.index){
            Insert(x,End(newone));
            p1 = SPACE[p1].next;
        }
        else if(SPACE[p1].val.index<SPACE[p2].val.index){
            y.numerator *= -1;
            Insert(y,End(newone));
            p2 = SPACE[p2].next;
        }
        else{
            elemtype z = fractionSubtract(x,y);
            Insert(z,End(newone));
            p1 = SPACE[p1].next;
            p2 = SPACE[p2].next;
        }
    }
    if(SPACE[p2].next==-1){
        SPACE[End(newone)].next = p1;
        CLEAR(newone);
        return newone;
    }
    while(SPACE[p2].next!=-1){
        elemtype y = SPACE[p2].val;
        y.numerator *= -1;
        Insert(y,End(newone));
        p2 = SPACE[p2].next;
    }
    CLEAR(newone);
    return newone;
}
head MULTIPLY(head L1,head L2){ //DONE!!
    position p = First(L1); int s1 = SPACE[p].val.index;
    position q = First(L2); int s2 = SPACE[q].val.index;
    head* arrL = (head*) malloc(sizeof(position)*(s1+1)*(s2+1));
    int count = 0;
    while(SPACE[p].next!=-1){
        arrL[count] = Create();
        q = First(L2);
        while(SPACE[q].next!=-1){
            elemtype newnode = fractionMultiply(SPACE[p].val,SPACE[q].val);
            Insert(newnode,End(arrL[count]));
            q = SPACE[q].next;
            //printf("q动了一下!");
        }
        //printf("p动了一下!");
        count ++;
        p = SPACE[p].next;
    }
    //printf("需要相加的有%d个式子:\n",count);
    head* L = (head*) malloc(sizeof(position)*(s1+s2+1));
    L[0] = ZERO();
    for(int i=0; i<count; i++){
        L[i+1] = Create();
        //printf("第%d个式子为:",i+1);
        //SHOW(arrL[i]);
        //SHOW(L[i]);
        L[i+1] = PLUS(L[i],arrL[i]);
        //printf("第%d个he式为:",i+1);
        //SHOW(L[i+1]);
    }
    free(arrL);     arrL = NULL;
    CLEAR(L[count]);
    return L[count];
}
elemtype fractionMultiply(elemtype a,elemtype b){ //DONE!!
    elemtype x;
    x.index = a.index + b.index;
    x.numerator = a.numerator * b.numerator;
    x.denumerator = a.denumerator * b.denumerator;
    return fractionGCD(x);
}
elemtype fractionPlus(elemtype a,elemtype b){
    if(a.index!=b.index){
        printf("指数不同无法相加!\n");
        return a;
    }
    int fz1 = a.numerator;  int fm1 = a.denumerator;
    int fz2 = b.numerator;  int fm2 = b.denumerator;
    int fz = fz1*fm2 + fz2*fm1; int fm = fm1*fm2;
    elemtype x;
    x.numerator = fz;
    x.denumerator = fm;
    x.index = a.index;
    return fractionGCD(x);
}
elemtype fractionSubtract(elemtype a,elemtype b){
    if(a.index!=b.index){
        printf("指数不同无法相减!\n");
        return a;
    }
    int fz1 = a.numerator;  int fm1 = a.denumerator;
    int fz2 = b.numerator;  int fm2 = b.denumerator;
    int fz = fz1*fm2 - fz2*fm1; int fm = fm1*fm2;
    elemtype x;
    x.numerator = fz;
    x.denumerator = fm;
    x.index = a.index;
    return fractionGCD(x);
}
elemtype fractionGCD(elemtype x){   //DONE!!
    int fz = abs(x.numerator);
    int fm = abs(x.denumerator);
    if(fm==0){
        printf("出现分母为零!\n");
        return x;
    }
    if(fz==0){
        x.denumerator = 1;
        return x;
    }
    int GCD = fz>fm?fm:fz;
    while(GCD>1){
        if((fz%GCD==0)&&(fm%GCD==0)){
            break;
        }
        GCD--;
    }
    fm = x.denumerator/GCD;
    fz = x.numerator/GCD;
    elemtype xgcd;
    xgcd.numerator = fz;
    xgcd.denumerator = fm;
    xgcd.index = x.index;
    return xgcd;
}
head DERIVALTIVE(head L){
    head newone = Create();
    position p = First(L);
    while(SPACE[p].next!=-1){
        elemtype x;
        if(SPACE[p].val.index==0){
            x.numerator = 0;
        }else{
            x.numerator = SPACE[p].val.numerator * SPACE[p].val.index;
        }
        x.denumerator = SPACE[p].val.denumerator;
        x.index = SPACE[p].val.index - 1;
        Insert(fractionGCD(x),End(newone));
        p = SPACE[p].next;
    }
    CLEAR(newone);
    return newone;
}
double VALUE(head L,double x){
    double ans = 0;
    position p = First(L);
    while(SPACE[p].next!=-1){
        ans += SPACE[p].val.numerator*1.0/SPACE[p].val.denumerator*1.0*pow(x,SPACE[p].val.index);
        p = SPACE[p].next;
    }
    printf("该多项式在%.2lf处的值为:%.2f\n",x,ans);
    return ans;
}
void DIVIDE(head L1,head L2){
    //多项式相除->获得商元素->获得余数多项式->余数多项式作为被除数
    //直到被除数的最高次数小于除数的最高次数
    const head divide = Copy(L2); //divide_除数
    head bedivided = Copy(L1);//一直在变化的被除数
    head quotient = ZERO();//创建商多项式
    head sub_bedivided = Create();
    sub_bedivided = bedivided;//创建一个被减元素
    while(SPACE[SPACE[sub_bedivided].next].val.index>=SPACE[SPACE[divide].next].val.index){
        bedivided = sub_bedivided;
        //新的余数作为新的被除数
        elemtype part = fractionDivide(SPACE[First(bedivided)].val,SPACE[First(divide)].val);
        //计算商元素
        CLEAR(quotient);
        //商元素插入商多项式中
        head quotient_part = Create();
        Insert(part,End(quotient_part));
        quotient = PLUS(quotient_part,quotient);
            //printf("商元素为:\t");
            //SHOW(quotient_part);
        //创建一个商元素多项式
        head mul_divide = MULTIPLY(quotient_part,L2);
            //printf("乘过的为:\t");
            //SHOW(mul_divide);
        sub_bedivided = SUBTRACT(bedivided,mul_divide);
        //获取余数
        CLEAR(sub_bedivided);
            //printf("余数为:\t");
            //SHOW(sub_bedivided);
        Destory(quotient_part);
    }
    printf("商为:\n");
    SHOW(quotient);
    save[cursor_save] = quotient;
    cursor_save++;
    printf("余数为:\n");
    SHOW(sub_bedivided);
    save[cursor_save] = sub_bedivided;
    cursor_save++;
}
elemtype fractionDivide(elemtype a,elemtype b){
    if(a.index<b.index){
        printf("被除多项数次数小于除数多项式,不能再除!\n");
        return a;
    }
    int fz1 = a.numerator;  int fm1 = a.denumerator;
    int fz2 = b.numerator;  int fm2 = b.denumerator;
    elemtype x;
    x.index = a.index-b.index;
    x.numerator = fz1 * fm2;
    x.denumerator = fz2 * fm1;
    x = fractionGCD(x);
    return x;
}
head ZERO(void){
    head newone = Create();
    elemtype x;
    x.numerator = 0;
    x.denumerator = 1;
    x.index = 0;
    Insert(x,End(newone));
    return newone;
}
void CLEAR(head L){
    position p = First(L);
    while(SPACE[p].next!=-1){
        if(SPACE[p].val.numerator==0){
            Delete(p);
        }else{
            p = SPACE[p].next;
        }
    }
}
void MENU(void){    //DONE!
    printf("------欢迎使用一元多项式计算器------\n");
    printf("将读入多项式,请选择功能:\n");
    printf("A->显示所有\t");
    printf("B->重新选中\t");
    printf("C->键盘输入\t");
    printf("D->加载结果\t");
    printf("E->保存结果\t");
    printf("F->选中最新\t");
    printf("H->帮助\n");
    printf("0->退出\t\t");
    printf("1->求和\t\t");
    printf("2->做差\t\t");
    printf("3->乘积\t\t");
    printf("4->相除\t\t");
    printf("5->求导\t\t");
    printf("6->求值\n");
}
void DISPLAY(void){
    printf("初始输入多项式:\n");
    for(int i=0; i<number_load; i++){
        printf("编号:%d-->\n",i);
        SHOW(load[i]);
    }
    printf("结果多项式:\n");
    for(int i=0; i<cursor_save; i++){
        printf("编号:%d-->\n",i);
        SHOW(save[i]);
    }
}
void SELECT(void){
    printf("按次序选择两个多项式:");
    scanf("%d %d",&cursor_s1,&cursor_s2);
    if (cursor_s1>0){
        if(cursor_s1>number_load||cursor_s2>number_load){
            printf("数字过大!\n");
            return;
        }
        printf("你选中了:\n");
        printf("第一个->\n");
        SHOW(load[cursor_s1]);
        printf("第二个->\n");
        SHOW(load[cursor_s2]);
    }
}
void COLLECT(void){
    fflush(stdin);
    printf("选择结果多项式:\n");
    for(int i=0; i<cursor_save; i++){
        printf("编号:%d-->\n",i);
        SHOW(save[i]);
    }
    int s;
    scanf("%d",&s);
    if(0<=s&&s<=cursor_save){
            printf("载入输出编号%d-->",s);
            load[cursor_load] = save[s];
            printf("输入编号%d!",cursor_load);
            cursor_load++;
    }
}
void SAVE(void){
    FILE* PUT;
    PUT = fopen("OUTPUT.txt","w");
    if(PUT == NULL){
        printf("保存失败!!\n");
        return;
    }
    printf("正在储存数据...\n");
    number_save = cursor_save;
    fprintf(PUT,"%d\n",number_save);
    for(int i=0; i<number_save; i++){
            position p = First(save[i]);
            while(SPACE[p].next!=-1){
                fprintf(PUT,"%d/%d %d ",SPACE[p].val.numerator,SPACE[p].val.denumerator,SPACE[p].val.index);
                p = SPACE[p].next;
            }
            fprintf(PUT,"1/0 1 \n");
    }
    fclose(PUT);
    printf("储存完毕!!正在返回计算器...\n");
    MENU();
}
void LAST(void){
    load[cursor_load] = save[cursor_save-1];
    printf("载入最新结果!\t");
    cursor_s1 = cursor_load;
    cursor_load++;
}

 


逻辑设计

主程序流程图


程序模块间的调用关系

 

 

 

(3)CRC校验码的生成多项式表示与常用生成多项式 这是CRC码原理与实现系列的第三篇文章。(1)CRC码简介及其与汉明码的区别(2)CRC校验码的原理。 阅读详情

相关推荐

Arduino跑通ssd1306_spi显示屏

代码首先,您需要下载两个库:● Adafruit GFX库,这是核心图形库,提供了一组通用的图形基元(点、线、圆等)。它需要与特定于硬件的库对应。● Adafruit SSD-1306 OLED显示库,这是基于SSD1306驱动程序的OLED显示器的库。解压缩这两个库并将它们添加到Arduino库文件夹中,然后运行Arduino IDE并从OLED库中打开SPI示例。

Leo ICer的博客 1494

【CRC循环冗余校验-2】crc多项式及校验原理

CRC多项式是为了生成一个除数,这个除数是模二运算的除数 示例:, 多项式生成的二进制序列位数是最高次幂加一,即6位,即从第0位开始到第5位,多项式中为0的位已经省略,原式为:(0次幂为1),幂次数也即其位置,即:100101 如上,生成的二进制序列即为crc检验用到的除数,而crc校验码即数据补0后除(模二运算除)以这个除数后的余数,检验码位数比除数少一位,余数不足的位用0补足,数据补0即在原始数据后加上除数减一个0. 示例:原始数据:10110011, 多项式: 多项式生成除...

幻蜗的笔记 1万+

数学之美 | 图论和网络爬虫

文章目录概述图论网络爬虫分析BFSDFSBFS + DFS参考资料 概述 这篇文章主要给大家介绍一下计算机算法中非常重要的一部分——图论,以及它在生活中的应用——网络爬虫。   图论 离散数学是当代数学的一个重要的分支,也是计算机科学的数学基础。它又包括四个分支,而图论便是其中一支,另外三个分别是:数理逻辑、集合论、近代数学。 图论中的图由一些节点和边构成,比如下面这张图 。 在图论中一个很基础...

小小酥梨的博客 3231

CRC校验(1):CRC原理、计算例子和最优多项式的选择

CRC校验在做项目的过程中经常会使用到,在我上大学的时候有浅浅地理解这个计算的过程,后面工作了就是直接用NXP SDK中写的软件CRC的代码。说实话,我看不懂这简简单单的几行CRC-32查表算法,但我不希望我只是会用这些函数,而是要理解其中的原理。所以我开始写这一系列的博客深入地研究和理解常见的一些算法,希望能有所收获。对于现在的CPU来说,大多都在硬件上实现了CRC校验,但我想从软件上来实现CRC32的查表算法,包括表格的生成和CRC的计算。

主要分享嵌入式软件、人工智能部分知识 1万+

使用Kolla部署多节点Rocky版本OpenStack

openstack命令行客户端使用,post-deploy会在 /etc/kolla/目录下生成文件admin-openrc.sh。每次使用openstack命令时执行source /etc/kolla/admin-openrc.sh(manager节点执行)source /etc/kolla/admin-openrc.sh (将文件内容复制到/etc/profile中,即可一直生效)3.2.2 开始安装kolla-ansible,要带上--ignore-installed PyYAML,否则可能会报错。

gyc1206的博客 1929

实战分享:如何用Dify和MaxKb实现文档智能切分与高效检索(附代码解析)

本文详细介绍了如何结合Dify和MaxKB构建文档智能切分与高效检索系统。针对传统全文检索的不足,提出了结构感知的文档切分方案,通过解析文档层级关系并构建标题链,实现了精准的章节级检索。文章包含完整的代码实现,涵盖文档解析、智能切分、向量化策略及双索引优化,并分享了性能调优和生产环境实践经验。

qsc90123456的博客 547

CRC校验多项式

循环冗余校验码(CRC) 循环冗余校验码(CRC)的基本原理是:在K位信息码后再拼接R位的校验码,整个编码长度为N位,因此,这种编码又叫(N,K)码。对于一个给定的(N,K)码,可以证明存在一个最高次幂为N-K=R的多项式G(x)。根据G(x)可以生成K位信息的校验码,而G(x)叫做这个CRC码的生成多项式。 校验码的具体生成过程为:假设发送信息用信息多项式C(X)表示,将C(x)左移R位,则可表...

Owen_Liangcheng的博客 1万+

最短线性递推式求解与有理函数重建

这一算法来自于我们对“线性递推式拟合”的视角转换,其后得到的算法是自然的。 引理 1. 如果两个有理分式 p1/q1,p2/q2p_1/q_1, p_2/q_2p1​/q1​,p2​/q2​ 均有 deg⁡p<n,deg⁡q≤n\deg p<n, \deg q\leq ndegp<n,degq≤n 且展开式 p1/q1≡p2/q2(modx2n)p_1/q_1 \equiv p_2/q_2 \pmod {x^{2n}}p1​/q1​≡p2​/q2​(modx2n),那么 p1/q1=p2/

Entropy Increaser 的博客 2592

CRC算法

CRC计算

FU_GUANJUN的博客 1万+

《QGIS快速入门与应用基础》108:CGCS2000对应的投影坐标系

本文详细解析了CGCS2000地理坐标系对应的各类投影坐标系,包括高斯-克吕格3°带/6°带、UTM、地方独立投影和Web墨卡托投影。文章系统阐述了各投影类型的分带规则、参数设置、精度特性及适用场景,并提供了EPSG编码对照表和QGIS操作指南。通过"基准+投影"的绑定机制,这些投影坐标系实现了平面坐标与经纬度的精准转换,满足从大比例尺工程测量到Web地图服务等不同应用需求。内容涵盖投影原理、坐标格式、变形控制等关键技术要点,为GIS开发者和测绘人员提供了实用的参考信息。

LuckyHanMo的博客 545

PX4从放弃到精通(二十七):固定翼姿态控制

固件版本 PX4 1.13.2欢迎交流学习,可加左侧名片。

超维空间科技的博客 6892

CRC 生成多项式

是接受方和发送方的一个约定,也就是一个二进制数,在整个传输过程中,这个数始终保持不变。 在发送方,利用生成多项式对信息多项式做模2除生成校验码。在接受方利用生成多项式对收到的编码多项式做模2除检测和确定错误位置。 应满足以下条件: a、生成多项式的最高位和最低位必须为1。 b、当被传送信息(CRC码)任何一位发生错误时,被生成多项式做模2除后应该使余数不为0。 c、不同位发生错误时,应该

lonffy的专栏 6845

深入大模型-19-Windows10中安装OpenClaw-CN配置接入智谱免费大模型

OpenClaw CN (中国社区版) 是 OpenClaw 的本地化维护版本,针对国内网络环境进行了深度优化,源码级原生支持 DeepSeek/Qwen 等国产大模型,致力于让中国开发者拥有最顺滑的 Agent 开发体验。

qq_20466211的博客 771

crc码生成多项式怎么算出来的_CRC校验源码分析

这两天做项目,需要用到 CRC 校验。以前没搞过这东东,以为挺简单的。结果看看别人提供的汇编源程序,居然看不懂。花了两天时间研究了一下 CRC 校验,希望我写的这点东西能够帮助和我有同样困惑的朋友节省点时间。先是在网上下了一堆乱七八遭的资料下来,感觉都是一个模样,全都是从 CRC 的数学原理开始,一长串的表达式看的我头晕。第一次接触还真难以理解。这些东西不想在这里讲,随便找一下都是一大把。我想根据...

weixin_33374585的博客 1万+

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

CRC校验的原理

CRC是什么? CRC全称是:Cyclic Redundancy Check,翻译过来就是:循环冗余校验码。是在数据通信领域中一种十分常用的查错校验码,和串口通信中常用的奇偶校验是属于同一种类型的。都是进行数据查错的算法,而不具有纠错能力。 CRC的所采用的多项式是什么 数据发送方(TX)与接收方(RX)进行交换时,采用CRC进行数据检错时,确定数据在传送过程中没有发生错误。其基本实现原理是TX侧在一个将要传送的数据包后加上N位CRC校验码,RX侧接收 数据包+N位CRC校验码。而添加CRC校验码的基本原则

sinat_34875384的博客 2544

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

CRC 常用多项式 与 计算代码

常用多项式: 生成多项式的选取应满足以下条件:     a、生成多项式的最高位和最低位必须为1。     b、当被传送信息(CRC码)任何一位发生错误时,被生成多项式做模2除后,应该使余数不为0。     c、不同位发生错误时,应该使余数不同。     d、对余数继续做模2除,应使余数循环。 主要的生成多项式G(x)有以下几种: 名称 生成多项式 ...

Sunning Pig 的专栏 3万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

最详细的“CRC码原理详解”

某人,查阅和参考了大量博主的优质内容,总结一篇完整的CRC码详解,文字内容尽量做到最少。CRC码即循环冗余校验码(Cyclic Redundancy Check)是数据通信领域中最常用的一种查错校验码,其特征是数据字段和校验字段的长度可以任意选定。基本原理CRC码中数据总长度为n,其中原始数据长度为k,CRC校验码长度为r,即n=k+r。将原始数据(如:1110010)+CRC校验码(如:101)组成新的数据(如:1110010101),发送到接收端。其中,CRC校验码由CRC多项式。

qq_37708525的博客 2万+

CRC校验

细致入微的讲解CRC校验,手把手带你验证。CRC(Cyclic Redundancy Check)校验即循环冗余校验,是一种在数字通信和数据存储领域广泛应用的检错技术,用于检测数据在传输或存储过程中是否发生错误。

ikun 7174

CRC校验的计算方法和示例

CRC多项式校验计算方法

不知道你是通过何种途径访问到这里,总之欢迎来到red velet的博客 3593

详解CRC校验码生成多项式的“四大条件”

本文对简中网博文乃至某些教材上广泛提及的CRC校验码生成多项之“四大条件”进行了系统性分析,发现: 条件1,是必要的,同时也是众所周知的,所有现行通讯协议规范都遵照的。 条件2,是毫无意义的,是条件1的结果,满足条件1自然满足条件2。 条件3,是码字长度与生成多项式周期的权衡结果。较短(比如8位)的CRC校验位时,现行通讯协议规范不一定都满足。 条件4,都不能称其为条件,是CRC校验码生成多项式固有周期的外在表现,用CRC就天然满足。

innovationcjs的博客 2233

CRC算法详解

原文出处:http://blog.youkuaiyun.com/sparkliang/article/details/5671510 感谢作者的详解。转到此处以备学习。 作为blog再次发出来,详细描述一下CRC32算法的推导过程。 CRC算法的数学基础 CRC算法的数学基础就不

学而不思则罔 4672

CRC的计算

用多项式来表示循环冗余检验过程。 多项式P(X) = X4 + X3 + 1表示除数P=11001 现假设选择的CRC生成多项式为P(X) = X4 + X3 + 1,要求出二进制序列10110011的CRC校验码。下面是具体的计算过程: (1)首先把生成多项式转换成二进制数,由G(X) = X4 + X3 + 1可以知道(,它一共是5位(总位数等于最高位的幂次加1,即4+1=5),然后根据多项式...

qq_45712170的博客 2万+

CRC的数学原理

CRC(循环冗余校验)是一种基于多项式除法的差错检测技术,广泛应用于数据传输和存储领域。其核心原理是将数据视为二进制多项式,通过模2除法计算余数作为校验码。接收方通过验证余数是否为0判断数据完整性。CRC具有强大的检错能力,可检测所有奇数比特错误和长度不超过生成多项式阶数的突发错误,漏检概率仅为1/2^r(r为校验码长度)。常见标准包括CRC-8、CRC-16和CRC-32,分别适用于不同场景。相比奇偶校验和校验和,CRC具有更高的可靠性,但仅能检错不能纠错。其有效性通过多项式模2运算的整除性得以证明,广泛

颹蕭蕭 2931

CRC:循环冗余校验

CRC32:多项式是X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1,对应数字是0x104C11DB7。常见的CRC校验:CRC8,CRC16,CRC32。CRC12:多项式是X12+X11+X3+X2+1,对应的数字是0x180D。CRC16:多项式是X16+X12+X5+1,对应的数字是0x11021。CRC16:多项式是X16+X15+X2+1,对应的数字是0x18005。CRC8:多项式是X8+X5+X4+1,对应的数字是0x131。

qq_51284092的博客 6595

crc生成多项式怎么算_FPGA-CRC校验学习笔记

以太网帧需要对数据进行CRC校验,原理部分参考以下文章:https://blog.51cto.com/winda/1063951https://www.cnblogs.com/masonzhang/p/10261855.html以太网帧需要进行CRC32校验,FPGA开发一般使用的是CRC32_d4.v这个代码进行校验和的计算,输入数据是4比特,初始值是32’hffffffff,代码是组合逻辑实现...

weixin_36410316的博客 4036

【加解密与C】CRC

CRC是一种用于检测数据传输或存储中错误的校验算法。它通过生成固定长度的校验值(通常为16位或32位)来验证数据的完整性,广泛应用于网络通信、文件存储等领域。

geesehoward20000的博客 717
上一篇: 【排除故障】一次非常诡异的排bug经历...
Li_Boxuan
博客等级 码龄6年 2粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值