1. 程式人生 > >資料結構實驗4-棧與字串

資料結構實驗4-棧與字串

/*
利用順序棧結構,編寫演算法函式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;
}

轉載請註明