实习一:1、编写一个读入一个字符串,把它存入一个链表,并按相反的次序打印的程序。
2、设有一个单位的人员工资有如下信息:name、department、 base pay、allowance、total。
现从键盘输入一组人员工资数据并将它们存储到名为paydata的文件中;再从paydata取出工资数据并给每个人的base pay增加100元,增加后将工资数据显示于屏幕(每行1人)。
请编写能够完成上述工作的程序。
代码如下:1.#include <stdio.h>#include <string.h>#include <malloc.h>void main(){char x;struct node //定义个结构node{char c;struct node *next;};struct node *head,*pb,*pf,*p,*s,*t; //定义指针printf("请输入字符串,按Enter结束!\n");for(int i=0;x!='\n';i++){pb=(struct node *)malloc(sizeof(struct node));//动态分配n字节的内存空间scanf("%c",&pb->c); //输入字符x=pb->c;if(i==0){ //输入的首个字符作为头结点pfhead=pb;pf=head;}else if(pb->c!='\n'){ //如果输入的是Enter,输入终止,否则把字符依次存入链表pf->next=pb; //把输入的字符pb存在pf后,pb后为空pb->next=NULL;pf=pb;//pb赋给pf,重复上述操作p=head;}}for(;p!=NULL;p=p->next)s=p; //把指向链表的最后一个字符的指针赋给sprintf("输出结果为:\n");printf("%c",s->c);//输出链表的最后一个字符for(p=head;s!=head;)//若s==head,该链表只有一个字符。
重置p为头结点{for(p=head;p!=s;p=p->next)t=p;s=t;printf("%c",t->c);}printf("\n");}2.#include<stdio.h>#include<string.h>#include <malloc.h>//#define SIZE 4void main(){ struct Worker{ //定义链表结构char name[40];char department[40];int basepay;int allowance;int total;struct Worker *next;}; struct Worker *p;////定义链表头指针,全局变量struct Worker worker[4];p=(struct Worker *)malloc(sizeof(struct Worker));//为链表头结点分配内存int i;FILE *fp;if((fp=fopen("paydata.txt","wb"))==NULL){ printf("cannot open file\n");return;}printf("请输入员工的姓名,部门,底薪,津贴\n");for(i=0;i<4;i++){scanf("%s%s",&worker[i].name,&worker[i].department);scanf("%d%d",&worker[i].basepay,&worker[i].allowance);struct Worker *pb;pb=&worker[i];struct Worker *head;if(i==0){head=pb;p=head;}else {p->next=pb;pb->next=NULL;p=pb;}} for(i=0;i<4;i++)if(fwrite(&worker[i],sizeof(struct Worker),1,fp)!=1)printf("file write error\n");fclose(fp);fp=fopen("paydata.txt","rb");printf("姓名部门底薪津贴总工资\n");for(i=0;i<4;i++){ fread(&worker[i],sizeof(struct Worker),1,fp);printf("%2s%6s%6d%6d%6d",worker[i].name,worker[i].department,worker[i ].basepay+100,worker[i].allowance,worker[i].allowance+worker[i].basepay+100) ;printf("\n");}fclose(fp);}实习二:试分别用线性表的向量存储结构和链表存储结构来实现约瑟夫(Josephu)问题。
约瑟夫问题如下:设有n个人围坐圆桌周围。
从某个位置上的人开始从1报数,数到m的人便出列,下一个人(第m+1个)又从1报数开始,数到m的人便是第2个出列的人,依次类推,直到最后一个人出列为止,这样就可以得到一个人员排列的新次序。
例如,n=8,m=4,从第1个人数起,得到的新次序为48521376.代码如下:链表存储结构:#include<stdio.h>#include<string.h>#include<malloc.h>void main(){ struct Jonse{int code;struct Jonse *next;};struct Jonse *head,*p,*pb,*pf,*ph;p=(struct Jonse *)malloc(sizeof(struct Jonse));int i,n;printf("请输入人数:");scanf("%d",&n);p->code=1;head=p;for(i=2;i<=n;i++){//给每个人赋数,形成环链表pb=(struct Jonse *)malloc(sizeof(struct Jonse));pb->code=i;p->next=pb;pb->next=head;p=pb;}pf=head;int k,m;printf("从第k个位置开始报数,输入k:");scanf("%d",&k);for(i=1;i<=k-1;i++){pf=pf->next;}printf("数到m的人便出列,输入m:");scanf("%d",&m);printf("得到的新次序为:");for(int t=n;t>0;t--){for(int j=1;j<m-1;j++){pf=pf->next;}ph=pf->next;pf->next=pf->next->next;//删除结点printf("%d",ph->code);pf=pf->next;}printf("\n");}向量存储结构:#include<stdio.h>void main(){int a[50],i,g,t,jm,m1,k,m,j;//数组a的长度最好大于8;数小容易出错!for(i=1;i<=8;i++)a[i]=i;printf("数到便m1出列,请输入m1:");scanf("%d",&m1);g=m1;printf("从第K个人开始数:");scanf("%d",&k);m=m1+k-1;printf("新的次序为:");for( t=8;t>0;t--){loop: if(m>t){m=m-t;goto loop;}if(t==1) m=1;printf("%d",a[m]);for(j=m;j<t;j++){a[i]=a[i+1];}m=m+g-1;}printf("\n");}实习三:试编写一程序,实现KMP算法,输入三组主串S和模式串P,输出模式串的Next(j)函数值,以及该P在S中的位置的定位函数值,即序号值。
其中S的长度为15~25,P的长度为5~8。
代码如下:#include<stdio.h>void main(){char p[10];printf("请输入模式串,为6个字符:");scanf("%s",p);int i=0;int k=-1;int next[6];int m=next[0]=-1;//初始化为-1;while(i<6){while(k>=0&&p[i]!=p[k])k=next[k];i++;k++;if(p[i]==p[k])next[i]=next[k];else next[i]=k;}printf("NEXT值:");for(i=0;i<6;i++){printf("%2d",next[i]);}int j=0;loop: while(j<3){printf("\n");printf("输入目标串:");char t[25];scanf("%s",t);int x=0;int y=0;while(x<6&&y<25){ //反复比较字符,开始匹配if(x==-1||t[y]==p[x]){x++;y++;}else x=next[x];}printf("p在t中的序号为:");if((y-x+1)>25)printf("没有相关匹配");else{ printf("%d",y-x+1);}printf("\n");j++;goto loop;}}实习四:采用llink-rlink方式存储二叉排序树,编写能够通过键盘输入建立二叉排序树,并在建立完立即在屏幕显示中序遍历结果的程序。