输入多项式的系数和指数
p->next=h->next;h->next=p;
继续输入
returnh;
2.voidsort(dnode*h)//采用冒泡法对链表每一项重新排序//
while(p->next!
=NULL)
p=p->next;//寻找尾结点
pi=p;指向最后一次交换的位置,初值为表尾
while(pi!
=h->next)//外层循环,比较趟数
for(p=h->next;p!
=pi;p=p->next)
内层循环,前后两两相比
swap(p,q);pl=p;//调用交换函数
pi=pl;
3.dnode*operate(dnode*a,dnode*b)//稀疏多项式计算//
while(p&&q)
比较对应两项的指数
x=p->c+q->c;if(fabs(x)<1e-5)
p=p->next;q=q->next;
if(x!
=0)将和链接到新的链表中
elseif(p->e>q->e)p链接到新的链表中,p后移,q不动
elseif(p->ee)p链接到新的链表中,q后移,p不动
++c->c;
if(q!
=NULL)t->next=q;++c->c;
if(p!
=NULL)t->next=p;++c->c;
4.floatqiuzhi(intx,dnode*h)//求多项式在x处的值
if(p==NULL)return0;
while(p)
if(p->e==0)sum+=p->c;
elsesum+=(p->c)*(pow(x,p->e));
p=p->next;
returnsum;
【详细设计】
源代码如下:
#include
#include
#include
#defineNULL0
typedefstructnode/*定义多项式每一项*/
{
inte;//e为指数
floatc;//c为系数
structnode*next;//next指向下一项
}dnode;
dnode*creat()/*用链表存放多项式*/
{//多项式的创建,即输入两个多项式
dnode*h,*p;
inte,i,n;//n为多项式的项数
floatc;//c为多项式的系数
h=(dnode*)malloc(sizeof(dnode));//分配头节点
h->next=NULL;
do//当n为0或小于1时,则重新输入
{
printf("请输入多项式的项数n:
");
scanf("%d",&n);
}while(n<1);
for(i=1;i<=n;i++)//输入各项的系数c和指数e
{
printf("请输入第%d项的系数c和指数e:
",i);
scanf("%f%d",&c,&e);
p=(dnode*)malloc(sizeof(dnode));//创建新结点
p->c=c;p->e=e;//将值传给data域
p->next=h->next;//用头插法建立链表
h->next=p;
}
returnh;//返回头结点
}
voidswap(dnode*p,dnode*q)/*交换p,q指针所指的指数和系数*/
{
floatm;//中间变量
intn;//中间变量
n=p->e;//交换操作
p->e=q->e;
q->e=n;
m=p->c;
p->c=q->c;
q->c=m;
}
voidsort(dnode*h)/*采用冒泡法对链表每一项重新排序*/
{
dnode*pi,*pl,*p,*q;
p=h->next;//p此时指向第一项
while(p->next!
=NULL)
p=p->next;//寻找尾结点
pi=p;//pi指向最后一次交换的位置,初值为表尾
while(pi!
=h->next)//结点数大于1时
{
pl=h->next;//pl为中间变量,起传递地地址的作用
for(p=h->next;p!
=pi;p=p->next)
{
q=p->next;
if(p->e>q->e)
{
swap(p,q);//调用交换函数
pl=p;
}
}
pi=pl;//pi指向前一个结点
}
}
dnode*operate(dnode*a,dnode*b)/*稀疏多项式计算*/
{
intsel;
floatx;
dnode*p1,*p2,*p,*t;//t为结果链表的表头
t=(dnode*)malloc(sizeof(dnode));
t->next=NULL;
printf("--------------------------------------\n");
printf("|请选择运算方式:
|\n");
printf("|1、多项式相加|\n");
printf("|2、多项式相减|\n");
printf("|0、退出!
|\n");
printf("--------------------------------------\n");
printf("请选择:
");
scanf("%d",&sel);
p1=a->next;
p2=b->next;
while(p1&&p2)
{
if(p1->e==p2->e)//指数相同
{
if(sel==1)
x=p1->c+p2->c;//系数相加
else
x=p1->c-p2->c;//系数相减
if(x!
=0)
{
p=(dnode*)malloc(sizeof(dnode));
p->e=p1->e;
p->c=x;
p->next=t->next;//利用头插法将p结点插入t中
t->next=p;
}
p1=p1->next;
p2=p2->next;
}
elseif(p1->e>p2->e)//p1的指数大于p2的指数
{
p=(dnode*)malloc(sizeof(dnode));
p->e=p2->e;
if(sel==1)
p->c=p2->c;
else
p->c=(-1)*p2->c;
p->next=t->next;
t->next=p;
p2=p2->next;
}
else//p1的指数小于p2的指数
{
p=(dnode*)malloc(sizeof(dnode));
p->e=p1->e;
p->c=p1->c;
p->next=t->next;
t->next=p;
p1=p1->next;
}
}
while(p1!
=NULL)//p2为空,p1不为空时
{
p=(dnode*)malloc(sizeof(dnode));
p=p1;
p1=p1->next;
p->next=t->next;//把p1放在结果链表后面
t->next=p;
}
while(p2!
=NULL)//p1为空,p2不为空时
{
p=(dnode*)malloc(sizeof(dnode));
p->e=p2->e;
if(sel==2)//如果选择的是2,则将p2中剩余的项的系数取其相反数
p->c=(-1)*p2->c;
else
p->c=p2->c;
p2=p2->next;
p->next=t->next;//把p1放在结果链表后面
t->next=p;
}
returnt;//返回运算后的多项式的头结点
}
voidprn(dnode*h)//打印结果
{
dnode*p;
p=h->next;
if(p==NULL)//如果多项式项数为0
{
printf("多项式项数为0,退出!
\n");
exit(0);
}
printf("生成的多项式如下:
\n");
while((p->next)!
=NULL)//否则,则输出
{
printf("%3.1fX^%d+",p->c,p->e);
p=p->next;
}
if(p->next==NULL)
{
printf("%3.1fX^%d\n",p->c,p->e);
}
}
floatqiuzhi(intx,dnode*h)//求多项式在x处的值
{
dnode*p;
floatsum=0;
inti,t;
printf("请输入x的值:
");
scanf("%d",&x);
for(p=h->next;p;p=p->next)
{
t=1;
for(i=p->e;i!
=0;)
{
if(i<0){t/=x;i++;}//指数小于0,进行除法
else{t*=x;i--;}//指数小于0,进行除法
}
sum+=p->c*t;
}
returnsum;
}
voidmain()
{
intx;
floatsum=0;
dnode*a,*b,*c;
a=creat();//第一个多项式
sort(a);//排序
prn(a);//打印结果
b=creat();//第二个多项式
sort(b);//排序
prn(b);//打印结果
c=operate(a,b);//结果多项式
prn(c);//打印
sum=qiuzhi(x,c);
printf("多项式的值为:
%.3f",sum);
printf("\n");
}
【运行结果及分析】
(1)输入多项式:
(2)输出多项式(多项式格式为:
c1x^e1+c2x^e2+…+cnx^en):
(3)实现多项式a和b相加:
(4)实现多项式a和b相减:
(5)计算多项式在x处的值:
2、模拟浏览器操作程序
【实验内容】
模拟浏览器操作程序
【问题描述】
标准Web浏览器具有在最近访问的网页间后退和前进的功能。
实现这些功能的一个方法是:
使用两个栈,追踪可以后退和前进而能够到达的网页。
在本题中,要求模拟实现这一功能。
【需求分析】
需要支持以下指令:
BACK:
将当前页推到“前进栈”的顶部。
取出“后退栈”中顶端的页面,使它成为当前页。
若“后退栈”是空的,忽略该命令。
FORWARD:
将当前页推到“后退栈”的顶部。
取出“前进栈”中顶部的页面,使它成为当前页。
如果“前进栈”是空的,忽略该命令。
VISIT:
将当前页推到“后退栈”的顶部。
使URL特指当前页。
清空“前进栈”。
QUIT:
退出浏览器。
假设浏览器首先加载的网页URL是:
http:
//www.acm.org/。
【概要设计】
-=ADT=-
{
typedefstructstacknode
voidpush(stacknode*top,stringe)//进栈
stringpop(stacknode*top)//出栈
voidInitStack(stacknode*top)//栈的初始化
intgetempty(stacknode*top)
intmain()
}
【存储结构】
typedefstructstacknode
{
chardata[70];
structstacknode*next;
}stacknode;
【流程图】
【详细设计】
源代码如下:
#include//C++文件输入输出流
#include//字符串操作
#include//C++标准输入输出
#include//实现将char[]转换成string的功能头文件
usingnamespacestd;
typedefstructstacknode
{
chardata[70];
structstacknode*next;
}stacknode;
voidpush(stacknode*top,stringe)//进栈
{
stacknode*q;
q=(stacknode*)malloc(sizeof(stacknode));
strcpy(q->data,e.c_str());//e.c_str()库函数实现将string类型的e转换成char[]类型
q->next=top->next;//strcpy库函数实现将转换后的e.str()复制到q->data中
top->next=q;
}
stringpop(stacknode*top)//出栈
{
stacknode*p;
chare[70];
if(top->next==NULL)
{
returnNULL;
}
else
{
p=top->next;
top->next=p->next;
strcpy(e,p->data);
free(p);
strstreams;//将char[]类型的e转换成string类型的a,s是strstream的对象
s<stringa;
s>>a;
returna;
}
}
voidInitStack(stacknode*top)//栈的初始化
{
top->next=NULL;//初始化为一个带有头结点的链栈,头结点的数据域没有值
}
intgetempty(stacknode*top)//判断栈是否为空
{
if(top->next==NULL)
return1;
else
return0;
}
intmain()
{
stacknode*fls,*bls;//fls指向前进栈,bls指向后退栈
fls=(stacknode*)malloc(sizeof(stacknode));//分别开辟结点
bls=(stacknode*)malloc(sizeof(stacknode));
InitStack(fls);//分别初始化
InitStack(bls);//用C++读取文件,代码比C语言要简单方便很多,但是效率稍低
ifstreamfin("input.txt");//C++的文件输入流,从硬盘读到内存,fin是自己定义的名字,可以随便更改成别的名字
ofstreamfout("output.txt");//C++的文件输出流,从内存写到硬盘,fout也是自己定义的名字,可以随便更改成别的名字
stringURL="http:
//www.acm.org/";//将初始加载的网页赋值给URL,是string类型
stringdemand;/*关于为何使用string的说明:
*/
cout<<"程序从input.txt文件读取测试数据"<cout<<"测试输出保存在output.txt文件中"<while(!
fin.eof())//如果没有读取到文件结尾,则执行循环
{
fin>>demand;//先将第一个字符串读取到string类型的demand变量中,fin读取会忽略空格,遇空格停止
if(demand=="VISIT")//如果读到VISIT则执行题目要求的相应操作
{
push(bls,URL);//将当前页推到后退栈
fin>>URL;//将当前页推到后退栈后,接着读取VISIT后面的网址
fout<InitStack(fls);//清空前进栈
}
if(demand=="BACK")//如果独到BACK
{
if(getempty(bls))//判断后退栈如果为空则输出Ignored到文件中
{
fout<<"Ignored"<continue;//Ignored说明忽略这条命令,则结束本次循环
}
push(fls,URL);//否则将当前页推到前进栈
URL=pop(bls);//取出后退栈中顶端的页面,使它成为当前页
fout<}
if(demand=="FORWARD")//如果独到FORWARD
{
if(getempty(fls))//如果前进栈是空的,则输出Ignored到文件中
{
fout<<"Ignored"<continue;//Ignored说明忽略这条命令,则结束本次循环
}
push(bls,URL);//否则将当前页推到后退栈
URL=pop(fls);//取出前进栈中顶端的页面,使它成为当前页
fout<}
if(demand=="QUIT")//如果读到QUIT,则退出程序
exit
(1);
}
return0;
}
【运行结果及分析】
(1)运行程序界面:
(2)input与output文件截图:
3、背包问题的求解
【实验内容】
背包问题的求解。
【问题描述】
假设有一个能装入总体积为T的背包和n件体积分别为w1,w2,…wn的物品,能否从n件物品中挑选若干件恰好装满背包,即使w1+w2+…+wm=T,要求找出所有满足上述条件的解。
例如:
当T=10,各件物品的体积{1,8,4,3,5,2}时,可找到下列4组解:
(1,4,3,2)
(1,4,5)
(8,2)
(3,5,2)。
【概要设计】
可利用回溯法的设计思想来解决背包问题。
首先,将物品排成一列,然后,顺序选取物品装入背包,若已选取第i件物品后未满,则继续选取第i+1件,若该件物品“太大”不能装入,则弃之,继续选取下一件,直至背包装满为止。
如果在剩余的物品中找不到合适的物品以填满背包,则说明“刚刚”装入的物品“不合适”,应将它取出“弃之一边”,继续再从“它之后”的物品中选取,如此重复,直到求得满足条件的解,或者无解。
由于回溯求解的规则是“后进先出”,自然要用到“栈”。
【存储结构】
structstacks//定义一个顺序栈结构
{
intdata[size];
inttop;
}stack;
【流程图】
【详细设计】
源代码如下:
#include
#definesize100
structstacks//定义一个顺序栈结构
{
intdata[size];
inttop;
}stack;
voidbag(intV,intw[size],intnumber)//向背包中装入物品
{
inti=0,j=1,k=0,c=0;//c为背包装满与否的标志
stack.top=0;//将顺序栈置空
do
{
while(V>0&&k<=number)
{
if(V>=w[k])
{
stack.data[stack.top]=k;//将符合条件的物品的下标入栈
stack.top++;//栈顶元素的位置后移
V-=w[k];//计算背包的剩余体积
}
k++;
}