一元多项式相加减、原数组上逆置、原字符串删除并插入新字符串、回文(C语言)

1.一元多项式相加减

(1)建立多项式:存储系数和指数,尾插法创建链表,以系数为0结束,并约定建立的一元多项式链表指数总是按指数从小到大的顺序排列

(2)输出多项式:从第一个元素开始,逐项读出系数和指数,按多项式的形式输出。第一项不带正负号;X的系数为正负1时,只有指数也为1时,输出系数即可,指数不为1时,直接输出指数部分

(3)两个多项式相加:指数相同才加系数,不同时将指数小的排在前面,一个多项式完了之后,将另一个直接接在后面即可

(4)两个多项式相减:将减数的系数变负,然后相加即可

(5)代码:

#include<stdio.h>

#include<stdlib.h>

typedef struct ddd

{

//链表数据域为系数coef和指数expn

int coef;

int expn;

struct ddd *next;

}Polynomial, *Polyn;

Polyn CreatePoly()

{

    //尾插法创建多项式链表

Polynomial *head,*rear,*s;

int c,e;

head=(Polynomial *)malloc(sizeof(Polynomial));

rear=head;

scanf("%d,%d",&c,&e);

while(c!=0)

{

    s=(Polynomial *)malloc(sizeof(Polynomial));

    s->coef=c;

    s->expn=e;

    rear->next=s;

    rear=s;

    scanf("%d,%d",&c,&e);

}

rear->next=NULL;

return(head);

}

void PrintPolyn(Polyn P)

{

//多项式输出

Polyn q=P->next;

int flag=1;

if(!q)

{

    putchar('0');

    printf("\n");

    return;

}

while(q)

{

    if(q->coef>0&&flag!=1)

        putchar('+');//系数大于0并且不是多项式的第一项时,输出"+"

    if(q->coef!=1&&q->coef!=-1)

    {

        //系数不是正负1时,输出系数

        printf("%d",q->coef);

        if(q->expn==1)

            putchar('X');//指数为1,输出X

        else if(q->expn)

            printf("X^%d",q->expn);//指数不为1,输出X^指数

    }

        else

        {

            if(q->coef==1)

            {

               if(!q->expn)

                   putchar('1');//系数1,指数0,输出1

               else if(q->expn==1)

                   putchar('X');//系数1,指数1,输出X

               else

               printf("X^%d",q->expn);

        }

            if(q->coef==-1)

        {

           if(!q->expn)

               printf("-1");//系数-1,指数0,输出-1 

           else if(q->expn==1)

               printf("-X");//系数1,指数1,输出X

           else

              printf("-X^%d",q->expn);

        }   

                   

    }     

        q=q->next;

    flag++;       

}

printf("\n");

}

Polyn AddPolyn(Polyn pa,Polyn pb)

{

Polyn qa=pa->next;

Polyn qb=pb->next;

Polyn headc,pc,qc;

pc=(Polynomial *)malloc(sizeof(Polynomial));

pc->next=NULL;

headc=pc;

while(qa!=NULL&&qb!=NULL)

{

    qc=(Polynomial *)malloc(sizeof(Polynomial));

    if(qa->expn<qb->expn)

    {

        //qa指数小,直接存入qc,qa后移

       qc->coef=qa->coef;

        qc->expn=qa->expn;

        qa=qa->next;

    }

    else if(qa->expn==qb->expn)

    {

        //指数相等时,系数相加,存入qc

        qc->coef=qa->coef+qb->coef;

        qc->expn=qa->expn;

        qa=qa->next;

        qb=qb->next;

    }

    else

    {

        //qb指数小,直接存入qc,qb后移

        qc->coef=qb->coef;

        qc->expn=qb->expn;

        qb=qb->next;

    }

    if(qc->coef!=0)

    {

        qc->next=pc->next;

        pc->next=qc;

        pc=qc;

    }

    else

        free(qc);

}

while(qa!=NULL)

    {

        //当qa没完时,直接将qa接到qc的后面

        qc=(Polynomial *)malloc(sizeof(Polynomial));

        qc->coef=qa->coef;

        qc->expn=qa->expn;

        qa=qa->next;

        qc->next=pc->next;

        pc->next=qc;

        pc=qc;

}

while(qb!=NULL)

{

    qc=(Polynomial *)malloc(sizeof(Polynomial));

    qc->coef=qb->coef;

    qc->expn=qb->expn;

    qb=qb->next;

    qc->next=pc->next;

    pc->next=qc;

    pc=qc;

}

return headc;

}

Polyn SubtractPolyn(Polyn pa,Polyn pb)

{

//减法是将减数系数变为-,再相加

Polyn h = pb;

Polyn p = pb->next;

Polyn pd;

while(p)

{

    p->coef *= -1;

    p = p->next;

}

pd = AddPolyn(pa,h);

for(p = h->next;p;p = p->next)

    p->coef *= -1;

return pd;

}

int main()

{

Polyn muil_a,muil_b,muil_c,muil_d;

printf("输入第一组多项式:\n");

muil_a=CreatePoly();

printf("输入第二组多项式:\n");

muil_b=CreatePoly();

printf("两个多项式相加为:\n");

muil_c=AddPolyn(muil_a,muil_b);

PrintPolyn(muil_c);

printf("两个多项式相减为:\n");

muil_d=SubtractPolyn(muil_a,muil_b);

PrintPolyn(muil_d);

return 0;

}

(6)运行结果截图:

2.设有一线性表e=(e1,e2,…,en-1,en),其逆线性表定义为e‘=(en,en-1,…,e2,e1)。请设计一个算法,将线性表逆置,要求逆线性表仍占用原线性表的空间,并且用顺序表和单链表两种方法来表示,写出不同的处理函数。

(1)数组实现逆置:循环一半,交换前后数据

(2)代码:

#include <stdio.h>

#define MAXSIZE 50000

int main()

{

    int n,t,i;

    printf("输入数据个数:\n");

    scanf("%d",&n);

    int a[MAXSIZE];

    printf("输入数据:\n");

    for(i=0;i<n-1;i++)

       scanf("%d ",&a[i]);

    scanf("%d",&a[n-1]);

    for(i=0;i<n/2;i++)

    {

       t=a[i];

       a[i]=a[n-1-i];

       a[n-1-i]=t;

    }

    printf("逆置后数组为:\n");

    for(i=0;i<n;i++)

       printf("%d ",a[i]);

    return 0;

}

(3)运行结果:

(4)链表实现逆置:用头插法逆置链表

(5)代码:

#include <stdio.h>

#include <stdlib.h>

typedef struct Node

{

    int data;

    struct Node* next;

}LNode,*Linklist;

Linklist CreatFromTail()

{

    Linklist L;

    LNode *s, *r;

    L=(Linklist)malloc(sizeof(LNode));

    L->next=NULL;

    r=L;

    int x;

    printf("输入数据(-1结束):\n");

    scanf("%d ",&x);

    while(x!=-1)

    {   s=(Linklist)malloc(sizeof(LNode));

       s->data=x;

       r->next=s;

       r=s;

       scanf("%d",&x);  

    }

    r->next=NULL;

    return L;

}

void Reverse(Linklist H)

{

    LNode *p,*q;

    p=H->next;//p指向第一个数据结点

    H->next=NULL;//将原链表置为空表H

    while(p)

    {

       q=p;

       p=p->next;

       q->next=H->next;//将当前结点查到头结点的后面

       H->next=q;

    }

}

void PrintList(Linklist head)

{

    LNode *p,*q;

    p=head;

    printf("逆置后为:\n");

    while(p->next!=NULL)

    {

       p=p->next;

       printf("%d ",p->data);

    }

}

int main()

{

    Linklist a;

    a=CreatFromTail();

    Reverse(a);

    PrintList(a);

}

(6)运行结果:

3.设指针la和lb分别指向两个无头结点单链表中的首元结点,试设计算法,从表la中删除自第i个元素起共len个元素,并将它们插入表lb的第j个元素之后。

(1)思路:遍历la中的元素,记录下i-1的地址p,然后len-1个数据后,再记录地址q,将这部分数据放到c链表,删除这部分数据p->next = q->next.在lb链表遍历后,找到第j-1个元素,将c链表接到j-1地址后。

(2)代码:

#include<stdio.h>

#include<stdlib.h>

typedef struct Node

{

    int data;

    struct Node *next;

}LNode,*Linklist;

void CreatList(Linklist L){

    L = (LNode*)malloc(sizeof(LNode));

    L = NULL;

}//无头结点

void CreateLinkList(Linklist L,int n){

    int i;

    Linklist pre,p;

    printf("首结点数据:");

    L = (LNode*)malloc(sizeof(LNode));

    scanf("%d",L->data);

    pre = L;

    printf("输入剩余%d结点的值\n",n-1);

    for(i = 0;i < n - 1;i++){

       p = (LNode*)malloc(sizeof(LNode));

       scanf("%d",p->data);

       pre->next = p;

       pre = p;

    }

    pre->next = NULL;

}

//遍历链表

void show(Linklist L){

    Linklist p;

    p = L;

    while(p){

       printf("%5d",p->data);

       p = p->next;

    }

    printf("\n");

}

//求链表长度

int ListLength(Linklist L){

    int count;

    Linklist p;

    count = 0;

    p = L;

    while(p){

       count++;

       p = p->next;

    }

    return count;

}

//删除pa中i开始len元素,将删除元素写到pc中

void Operate(Linklist &pa,Linklist &pc,int i,int len)

{

    int j=0,k=0;//j计数至i-1;k计数至len-1

    Linklist p,s,l;

    p = pa;

    while(p->next && j < i - 2){

       j++;

       p = p->next;

    }

    s = p;//记住删除前的位置

    pc = p->next;

    l = pc;

    while(k < len - 1){

       p = p->next;

       l = l->next;

       k++;

    }

    s->next = l->next;//将除了删除的地方连接起来

    l->next = NULL;//终点指向空

    printf("所要删除的链表元素有:\n");

    show(pc);

}

//把pc插入到pb i 元素后

void Operate2(Linklist &pb,Linklist &pc,int i,int len){

    int j;

    Linklist p,m;

    j = 0;

    p = pb;

    while(p && j < i - 1){

       j++;

       p = p->next;

    }

    m = p->next;//记录插入前位置

    p->next = pc;//插入pc

    while(pc->next){

       pc=pc->next;

    }

    pc->next = m;//连接前面

    show(pb);

}

int main(int argc, char *argv[]) {

    int m,n,k;

    Linklist pa,pb,pc;

    CreatList(pa);

    CreatList(pb);

    CreatList(pc);

    CreateLinkList(pa,3);

    CreateLinkList(pb,3);

    printf("链表a:");

    show(pa);

    printf("链表b:");

    show(pb);

    printf("从第几个开始删除");

    scanf("%d",&m);

    printf("删除多少个");

    scanf("%d",&n);

    Operate(pa,pc,m,n);

    printf("a删除后的元素");

    show(pa);

    printf("从b的哪里插入");

    scanf("%d",&k);

    printf("b现在为");

    Operate2(pb,pc,k,n);

    return 0;

}

(3)运行结果:

4.回文是指正读反读均相同的字符序列,如“abba”和“abdba”均是回文,但“good”不是回文。试写一个算法判定给定的字符串是否为回文。

(1)思路:将要待检测的字符串分别放入数组和栈,然后遍历输出比较。因为栈是先进后出,会逆置字符串,和数组输出比较每个字符都相等,则是回文

(2)代码:

#include<stdio.h>

 #include<stdlib.h>

 #include<string.h>

 #define Maxsize 20000

 typedef struct PalindromeQueue     //定义顺序列表结构体

 {

     char LinlistQ[Maxsize];

     int front ;

     int rear ;

 };

 typedef struct PalindromeStack    //定义顺序栈结构体

 {

     char LinklistS[Maxsize];

     int top;

 };

void Init(PalindromeQueue *Q,PalindromeStack *S)     //初始化

 {       

     Q->front=Q->rear=0;

     S->top=-1;  //栈空

 }

void Operate(PalindromeQueue *Q,PalindromeStack *S)

{

    while (S->top != -1 )

    {

       if(Q->LinlistQ[Q->front] != S->LinklistS[S->top])

       {

           printf("该字符序列不是回文序列\n");

           break;

       }

       (S->top)--;

       (Q->front)++;

    }

    if (S->top = -1 && Q->front == Q->rear)

    {  

        printf("该序列式是回文序列\n");   

    }  

}

int main()

{

    int j=0;

    char List[Maxsize];

    PalindromeQueue  M;

    PalindromeStack  N; 

    printf("请输入一段需要判断是否是“回文序列”的字符序列并以'@'字符作为结束标识符\n"); 

    while(1)                           

    {

        scanf("%s",List,sizeof(List));    //sizeof时是一个操作符,可测量变量声明后所占内存数

       break;

    }  

    Init(&M,&N);           //初始化队列和栈

    while(List[j] != '@')

    {

       M.LinlistQ[j]=List[j];       //进入队列

       M.rear++;                   //队尾后移

       N.LinklistS[j]=List[j];    //进栈

       N.top++;

       j++;      

    }  

    Operate(&M,&N);         //判断是否是回文序列

    return 0;

}

(3)运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值