实验4 栈与字符串
1、利用顺序栈结构,编写算法函数void Dto16(unsigned int m)实现十进制无符号整数m到十六进制数的转换功能。
#include "seqstack.h"
void Dto16(int m)
{ seqstack s;
init(&s);
printf("十进制数%u对应的十六进制数是:",m);
while (m)
{
push(&s,m%16);
m/=16;
}
while (!empty(&s))
putchar( read(&s)<10? pop(&s)+48: pop(&s)+55 );
printf("\n");
}
int main()
{ int m;
printf("请输入待转换的十进制数:\n");
scanf("%u",&m);
Dto16(m);
return 0;
}
2、利用链式栈结构,编写算法函数void Dto16(unsigned int m)实现十进制无符号整数m到十六进制数的转换功能。
#include "linkstack.h"
void Dto16(unsigned int m)
{
linkstack s;
s=init();
printf("十进制数%u对应的十六进制数是:",m);
while (m)
{
s=push(s,m%16);
m/=16;
}
while (!empty(s))
{
printf("%x", read(s));
s=pop(s);
}
printf("\n");
}
int main()
{
unsigned int m;
printf("请输入待转换的十进制数:\n");
scanf("%u",&m);
Dto16(m);
return 0;
}
3、利用字符顺序栈,设计并实现算术表达式求值的程序。
#include
#include "stack.h"
int is_op(char op)
{
switch(op)
{ case '+':
case '-':
case '*':
case '/':return 1;
default:return 0;
}
}
int priority(char op)
{
switch(op)
{
case '(':return 0;
case '+':
case '-':return 1;
case '*':
case '/':return 2;
default: return -1;
}
}
void postfix(char e[],char f[])
{seqstack opst;
int i,j;
initstack(&opst);
push(&opst,'\0');
i=j=0;
while (e[i]!='\0')
{ if ((e[i]>='0' && e[i]<='9') || e[i]=='.')
f[j++]=e[i];
else if (e[i]=='(')
push(&opst,e[i]);
else if (e[i]==')')
{ while (stacktop(&opst)!='(')
f[j++]=pop(&opst);
pop(&opst);
}
else if (is_op(e[i]))
{f[j++]=' ';
while (priority(stacktop(&opst))>=priority(e[i]))
f[j++]=pop(&opst);
push(&opst,e[i]);
}
i++;
}
while (!stackempty(&opst))
f[j++]=pop(&opst);
f[j]='\0';
}
float readnumber(char f[],int *i)
{float x=0.0;
int k=0;
while (f[*i]>='0' && f[*i]<='9')
{
x=x*10+(f[*i]-'0');
(*i)++;
}
if (f[*i]=='.')
{ (*i)++;
while (f[*i]>='0' && f[*i]<='9')
{ x=x*10+(f[*i]-'0');
(*i)++;
k++;
}
}
while (k!=0)
{ x=x/10.0;
k=k-1;
}
printf("\n*%f*",x);
return(x);
}
double evalpost(char f[])
{ double obst[50];
int i=0,top=-1;
double x;
while (f[i]!='\0')
{
if (f[i]>='0' && f[i]<='9')
obst[++top]=readnumber(f,&i);
else if (f[i]==' ') i++;
else if (f[i]=='+')
{ x=obst[top--];
obst[top]=x+obst[top];
i++;
}
else if (f[i]=='-')
{ x=obst[top--];
obst[top]=obst[top]-x;
i++;
}
else if (f[i]=='*')
{ x=obst[top--];
obst[top]=obst[top]*x;
i++;
}
else if (f[i]=='/')
{ x=obst[top--];
obst[top]=obst[top]/x;
i++;
}
}
return obst[top];
}
int main()
{
char e[50],f[50];
int i,j;
printf("\n\n请输入中缀表达式:\n");
gets(e);
postfix(e,f);
i=0;
printf("\n\n对应的后缀表达式为: [");
while (f[i]!='\0')
printf("%c",f[i++]);
printf("]");
printf("\n\n计算结果为 :");
printf("\n\n%f",evalpost(f));
return 0;
}
4、已知字符串采用带结点的链式存储结构(详见linksrting.h文件),请编写函数linkstring substring(linkstring s,int i,int len),在字符串s中从第i个位置起取长度为len的子串,函数返回子串链表。
#include "linkstring.h"
linkstring substring(linkstring s, int i, int len)
{
linkstring head,r,q,p;
int k=1;
head=r=(linkstring)malloc(sizeof(linknode));
r->next=NULL;
p=s->next;
while (p && k<i)
{
p=p->next;
k++;
}
if (!p) return head;
else
{
k=1;
while (p && k<=len)
{
q=(linkstring)malloc(sizeof(linknode));
q->data=p->data;
r->next=q;
r=q;
p=p->next;
k++;
}
r->next=NULL;
return head;
}
}
int main()
{ linkstring str1,str2;
str1=creat();
print(str1);
str2=substring(str1,3,5);
print(str2);
delList(str1);
delList(str2);
return 0;
}
5、字符串采用带头结点的链表存储,设计算法函数void delstring(linkstring s, int i,int len) 在字符串s中删除从第i个位置开始,长度为len的子串。
#include "linkstring.h"
void delstring(linkstring s, int i, int len)
{
linkstring p,q;
int k=1;
p=s->next;
while (p && k<i-1)
{
p=p->next;
k++;
}
if (!p || !p->next) return ;
else
{
k=0;
while (p->next && k<len)
{
q=p->next;
p->next=q->next;
free(q);
k++;
}
}
}
int main()
{ linkstring str;
str=creat();
print(str);
delstring(str,2,3);
print(str);
delList(str);
return 0;
}
6、字符串采用带头结点的链表存储,编写函数linkstring index(linkstring s, linkstring t),查找子串t在主串s中第一次出现的位置,若匹配不成功,则返回NULL。
#include "linkstring.h"
linkstring index(linkstring s, linkstring t)
{
linkstring p,s1,t1;
p=s->next;
while (p)
{
s1=p;
t1=t->next;
while (s1 && t1 && s1->data==t1->data)
{
s1=s1->next;
t1=t1->next;
}
if (t1==NULL) return p;
p=p->next;
}
return NULL;
}
int main()
{ linkstring s,t,p=NULL;
s=creat();
t=creat();
print(s);
print(t);
p=index(s,t);
if(p)
printf("匹配成功,首次匹配成功的位置结点值为%c\n",p->data);
else
printf("匹配不成功!\n");
delList(s);
delList(t);
return 0;
}
7、利用朴素模式匹配算法,将模式t在主串s中所有出现的位置存储在带头结点的单链表中。
#include
#include
#include
typedef struct node
{ int data;
struct node *next;
}linknode;
typedef linknode *linklist;
int index(char *s,char *t)
{ int i,k,j;
int n,m;
n=strlen(s);
m=strlen(t);
for (i=0;i<n-m+1;i++)
{
k=i;
j=0;
while (j<m)
{
if (s[k]==t[j]) {k++;j++;}
else
break;
}
if (j==m) return i;
}
return -1;
}
linklist indexall(char *s,char *t)
{
linklist head,r,p;
int i,k,j;
int n,m;
n=strlen(s);
m=strlen(t);
head=r=(linklist)malloc(sizeof(linknode));
for (i=0;i<n-m+1;i++)
{
k=i;
j=0;
while (j<m)
{
if (s[k]==t[j]) {k++;j++;}
else
break;
}
if (j==m)
{
p=(linklist)malloc(sizeof(linknode));
p->data=i;
r->next=p;
r=p;
}
}
r->next=NULL;
return head;
}
void print(linklist head)
{ linklist p;
p=head->next;
while(p)
{ printf("%5d",p->data);
p=p->next;
}
printf("\n");
}
int main()
{ char s[80],t[80];
linklist head;
printf("请输入主串:\n");
gets(s);
printf("请输入模式串:\n");
gets(t);
int k=index(s,t);
printf("k=%d",k);
head=indexall(s,t);
printf("\n[ %s ]在[ %s ]中的位置有:\n",t,s);
print(head);
return 0;
}
8、编写快速模式匹配KMP算法,请将相关函数补充完整。
#define maxsize 100
typedef struct{
char str[maxsize];
int length ;
} seqstring;
void getnext(seqstring p,int next[])
{
int i,j;
next[0]=-1;
i=0;j=-1;
while(i<p.length)
{
if(j==-1||p.str[i]==p.str[j])
{++i;++j;next[i]=j;}
else
j=next[j];
}
for(i=0;i<p.length;i++)
printf("%d",next[i]);
}
int kmp(seqstring t,seqstring p,int next[])
{
int i,j;
i=0;j=0;
while (i<t.length && j<p.length)
{
if(j==-1||t.str[i]==p.str[j])
{i++; j++;}
else j=next[j];
}
if (j==p.length) return (i-p.length);
else return(-1);
}
int main()
{ seqstring t, p;
int next[maxsize],pos;
printf("请输入主串:\n");
gets(t.str);
t.length=strlen(t.str);
printf("请输入模式串:\n");
gets(p.str);
p.length=strlen(p.str);
getnext(p,next);
pos=kmp(t,p,next);
printf("\n");
printf("%d",pos);
return 0;
}