資料結構實驗4-棧與字串
阿新 • • 發佈:2019-02-14
/*
利用順序棧結構,編寫演算法函式void Dto16(unsigned int m)實現十進位制無符號整數m到十六進位制數的轉換功能。
*/
/**********************************/
/*檔名稱:lab4_01.c */
/**********************************/
#include "seqstack.h"
/*請將本函式補充完整,並進行測試*/
void Dto16(int m)
{ seqstack s; /*定義順序棧*/
init(&s);
printf("十進位制數%u對應的十六進位制數是:" ,m); //%d 輸出有符號十進位制數 %u 輸出無符號十進位制數
while (m)
{
push(&s,m%16);
m=m/16;
}
while (!empty(&s))
printf("%x",pop(&s));
printf("\n");
}
int main()
{ int m;
printf("請輸入待轉換的十進位制數:\n");
scanf("%u",&m);
Dto16(m);
return 0;
}
/*
利用鏈式棧結構,編寫演算法函式void Dto16(unsigned int m)實現十進位制無符號整數m到十六進位制數的轉換功能。
*/
/**********************************/
/*檔名稱:lab4_02.c */
/**********************************/
#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;
}
#include <stdio.h>
#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;
/*請將本函式補充完整*/
float 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]=x-obst[top];
i++;
}
else if(f[i]=='*')
{
x=obst[top--];
obst[top]=x*obst[top];
i++;
}
else if(f[i]=='/')
{
x=obst[top--];
obst[top]=x/obst[top];
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;
}
/*
已知字串採用帶結點的鏈式儲存結構(詳見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,pos=s->next,makenode,newlist;
int cnt=0;
head=(linkstring)malloc(sizeof(linknode));
head->next=NULL;
newlist=head;
while(pos)
{
if(cnt>=i&&cnt<=i+len-1)
{
makenode=(linkstring)malloc(sizeof(linknode));
makenode->data=pos->data,makenode->next=NULL;
newlist->next=makenode;
newlist=makenode;
}
if(cnt>=i+len)
break;
cnt++;
pos=pos->next;
}
return head;
}
int main()
{ linkstring str1,str2;
str1=creat(); /*建字串連結串列*/
print(str1);
str2=substring(str1,3,5); /*測試,從第3個位置開始取長度為5的子串,請自行構造不同測試用例*/
print(str2); /*輸出子串*/
delList(str1);
delList(str2);
return 0;
}
/*
字串採用帶頭結點的連結串列儲存,設計演算法函式void delstring(linkstring s, int i,int len)
在字串s中刪除從第i個位置開始,長度為len的子串。
*/
/**********************************/
/*檔名稱:lab4_05.c */
/**********************************/
#include "linkstring.h"
/*請將本函式補充完整,並進行測試*/
void delstring(linkstring s, int i, int len)
{
linkstring p,q,r;
int k=1;
p=s->next;
while(k<i&&p) //查詢待刪除子串的起始位置
{
q=p;
p=p->next;
k++;
}
if(!p) //如果s串長度小於i,則無法刪除
return;
else
{
k=1;
while(k<len&&p) //從第i個位置開始查詢待刪除子串的終點
{
p=p->next;
k++;
}
if(!p) //如果s串中i後面的長度小於len,則無法刪除
return ;
else
{
if(!q) //如果待刪除子串位於s最前面
{
r=s;
s=p->next;
}
else //子串位於中間或者後面
{
r=q->next;
q->next=p->next;
}
p->next=NULL; //待刪除子串最後置為空
while(r)
{
p=r;
r=r->next;
free(p); //逐個釋放子串中的結點
}
}
}
}
int main()
{ linkstring str;
str=creat(); /*建字串連結串列*/
print(str);
delstring(str,2,3); /*測試,從第2個位置刪除長度為3的子串,請自行構造不同的測試用例 */
print(str); /*輸出*/
delList(str);
return 0;
}
/*
字串採用帶頭結點的連結串列儲存,編寫函式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) //p記錄匹配的起點
{
s1=p; //s1記錄s比較的當前位置
t1=t->next; //s2記錄t比較的當前位置
while(s1&&t1&&s1->data==t1->data)
{
s1=s1->next;
t1=t1->next;
}
if(!t1) return p; //如果匹配成功,則返回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;
}
/*
利用樸素模式匹配演算法,將模式t在主串s中所有出現的位置儲存在帶頭結點的單鏈表中。
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node
{ int data;
struct node *next;
}linknode;
typedef linknode *linklist;
/*樸素模式匹配演算法,返回t中s中第一次出現的位置,沒找到則返回-1,請將程式補充完整*/
int index(char *s,char *t)
{
int m,n,i,j,k;
m=strlen(s);
n=strlen(t);
for(i=0;i<=m-n;i++)
{
k=i;
j=0;
while(j<n)
{
if(s[k]==t[j])
{
k++;
j++;
}
else
break;
}
if(j==n)
return i;
}
return -1;
}
/*利用樸素模式匹配演算法,將模式t在s中所有出現的位置儲存在帶頭結點的單鏈表中,請將函式補充完整*/
linklist indexall(char *s,char *t)
{
linklist head,p,r;
int m,n,i,j,k;
head=(linklist)malloc(sizeof(linknode));
r=head;
m=strlen(s);
n=strlen(t);
for(i=0;i<=m-n;i++)
{
k=i;
j=0;
while(j<n)
{
if(s[k]==t[j])
{
k++;
j++;
}
else
break;
}
if(j==n)
{
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;
}
/*
編寫快速模式匹配KMP演算法,請將相關函式補充完整。
*/
#define maxsize 100
typedef struct{
char str[maxsize];
int length ;
} seqstring;
/*求模式p的next[]值,請將函式補充完整*/
void getnext(seqstring p,int next[])
{
int i,j;
i=0;j=-1;
next[0]=-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("%3d",next[i]);
}
/*快速模式匹配演算法,請將函式補充完整*/
int kmp(seqstring t,seqstring p,int next[])
{
int 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];
}
return j==p.length?i-p.length:-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;
}
轉載請註明