实验一 线性表应用

第1关:一元多项式相加

任务描述

本关任务:设计一种单链表存储结构,每个结点存储一项的系数和指数,类型都是整型,编写完成产生多项式的函数、多项式相加及输出多项式的函数。

相关知识

为了完成本关任务,你需要掌握:

如何存储一个一元多项式;

如何对一元多项式进行加法操作。

存储一元多项式

在数学上,一元多项式的形式:

p
n

(x)=p
0

+p
1

x
1
+p
2

x
2
+…+p
n

x
n

可由线性表(p
0

,p
1

,…p
n

)表示。一般情况下,一元多项式只表示非0系数项,采用链式存储,对应链表结点数据结构可采取:(设多项式的系数和指数都是整型)

struct node
{
int exp; //表示指数
int coef; //表示系数
struct node *next; //指向下一个结点的指针
};
多项式相加运算规则
两个一元多项式中所有指数相同的项,对于系数相加,若和不为0,则构成结果多项式中的一项,对于两个多项式中所有指数不同的项,则分别复制到结果多项式中。

举例:

p(x)=5+2x+3x
5
−2x
7

Q(x)=12x+2x
7
+13x
15

则结果多项式为:

R(x)=5+14x+3x
5
+13x
15

输入输出一元多项式

输入时逐项、按顺序输入一元多项式的系数、指数,输入系数为0时表述输入结束。

例如:

p(x)=5+2x+3x
5
−2x
7

输入: 5 0 2 1 3 5 -2 7 0 0

输出时采取以下格式,若预期输出的多项式为:

p(x)=5+2x+3x
5
−2x
7

则输出:5x^0 + 2x^1 + 3x^5 -2x^7

编程要求

在右侧编辑器补充代码,实现相应函数。

测试说明

平台会对你编写的代码进行测试:

测试输入:

5 0 2 1 3 5 -2 7 0 0
12 1 2 7 13 15 0 0

预期输出:

5x^0 + 14x^1 + 3x^5 + 13x^15

测试输入:

6 -1 5 0 7 9 0 0
-15 -2 9 9 18 12 0 0

预期输出:

-15x^-2 + 6x^-1 + 16x^9 + 18x^12

开始你的任务吧,祝你成功!

第2关:利用单链表实现集合基本运算

任务描述

本关任务:完成单链表基本操作,并使用基本操作实现集合的并、交和差功能。

相关知识

为了完成本关任务,你需要掌握集合是什么。

集合:是一些互不相同元素的无序汇集。

设有集合A、B,集合成员t,则

集合并的定义:C=A∪B={t|t∈A 或 t∈B }

集合交的定义:C=A∩B={t|t∈A 且 t∈B }

集合差的定义:C=A-B={t|t∈A 且 t∉B }

集合的实现

集合的实现方法有多种,其中一种方法是用单链表表示。存储结构可定义如下:

struct Node
{
DataType element;
struct Node *next;
};
假设单链表的头结点不存放集合元素,但头结点的element存放链表中数据元素的个数。

编程要求

在右侧编辑器补充代码,完成单链表基本操作并使用基本操作实现集合的相关操作。

测试说明

平台会对你编写的代码进行测试:

测试输入:

5 91 51 2 32 7
4 21 51 2 16

预期输出:

并集: 16 21 4 5 91 51 2 32 7
交集:51 2
差集:5 91 32 7

测试输入:

2 1 100
4 16 101 1 6

预期输出:

并集: 6 101 16 4 2 1 100
交集:1
差集:2 100

开始你的任务吧,祝你成功!
参考代码:

#ifndef _LINKSET_H_
#define _LINKSET_H_
#include <iostream>
using namespace std;
typedef int DataType;

struct  node
{
    DataType  element;
    struct node  *next;
};
typedef struct node * SET;
void insert(DataType datax, SET set);

/*
  函数名: InitSet
  函数功能:根据参数num,初始化集合
  函数参数:集合元素的个数 
  返回值:集合头指针 
*/
SET InitSet(int num)
{

    SET p;
    p = new struct  node  ;
    p->next = NULL;
    p->element = num;
    int temp;
    for(int i =0;i<num;i++)
    {
        cin>>temp;
        insert(temp, p); //调用insert函数,将输入数据插入集合
    }
    return p; 
}


/*
  函数名: find
  函数功能:在集合中查找值为datax的成员 
  函数参数:datax:待查找的值 ; set:集合的头结点 
  返回值:找到值为datax的成员返回1,否则返回0 
*/
int find(DataType datax, SET  set)
{
    //请在此处填写代码,在set集合中查找值为datax的成员,若找到返回1,否则返回0
    /**********  Begin  **********/
    SET p = set->next;
    while (p != NULL)
    {
        if (p->element == datax)
            return 1;
        p = p->next;
    }
    return 0;


    /**********   End   **********/
}

/*
  函数名: insert
  函数功能:在集合set中插入值为datax的成员 ,插入位置在表头
  函数参数:datax:待插入的值 ; set:集合的头结点
  返回值:无
*/
void insert(DataType datax, SET set)
{
    //请在此处填写代码,将datax插入集合set, 注意因集合元素是无序的,只需将新成员插入表头
    /**********  Begin  **********/
    SET  temp;
    temp = new struct  node;
    temp->element = datax;
    temp->next = set->next;
    set->next = temp;
    /**********   End   **********/
}

/*
  函数名: copyList
  函数功能:将集合setA复制生成集合setB
  函数参数:setA 、setB的头结点
  返回值:无
*/
void copySet(SET setA, SET setB)
{
    //请在此处填写代码,实现将集合setA的成员复制到集合setB的功能
    /**********  Begin  **********/

    setB = setA;
    while (setA != NULL)
    {
        setB = new struct  node;
        setB->element = setA->element;
        setA = setA->next;
    }
    setB->next = NULL;
    /**********   End   **********/
}

/*
  函数名: printSet
  函数功能:输出集合的元素,以空格作为元素之间分界符
  函数参数:set的头结点
  返回值:无
*/
void printSet(SET set)
{
    //请在此处填写代码,实现输出集合元素的功能,元素之间以空格为分界符
    /**********  Begin  **********/
    SET p = set->next;
    while (p != NULL)
    {
    	if(p->element>1000)
    		break;
        printf("%d ", p->element);
        p = p->next;
    }
    /**********  End  **********/
}

/*
  函数名: setUnion
  函数功能:求两个集合setA 和 setB的并集
  函数参数:setA和setB的头结点
  返回值:并集集合的头结点
*/
SET setUnion(SET L1, SET L2)
{
    //请在此处填写代码,可直接使用上面已经实现的各操作
    /**********  Begin  **********/
    SET s = new struct  node;
    s->next = NULL;
	SET p1,p2;
	p1=L1->next;
	p2=L2->next;
	while(p1)
	{
		SET inter =new struct node;//头插法插入 
		inter->element = p1->element;
		inter->next = s->next;
		s->next = inter;
		p1 = p1->next; 
	}
	while(p2)
	{
		p1 = s->next;
		while(p1)
		{
			if(p1->element != p2->element)
			{
				p1 = p1->next;
			}
			else
			{
				break;
			 } 
			
		}
		if(!p1)
		{
			SET inter = new struct node;//头插法插入 
			inter->element = p2->element;
			inter->next = s->next;
			s->next = inter;
		}
		p2 = p2->next;
	}
	return s;
   
    /**********  End  **********/
}

/*
  函数名: setIntersect
  函数功能:求两个集合setA 和 setB的交集
  函数参数:setA和setB的头结点
  返回值:交集集合的头结点
  3 4 5 6
  3 6 7 8
  5 45 44 67  30 89
  4 56 44 34 45
*/


SET setIntersect(SET L1, SET L2)
{
    //请在此处填写代码,可直接使用上面已经实现的各操作
    /**********  Begin  **********/

    
    SET s = new struct  node;
    s->next = NULL;
	SET Lp,Lq;
	Lp=L1->next;
	while(Lp)
	{	Lq = L2->next;
		while(Lq)
		{
			if(Lp->element==Lq->element)
			{
				SET inter = new struct  node;//头插法插入 
				inter->element = Lp->element;
				inter->next = s->next;
				s->next = inter;	
			}
			Lq=Lq->next;
		}
		Lp=Lp->next;
	}
	
	return s;

    /**********  End  **********/
}

/*
  函数名: setExcept
  函数功能:求两个集合setA 和 setB的差
  函数参数:setA和setB的头结点
  返回值:结果集合的头结点
*/
SET setExcept(SET L1, SET L2)
{
    //请在此处填写代码,可直接使用上面已经实现的各操作
    /**********  Begin  **********/
	SET s1,s2,s,p,q;
	s1 = L1;
	s2 = setIntersect(L1,L2);
	p=s1->next;
	while(p)
	{
		q=s2->next;
		while(q)
		{
			if(q->element != p->element)
				q=q->next;
			else
				break;
		}
		if(!q)
		{
			SET inter = new struct node;//头插法插入 
			inter->element = p->element;
			inter->next = s->next;
			s->next = inter;
		}
		p=p->next;
	}
	
    return s;
    /**********  End  **********/
}
      
#endif
实验线性表及其应用 一、 实验目的和要求 1、掌握线性表的插入、删除、查找等基本操作设计与实现 2、学习利用线性表提供的接口去求解实际问题 3、熟悉线性表的的存储方法 二、 实验内容和原理 1、实验内容:设计一个一元多项式的简单计算器,其基本功能有①输入并建立多项式;②输出多项式;③多项式相加。可利用单链表或单循环链表实现之。 2、实验原理:以线性表来描述一元多项式,存储结构采用单链表每个结点存储的多项式中某一项系数指数,建立单链表指数高的结点列于指数低的 结点之后,即线性表的元素按指数递增有序排列。 三、 实验环境 Visual C++ 6.0 及PC机 四、 算法描述及实验步骤 思想算法: 以线性表来描述一元多项式,存储结构采用单链表每个结点存储的多项式中某一项系数指数,建立单链表指数高的结点列于指数低的结点之后,即线性表的元素按指数递增有序排列。 例如构造两个多项式ha: 5X3+4X2+3X+2 hb: X2+X+1 多项式加法:定义指针p,q分别指向ha,hb i.p->exp==q->exp ,r->coef=p->coef+q->coef,pa,pb下移; ii.p->expexp ,r->coef=q->coef;r->exp=q->exp;,q下移 iii.pa->exp>pb->exp, r->exp=p->exp;r->coef=p->coef;,p下移 iv.p!=NULL,pb==NULL.相当于iii. V.q==NULL,pb!=NULL.相当于ii. 其流程图如下: 多项式乘法:定义指针fp,gp分别指向f,g 1.将两多项式最大指数相加并赋于maxp,并置g 2.用for循环求指数等于maxp时相乘的系数 3. (fp!=NULL)&&(gp!=NULL), p=fp->exp+gp->exp 1.p>maxp, fp=fp->next; 2. pnext; 3.p=maxp, x+=fp->coef*gp->coef; fp=fp->next;gp=gp->next; 五、 实验结果 1.分别输入两个多项式: 5X3+4X2+3X+2 和X2+X+1,然后输出结果如下: 2.分别输入两个多项式:6X4+4X2+2和5X+6,然后输出结果如下: 六、 总结 此次上机实验应用线性表实现了一次实际操作,完成了一个一元多项式的简单计算器,不仅对此次译程序的算法思想有了新的认识,还让我深刻的体会到了线性表的重要性以及其应用的方便,并且对指针加深了映象,应用了书本中的算法思想,对我以后的译以及完成新的程序有很大的帮助。 附录: 1.建立多项式列表代码如下: mulpoly *creatpoly()/*建立多项式列表*/ {mulpoly *head,*r,*s;/*设中间变量*/ int m,n; head=(mulpoly *)malloc(sizeof(mulpoly));/*头结点申请空间*/ printf("\ninput coef and exp:\n"); scanf("%d%d",&n,&m);/*输入多项式系数指数*/ r=head;/*尾指针指向头指针*/ while(n!=0)/*将输入的多项式存放在S中*/ {s=(mulpoly*)malloc(sizeof(mulpoly)); s->coef=n; s->exp=m; r->next=s; r=s; /*printf("input coef and exp:\n");*/ scanf("%d%d",&n,&m);/*再次输入多项式系数指数*/ } r->next=NULL;/*将尾指针置空*/ head=head->next;/*将head哑结点向前跑一个结点,使其不为空*/ return (head);/*返回多项式*/ } 2.两个多项式相加代码如下: mulpoly *polyadd(mulpoly *ha,mulpoly *hb)/*两个多项式相加*/ {mulpoly *hc,*p,*q,*s,*r;/*声明结构体型*/ int x; p=ha; q=hb; hc=(mulpoly *)malloc(sizeof(mulpoly));/*申请结点空间*/ s=hc; while((p!=NULL)&&(q!=NULL))/*两多项式不为空*/
C语言中,我们可以设计一个名为`Polynomial`的结构体来表示多项式,其中包含一个整数数组`coefficients`用于存储系数,一个整数`degree`表示多项式的最高次幂。下面是相关的数据结构和函数实现: ```c #include <stdio.h> #include <stdlib.h> // 定义多项式节点 typedef struct { int coefficient; // 系数 int exponent; // 指数 } PolynomialNode; // 定义多项式结构体 typedef struct { PolynomialNode* nodes; int degree; int size; } Polynomial; // 初始化多项式 void initPolynomial(Polynomial* poly) { poly->nodes = (PolynomialNode*)malloc(sizeof(PolynomialNode)); poly->degree = -1; poly->size = 0; } // 添加一个项到多项式 void addTerm(Polynomial* poly, int coefficient, int exponent) { if (poly->degree == exponent) { poly->nodes[poly->size].coefficient *= coefficient; } else if (poly->degree < exponent) { poly->degree = exponent; poly->nodes = realloc(poly->nodes, (poly->size + 1) * sizeof(PolynomialNode)); poly->nodes[poly->size].coefficient = coefficient; poly->nodes[poly->size].exponent = exponent; poly->size++; } else { poly->nodes[poly->size].coefficient += coefficient; } } // 多项式相加 void addPolynomials(Polynomial* result, Polynomial* a, Polynomial* b) { Polynomial temp; initPolynomial(&temp); for (int i = 0; i <= a->degree || i <= b->degree; i++) { int term_a = a->nodes[a->degree >= i ? a->degree : i].coefficient; int term_b = b->nodes[b->degree >= i ? b->degree : i].coefficient; // 加上当前次幂对应的系数 addTerm(&result, term_a + term_b, i); } // 更新结果多项式的度和大小 result->degree = max(result->degree, temp.degree); result->size = temp.size; } // 输出多项式 void printPolynomial(const Polynomial* poly) { for (int i = 0; i <= poly->degree; i++) { if (poly->nodes[i].coefficient != 0) { printf("%d*x^%d + ", poly->nodes[i].coefficient, i); } } printf("0\n"); // 如果最高次幂系数为0,则添加这一项 } int main() { Polynomial p1, p2, sum; initPolynomial(&p1); // 示例多项式1:x^2 + x + 1 initPolynomial(&p2); // 示例多项式2:2x^2 + 3x // 添加项到多项式 addTerm(&p1, 1, 2); addTerm(&p1, 1, 1); addTerm(&p1, 1, 0); addTerm(&p2, 2, 2); addTerm(&p2, 3, 1); // 相加多项式 addPolynomials(&sum, &p1, &p2); // 输出结果 printf("多项式1: "); printPolynomial(&p1); printf("多项式2: "); printPolynomial(&p2); printf("和: "); printPolynomial(&sum); return 0; } ``` 这个程序定义了一个简单的多项式存储结构,并实现了生成、相加和输出多项式的功能。注意这只是一个基本示例,实际应用可能需要处理更复杂的情况,例如合并重复的次幂。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值