版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p><b> 電子與信息工程學(xué)院</b></p><p> 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告</p><p> ( 2012——2013年度第一學(xué)期)</p><p> 課程名稱: 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì) </p><p> 題 目 一:6.3“哈夫曼樹”的建立及其應(yīng)用 </p>
2、;<p> 題 目 二: 3.4.6括號(hào)匹配的檢驗(yàn) </p><p> 院 系: 計(jì)算機(jī)科學(xué)系 </p><p> 班 級(jí): </p><p> 姓 名: </p&g
3、t;<p> 學(xué) 號(hào): </p><p> 指導(dǎo)教師: </p><p> 成 績(jī): </p><p> 2012 年 月 日</p><p> 設(shè)計(jì)題目<
4、;一>: 6.3“哈夫曼樹”的建立及其應(yīng)用</p><p><b> 一、設(shè)計(jì)要求</b></p><p><b> 1.問(wèn)題描述</b></p><p> 設(shè)有一段電文由字符集{A,B,C,D,E,F,G,H}組成,各字符在電文中出現(xiàn)的次數(shù)集為{5,29,7,8,14,23,3,11},試設(shè)計(jì)各字符的哈
5、夫曼編碼。</p><p><b> 2.需求分析</b></p><p> ?。?)設(shè)計(jì)哈夫曼樹。具體的構(gòu)造方法如下:以字符集{A,B,C,D,E,F,G,H}作為葉子結(jié)點(diǎn),以各字符出現(xiàn)的次數(shù){5,29,7,8,14,23,3,11}作為各葉子結(jié)點(diǎn)的權(quán)值構(gòu)造一棵哈夫曼樹。</p><p> ?。?)設(shè)計(jì)哈夫曼編碼。按照構(gòu)造出來(lái)的哈夫曼樹,規(guī)
6、定哈夫曼樹的左分支為0,右分支為1,則從根結(jié)點(diǎn)到每個(gè)葉子結(jié)點(diǎn)所經(jīng)過(guò)的分支對(duì)應(yīng)的0和1組成的序列便為該結(jié)點(diǎn)對(duì)應(yīng)字符的哈夫曼編碼。</p><p><b> 二、概要設(shè)計(jì)</b></p><p><b> 1.主界面設(shè)計(jì)</b></p><p> 運(yùn)行界面如圖1所示:</p><p> 圖1哈夫
7、曼編碼主菜單</p><p><b> 2.存儲(chǔ)結(jié)構(gòu)設(shè)計(jì)</b></p><p> 對(duì)于哈夫曼編碼問(wèn)題,希望在構(gòu)造哈夫曼樹的同時(shí)能方便地實(shí)現(xiàn)從雙親結(jié)點(diǎn)到左右孩子結(jié)點(diǎn)的操作,在進(jìn)行哈夫曼編碼時(shí)又要求能方便地實(shí)現(xiàn)從孩子結(jié)點(diǎn)到雙親結(jié)點(diǎn)的操作。因此,本程序選擇樹的雙親孩子表示法作為哈夫曼樹的存儲(chǔ)結(jié)構(gòu),并加入了指示結(jié)點(diǎn)權(quán)值的信息。</p><p>&
8、lt;b> 3.系統(tǒng)功能設(shè)計(jì)</b></p><p> 本程序完成了從哈夫曼樹的構(gòu)造到實(shí)現(xiàn)并輸出哈夫曼編碼的過(guò)程,分別由兩個(gè)子程序完成,其設(shè)計(jì)如下:</p><p> (1)選擇權(quán)值最小的樹。選擇權(quán)值最小的樹由函數(shù)Select()實(shí)現(xiàn)。該功能按照哈夫曼樹的構(gòu)造步驟,在當(dāng)前已構(gòu)成的n(n>=2)棵二叉樹的集合中選取兩棵根結(jié)點(diǎn)權(quán)值最小的樹作為左右子樹構(gòu)造一棵新的二
9、叉樹。</p><p> (2)哈夫曼編碼。哈夫曼編碼由函數(shù)HuffmanCoding( )實(shí)現(xiàn)。該功能首先調(diào)用函數(shù)Select()實(shí)現(xiàn)哈夫曼樹的構(gòu)造,然后從葉子到根逆向根據(jù)哈夫曼編碼的要求,一次求出每個(gè)字符的哈夫曼編碼。</p><p><b> 三、模塊設(shè)計(jì)</b></p><p><b> 1.模塊設(shè)計(jì) </b>
10、;</p><p> 本程序包含3個(gè)模塊:主程序模塊、哈夫曼編碼模塊和選擇模塊。其調(diào)用關(guān)系如圖2所示。</p><p> 圖2 模塊調(diào)用示意圖</p><p> 2.系統(tǒng)子程序及功能設(shè)計(jì)</p><p> 本程序共設(shè)置3個(gè)子程序,各子程序的函數(shù)名及功能說(shuō)明如下。</p><p> (1)void Select
11、(HuffmanTree &HT,int m,int *s1,int *s2)</p><p> //選擇權(quán)值最小的兩個(gè)結(jié)點(diǎn)</p><p> (2)void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n)</p><p><b> //構(gòu)造哈夫曼編碼&
12、lt;/b></p><p> (3)void main( ) //主函數(shù)。輸入結(jié)點(diǎn)個(gè)數(shù)及權(quán)值,調(diào)用哈夫曼編碼模塊函數(shù)</p><p> 3.函數(shù)主要調(diào)用關(guān)系圖 </p><p> 本程序3個(gè)子程序之間的主要調(diào)用關(guān)系如圖3所示。 </p><p> 圖中數(shù)字是各函數(shù)的編號(hào)
13、 </p><p> 圖3系統(tǒng)函數(shù)調(diào)用關(guān)系圖</p><p><b> 四、詳細(xì)設(shè)計(jì)</b></p><p><b> 1.?dāng)?shù)據(jù)類型定義</b></p><p> typedef struct</p><p><b> {</b><
14、/p><p> unsigned int weight; //用來(lái)存放各個(gè)結(jié)點(diǎn)的權(quán)值</p><p> unsigned int parent, lchild, rchild; //指向雙親、孩子結(jié)點(diǎn)的指針</p><p> }HTNode, *HuffmanTree; //
15、動(dòng)態(tài)分配數(shù)組存儲(chǔ)哈夫曼樹</p><p> typedef char * * HuffmanCode; //動(dòng)態(tài)分配數(shù)組存儲(chǔ)哈夫曼編碼表</p><p> 2.系統(tǒng)主要子程序詳細(xì)設(shè)計(jì)</p><p> 哈夫曼編碼模塊設(shè)計(jì)分兩步:首先構(gòu)造哈夫曼樹,然后完成哈夫曼編碼。</p><p> void Huffma
16、nCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n)</p><p> {//w存放n個(gè)字符的權(quán)值(均>0),構(gòu)造哈夫曼樹HT并求出n個(gè)字符的哈夫曼編碼HC</p><p> int i,j,m,s1,s2,start;</p><p><b> char *cd;</
17、b></p><p> unsigned int c,f;</p><p> if (n<=1) return;</p><p> m = 2 * n - 1;</p><p> HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); //0號(hào)單元未用</p>
18、<p> for (i=1;i<=n;i++) //葉子結(jié)點(diǎn)初始化并放入1-n號(hào)單元</p><p><b> {</b></p><p> HT[i].weight=w[i];</p><p> HT[i].parent=0;</p><p> HT[i].lchi
19、ld=0;</p><p> HT[i].rchild=0;</p><p><b> }</b></p><p> for (i=n+1; i<=m;i++) //非葉子結(jié)點(diǎn)初始化</p><p><b> {</b></p><p> HT
20、[i].weight=0;</p><p> HT[i].parent=0;</p><p> HT[i].lchild=0;</p><p> HT[i].rchild=0;</p><p><b> }</b></p><p> printf("\n哈夫曼樹的構(gòu)造過(guò)程如下所
21、示:\n");</p><p> printf("HT初態(tài):\n 結(jié)點(diǎn) weight parent lchild rchild");</p><p> for (i=1;i<=m;i++) //完成構(gòu)造哈夫曼樹算法的第1個(gè)步驟</p><p> printf("\n%4d%8d%8d%8d
22、%8d",i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);</p><p> printf(" 按任意鍵,繼續(xù) ...");</p><p><b> getch();</b></p><p> //創(chuàng)建哈夫曼樹HT</p><
23、;p> for (i=n+1;i<=m;i++)</p><p><b> {</b></p><p> Select (HT,i-1,&s1,&s2); </p><p> //在HT[1..i-1]中選擇parent為0且weight最小的兩個(gè)結(jié)點(diǎn)</p><p> HT[s
24、1].parent=i;HT[s2].parent=i;</p><p> HT[i].lchild=s1;HT[i].rchild=s2;</p><p> //將選取根結(jié)點(diǎn)權(quán)值最小的樹作為左右子樹</p><p> HT[i].weight=HT[s1].weight+HT[s2].weight;</p><p> //置新二叉樹
25、的根結(jié)點(diǎn)權(quán)值為其左、右子樹根結(jié)點(diǎn)之和</p><p> printf("\nselect:s1=%d s2=%d\n",s1,s2);</p><p> //根結(jié)點(diǎn)權(quán)值最小的樹在HT中的位置</p><p> printf(" 結(jié)點(diǎn) weight parent lchild rchild");</p>
26、<p> for (j=1;j<=i;j++)</p><p> //輸出選取根結(jié)點(diǎn)權(quán)值最小樹的過(guò)程</p><p> printf("\n%4d%8d%8d%8d%8d",j,HT[j].weight,HT[j].parent,HT
27、 [j].lchild,HT[j].rchild);</p><p> printf(" 按任意鍵,繼續(xù) ...");</p><p><b> getch();</b></p><p><b> }</b></p><p> printf(&q
28、uot;\n%d個(gè)字符的哈夫曼編碼如下:\n",n);</p><p> //從葉子到根逆向求每個(gè)字符的哈夫曼編碼</p><p> HC=(HuffmanCode)malloc((n+1)*sizeof(char *));//分配n個(gè)編碼的頭指針</p><p> cd = (char * )malloc(n*sizeof(char));
29、 //分配求編碼的工作空間</p><p> cd[n-1] = '\0'; //編碼結(jié)束符</p><p> for (i=1;i<=n;i++) //逐個(gè)字符求哈夫曼編碼</p><p><b> {<
30、/b></p><p> start =n-1; //編碼結(jié)束符位置</p><p> for (c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent) </p><p> //葉子結(jié)點(diǎn)到根逆向求編碼</p><p>
31、if (HT[f].lchild==c) cd[--start] ='0';</p><p> else cd[--start] = '1';</p><p> HC[i] = (char *)malloc((n-start)*sizeof(char));</p><p> //為第i個(gè)字符編碼分配空間</p>
32、<p> strcpy(HC[i], &cd[start]); //從cd復(fù)制編碼(串)到HC</p><p><b> }</b></p><p> free(cd); //釋放工作空間</p><p> for(i=1;i<=n;i++
33、)</p><p> printf("<%2d>編碼:%s\n",HT[i].weight,HC[i]);</p><p> }//HuffmanCoding</p><p><b> 五、測(cè)試分析</b></p><p> 根據(jù)設(shè)計(jì)要求中的問(wèn)題描述分別輸入字符的個(gè)數(shù)和對(duì)應(yīng)的權(quán)值,
34、程序運(yùn)行得到圖4的開始界面。</p><p> 圖4哈夫曼編碼程序開始界面</p><p> 構(gòu)造哈夫曼樹的過(guò)程如圖(5~ 12)所示。</p><p><b> 圖5</b></p><p><b> 圖6</b></p><p><b> 圖7<
35、/b></p><p><b> 圖8</b></p><p><b> 圖9</b></p><p><b> 圖10</b></p><p><b> 圖11</b></p><p><b> 圖12&
36、lt;/b></p><p> 構(gòu)造哈夫曼編碼如圖13所示。</p><p><b> 圖13 哈夫曼編碼</b></p><p><b> 六、用戶手冊(cè) </b></p><p> (1)本程序執(zhí)行文件為“哈夫曼樹的建立及其應(yīng)用.exe”。</p><p>
37、?。?)進(jìn)入本程序之后,分別輸入哈夫曼編碼字符的個(gè)數(shù)和對(duì)應(yīng)的權(quán)值。</p><p> (3)隨即顯示哈夫曼樹的構(gòu)造過(guò)程,最終顯示出對(duì)應(yīng)權(quán)值的哈夫曼編碼。</p><p><b> 七、調(diào)試報(bào)告</b></p><p> 此次課程設(shè)計(jì)主要是了解哈夫曼樹的設(shè)計(jì),并學(xué)會(huì)哈夫曼編碼的設(shè)計(jì)。通過(guò)這次課程設(shè)計(jì),我學(xué)到了課本上以外的許多知識(shí),學(xué)會(huì)了樹相
38、關(guān)的基礎(chǔ)知識(shí),受益匪淺。</p><p> 《數(shù)據(jù)結(jié)構(gòu)》是一門實(shí)踐性較強(qiáng)的課程,為了學(xué)好這門課程,必須在掌握理論知識(shí)的同時(shí),加強(qiáng)上機(jī)實(shí)踐。其次是,根據(jù)實(shí)際問(wèn)題的需要,對(duì)各個(gè)方面的優(yōu)缺點(diǎn)加以綜合平衡,從中選擇比較適宜的實(shí)現(xiàn)方法。比如在選擇數(shù)據(jù)結(jié)構(gòu)的時(shí)候,就要求從時(shí)間性能和空間性能去考慮,從而使得能編寫出更加實(shí)用和高效的代碼,而要做到這點(diǎn),就要求對(duì)知識(shí)點(diǎn)很熟悉。</p><p> 在這次課
39、程設(shè)計(jì)中曾遇到了不少問(wèn)題,比如輸入整型變量的時(shí)候,沒(méi)有辦法限制其不能輸入字符型,還有類型必須前后匹配等等。使我明白了理論與實(shí)際相結(jié)合的重要性,使我更深刻地意識(shí)到:掌握了好的理論并不一定能馬上將其運(yùn)用到自己的程序中,而只有通過(guò)不斷地學(xué)習(xí)和實(shí)踐,不斷地運(yùn)用它,才能熟能生巧!</p><p><b> 八、程序清單</b></p><p> #include <s
40、tdio.h></p><p> #include <malloc.h></p><p> #include <string.h></p><p> #include <conio.h></p><p> typedef struct</p><p><b>
41、 {</b></p><p> unsigned int weight; //用來(lái)存放各個(gè)結(jié)點(diǎn)的權(quán)值</p><p> unsigned int parent,lchild,rchild; //指向雙親、孩子結(jié)點(diǎn)的指針</p><p> }HTNode, *HuffmanTree;
42、 //動(dòng)態(tài)分配數(shù)組存儲(chǔ)哈夫曼樹</p><p> typedef char * * HuffmanCode; //動(dòng)態(tài)分配數(shù)組存儲(chǔ)哈夫曼編碼表</p><p> //1.選擇權(quán)值最小的兩個(gè)結(jié)點(diǎn)</p><p> void Select(HuffmanTree &HT,int m,int *s1,int *s2)</p>
43、<p><b> {</b></p><p> int i,min;</p><p> for(i=1;i<=m;i++) //在HT[1..i-1]中選擇parent為0且weight最小的兩個(gè)結(jié)點(diǎn)</p><p><b> {</b></p><p> if(
44、HT[i].parent==0)</p><p><b> {</b></p><p> min = i;i=m+1;</p><p><b> }</b></p><p><b> }</b></p><p> for(i=1;i<=m
45、;i++) //parent為0且weight最小的兩個(gè)結(jié)點(diǎn),第一個(gè)序號(hào)為s1</p><p><b> {</b></p><p> if(HT[i].parent == 0)</p><p><b> {</b></p><p> if(HT[i].weight < HT[mi
46、n].weight)</p><p><b> min = i;</b></p><p><b> }</b></p><p><b> }</b></p><p> *s1 = min;</p><p> for(i=1; i<=m;i
47、++) //在HT[1..i-1]中選擇parent為0且weight最小的兩個(gè)結(jié)點(diǎn)</p><p><b> {</b></p><p> if(HT[i].parent == 0 &&i!=(*s1))</p><p><b> {</b></p><p> min
48、 = i;i = m+1;</p><p><b> }</b></p><p><b> }</b></p><p> for(i=1;i<=m;i++) //parent為0且weight最小的兩個(gè)結(jié)點(diǎn),第二個(gè)序號(hào)為s2</p><p><b> {</b&g
49、t;</p><p> if(HT[i].parent == 0 &&i!=(*s1))</p><p><b> {</b></p><p> if(HT[i].weight < HT[min].weight)</p><p><b> min = i;</b><
50、;/p><p><b> }</b></p><p><b> }</b></p><p> *s2 = min;</p><p><b> }//Select</b></p><p> //2.構(gòu)造哈夫曼編碼</p><p&g
51、t; void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n)</p><p> {//w存放n個(gè)字符的權(quán)值(均>0),構(gòu)造哈夫曼樹HT并求出n個(gè)字符的哈夫曼編碼HC</p><p> int i,j,m,s1,s2,start;</p><p><b>
52、 char *cd;</b></p><p> unsigned int c,f;</p><p> if (n<=1) return;</p><p> m = 2 * n - 1;</p><p> HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); //0
53、號(hào)單元未用</p><p> for (i=1;i<=n;i++) //葉子結(jié)點(diǎn)初始化并放入1-n號(hào)單元</p><p><b> {</b></p><p> HT[i].weight=w[i];</p><p> HT[i].parent=0;</p><p&
54、gt; HT[i].lchild=0;</p><p> HT[i].rchild=0;</p><p><b> }</b></p><p> for (i=n+1; i<=m;i++) //非葉子結(jié)點(diǎn)初始化</p><p><b> {</b></p>
55、<p> HT[i].weight=0;</p><p> HT[i].parent=0;</p><p> HT[i].lchild=0;</p><p> HT[i].rchild=0;</p><p><b> }</b></p><p> printf("
56、;\n哈夫曼樹的構(gòu)造過(guò)程如下所示:\n");</p><p> printf("HT初態(tài):\n 結(jié)點(diǎn) weight parent lchild rchild");</p><p> for (i=1;i<=m;i++) //完成構(gòu)造哈夫曼樹算法的第1個(gè)步驟</p><p> printf("
57、;\n%4d%8d%8d%8d%8d",i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);</p><p> printf(" 按任意鍵,繼續(xù) ...");</p><p><b> getch();</b></p><p> //創(chuàng)建哈夫曼樹HT
58、</p><p> for (i=n+1;i<=m;i++)</p><p><b> {</b></p><p> Select (HT,i-1,&s1,&s2); </p><p> //在HT[1..i-1]中選擇parent為0且weight最小的兩個(gè)結(jié)點(diǎn)</p>
59、<p> HT[s1].parent=i;HT[s2].parent=i;</p><p> HT[i].lchild=s1;HT[i].rchild=s2;</p><p> //將選取根結(jié)點(diǎn)權(quán)值最小的樹作為左右子樹</p><p> HT[i].weight=HT[s1].weight+HT[s2].weight;</p><
60、;p> //置新二叉樹的根結(jié)點(diǎn)權(quán)值為其左、右子樹根結(jié)點(diǎn)之和</p><p> printf("\nselect:s1=%d s2=%d\n",s1,s2);</p><p> //根結(jié)點(diǎn)權(quán)值最小的樹在HT中的位置</p><p> printf(" 結(jié)點(diǎn) weight parent lchild rchild&qu
61、ot;);</p><p> for (j=1;j<=i;j++)</p><p> //輸出選取根結(jié)點(diǎn)權(quán)值最小樹的過(guò)程</p><p> printf("\n%4d%8d%8d%8d%8d",j,HT[j].weight,HT[j].parent,HT
62、 [j].lchild,HT[j].rchild);</p><p> printf(" 按任意鍵,繼續(xù) ...");</p><p><b> getch();</b></p><p><b> }</b></p><p
63、> printf("\n%d個(gè)字符的哈夫曼編碼如下:\n",n);</p><p> //從葉子到根逆向求每個(gè)字符的哈夫曼編碼</p><p> HC=(HuffmanCode)malloc((n+1)*sizeof(char *));//分配n個(gè)編碼的頭指針</p><p> cd = (char * )malloc(n*size
64、of(char)); //分配求編碼的工作空間</p><p> cd[n-1] = '\0'; //編碼結(jié)束符</p><p> for (i=1;i<=n;i++) //逐個(gè)字符求哈夫曼編碼</p><p><b&g
65、t; {</b></p><p> start =n-1; //編碼結(jié)束符位置</p><p> for (c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent) </p><p> //葉子結(jié)點(diǎn)到根逆向求編碼</p><p
66、> if (HT[f].lchild==c) cd[--start] ='0';</p><p> else cd[--start] = '1';</p><p> HC[i] = (char *)malloc((n-start)*sizeof(char));</p><p> //為第i個(gè)字符編碼分配空間</p
67、><p> strcpy(HC[i], &cd[start]); //從cd復(fù)制編碼(串)到HC</p><p><b> }</b></p><p> free(cd); //釋放工作空間</p><p> for(i=1;i<=n;
68、i++)</p><p> printf("<%2d>編碼:%s\n",HT[i].weight,HC[i]);</p><p> }//HuffmanCoding</p><p><b> //3.主函數(shù)</b></p><p> void main()</p>&
69、lt;p><b> {</b></p><p> HuffmanTree myHuffmanTree;</p><p> HuffmanCode myHuffmanCode;</p><p> int *w,i; </p><p>
70、; int n, wei; //編碼個(gè)數(shù)及權(quán)值</p><p> printf("請(qǐng)輸入需要哈夫曼編碼的字符個(gè)數(shù):");</p><p> scanf("%d",&n);</p><p> w=(int *)malloc((n+1
71、) *sizeof(int));</p><p> for(i=1;i<=n;i++)</p><p><b> {</b></p><p> printf("請(qǐng)輸入第%d字符的權(quán)值:",i);</p><p> fflush(stdin);</p><p>
72、scanf("%d",&wei);</p><p><b> w[i]=wei;</b></p><p><b> }</b></p><p> HuffmanCoding(myHuffmanTree,myHuffmanCode,w,n);</p><p><
73、b> }</b></p><p> 設(shè)計(jì)題目<二>: 3.4.6括號(hào)匹配的檢驗(yàn) </p><p><b> 一、設(shè)計(jì)要求</b></p><p><b> 1.問(wèn)題描述</b></p><p> 假設(shè)表達(dá)式中允許有兩種括號(hào):圓括號(hào)和方括號(hào),其
74、嵌套的順序隨意,即(()[ ])或[([ ] [ ])]等為正確格式,[( ])或((( ]均為不正確的格式。檢驗(yàn)括號(hào)是否匹配的方法可用“期待的緊迫程度”這個(gè)概念來(lái)描述。例如:考慮下列的括號(hào)序列:</p><p> [ ( [ ] [ ] ) ]</p><p> 1 2 3 4 5 6 7 8</p><p> 當(dāng)計(jì)算機(jī)接受了第1個(gè)括號(hào)以后,他期待著與其匹配
75、的第8個(gè)括號(hào)的出現(xiàn),然而等來(lái)的卻是第2個(gè)括號(hào),此時(shí)第1個(gè)括號(hào)“[”只能暫時(shí)靠邊,而迫切等待與第2個(gè)括號(hào)相匹配的 第7個(gè)括號(hào)“)”的出現(xiàn),類似的,因只等來(lái)了第3個(gè)括號(hào)“[”,此時(shí),其期待的緊迫程度較第2個(gè)括號(hào)更緊迫,則第2個(gè)括號(hào)只能靠邊,讓位于第3個(gè)括號(hào),顯然第3個(gè)括號(hào)的期待緊迫程度高于第2個(gè)括號(hào),而第2個(gè)括號(hào)的期待緊迫程度高于第1個(gè)括號(hào);在接受了第4個(gè)括號(hào)之后,第3個(gè)括號(hào)的期待得到了滿足,消解之后,第2個(gè)括號(hào)的期待匹配就成了最急迫的任務(wù)
76、了,…… ,依次類推??梢娺@個(gè)處理過(guò)程正好和棧的特點(diǎn)相吻合。</p><p><b> 2.需求分析</b></p><p> 輸入的形式和輸入值的范圍:從鍵盤上以字符串的形式輸入括號(hào)序列。</p><p> 輸出的形式:括號(hào)匹配或是括號(hào)不匹配。</p><p> 程序所能達(dá)到的功能:檢驗(yàn)括號(hào)是否匹配。</
77、p><p> 測(cè)試數(shù)據(jù):輸入([ ]()),結(jié)果“匹配”, 輸入 [(( )],結(jié)果“此串括號(hào)匹配不合法”</p><p><b> 二、概要設(shè)計(jì)</b></p><p><b> 1.主界面設(shè)計(jì)</b></p><p> 運(yùn)行界面如圖1所示:</p><
78、;p> 圖1 括號(hào)匹配的檢驗(yàn)主菜單</p><p><b> 2.存儲(chǔ)結(jié)構(gòu)設(shè)計(jì)</b></p><p> 對(duì)于括號(hào)匹配的檢驗(yàn)問(wèn)題,希望在輸入一個(gè)括號(hào)序列后,程序能檢測(cè)出該括號(hào)序列是否匹配,則設(shè)置一個(gè)棧來(lái)實(shí)現(xiàn)。當(dāng)遇到 ( 或 [ 時(shí)進(jìn)棧,遇到 ) 或 ] 時(shí)出棧進(jìn)行匹配檢驗(yàn),如果出現(xiàn)不匹配的情況立即結(jié)束,否則繼續(xù)取下一個(gè)字符。如果沒(méi)有遇到不匹配的情況,最后判
79、斷棧是否為空,棧為空,括號(hào)匹配,否則不匹配。</p><p><b> 3.系統(tǒng)功能設(shè)計(jì)</b></p><p> 本程序完成了輸入括號(hào)序列后檢驗(yàn)括號(hào)序列是否匹配,定義棧結(jié)構(gòu)和判斷棧的情況有以下說(shuō)明:</p><p> typedef struct{ }定義棧結(jié)構(gòu)體</p><p> Status CreatS
80、tack(SqStack &S)</p><p> 初始條件:棧指針已存在</p><p> 操作結(jié)果:定義空棧并分配存儲(chǔ)空間,成功返回ok</p><p> Status StackEmpty(SqStack S)</p><p><b> 初始條件:棧已存在</b></p><p&
81、gt; 操作結(jié)果:判斷是否為空,是返回ok</p><p> Status Push(SqStack &S,Elem e)</p><p> 初始條件:棧已存在,e已知</p><p> 操作結(jié)果:將e壓入棧中,成功返回ok</p><p> Status Pop(SqStack &S,Elem &e)<
82、;/p><p> 初始條件:棧非空,棧頂元素等于e</p><p> 操作結(jié)果:棧頂元素出棧</p><p> Status Bracket(SqStack &S,char *str)</p><p> 初始條件:空棧已存在,括號(hào)串非空</p><p> 操作結(jié)果:輸出括號(hào)串是否匹配</p>
83、<p> void main()</p><p> 操作結(jié)果:在屏幕上顯示操作菜單</p><p><b> 三、模塊設(shè)計(jì)</b></p><p><b> 1.模塊設(shè)計(jì) </b></p><p> 本程序包含2個(gè)模塊:主程序模塊和棧操作模塊。其調(diào)用關(guān)系如圖2所示。</
84、p><p> 圖2 模塊調(diào)用示意圖</p><p> 2.系統(tǒng)子程序及功能設(shè)計(jì)</p><p> 本程序共設(shè)置6個(gè)子程序,各子程序的函數(shù)名及功能說(shuō)明如下。</p><p> (1)Status CreatStack(SqStack &S)//創(chuàng)建空堆棧,棧頂指針和棧底指針相等時(shí),棧為空</p><p>
85、 (2)Status StackEmpty(SqStack S)//堆棧是否為空</p><p> (3)Status Push(SqStack &S,Elem e)//進(jìn)棧</p><p> (4)Status Pop(SqStack &S,Elem &e)//出棧</p><p> (5)Status Bracket(SqStack
86、 &S,char *str)//檢驗(yàn)括號(hào)匹配</p><p> (6)void main( ) //主函數(shù)。輸入括號(hào)序列,調(diào)用棧操作模塊函數(shù)</p><p> 3.函數(shù)主要調(diào)用關(guān)系圖</p><p> 本程序6個(gè)子程序之間的主要調(diào)用關(guān)系如圖3所示。</p><p> 圖3 系統(tǒng)函數(shù)調(diào)用關(guān)系圖</p&
87、gt;<p><b> 四、詳細(xì)設(shè)計(jì)</b></p><p><b> 1.?dāng)?shù)據(jù)類型定義</b></p><p> typedef struct{ </p><p> Elem *base; //棧底指針</p><p> Elem *top; //棧頂指針 </p&g
88、t;<p> int size; //當(dāng)前已分配的存儲(chǔ)空間</p><p><b> }SqStack;</b></p><p> typedef int Status;</p><p> 2.系統(tǒng)主要子程序詳細(xì)設(shè)計(jì)</p><p> Status CreatStack(SqStack &
89、S)//創(chuàng)建空堆棧,棧頂指針和棧底指針相等時(shí),棧為空</p><p><b> { </b></p><p> S.base=(Elem *)malloc(STACK_SIZE*sizeof(Elem)); </p><p> S.top=S.base; S.size=STACK_SIZE; return OK;</p>&
90、lt;p> } //棧頂指針和棧底指針相等,創(chuàng)建空堆棧</p><p> Status StackEmpty(SqStack S) //堆棧是否為空</p><p><b> { </b></p><p> if(S.top!=S.base) </p><p> return ER
91、ROR; //棧頂指針和棧底指針不相等,則返回ERROR</p><p> return OK; </p><p><b> }</b></p><p> Status Push(SqStack &S,Elem e)//進(jìn)棧</p><p><b> { </b
92、></p><p> if(S.top-S.base>=S.size)</p><p> { //棧滿,追加存儲(chǔ)空間 </p><p> S.base=(Elem *)realloc(S.base,(S.size+STACK_INC)*sizeof(Elem));</p><p> S.top=S.base+S.size
93、; S.size+=STACK_INC;</p><p><b> } </b></p><p> *S.top=e; //將e賦給棧頂指針</p><p> S.top+=1; //棧頂指針向上移加1</p><p> return OK;}</p><p>
94、; Status Pop(SqStack &S,Elem &e)//出棧</p><p><b> { </b></p><p> if(S.top==S.base) </p><p> return ERROR; //判斷棧是否為空,空則返回ERROR</p><p> S.
95、top-=1; //否則棧頂指針下移減1</p><p> e=*S.top; //將站頂元素賦給e</p><p> return OK;</p><p><b> }</b></p><p> Status Bracket(SqStack &S,char *
96、str)//檢驗(yàn)括號(hào)匹配</p><p><b> { </b></p><p> int i=0,flag1=0,flag2;</p><p><b> Elem e; </b></p><p> while(str[i]!='\0') //括號(hào)序列不為空</p
97、><p><b> { </b></p><p> switch(str[i])</p><p><b> { </b></p><p> case '(':Push(S,'(');</p><p> break; //'(
98、'進(jìn)棧 </p><p> case '[':Push(S,'[');</p><p> break; //'['進(jìn)棧</p><p> case ')':{Pop(S,e); </p><p> if(e!='(') </p>
99、<p> flag1=1; //出棧,判斷是否為'(',不是則用flag1標(biāo)記為1</p><p><b> break;</b></p><p><b> } </b></p><p> case ']':{Pop(S,e);</p><p>
100、; if(e!='[') </p><p> flag1=1; //出棧,判斷是否為['',不是則用flag1標(biāo)記為1</p><p><b> break;</b></p><p><b> } </b></p><p> default: brea
101、k; </p><p><b> } </b></p><p> if(flag1) </p><p> break; //出現(xiàn)不匹配,立即結(jié)束循環(huán) </p><p><b> i++; </b></p><p><b> } </b>&l
102、t;/p><p> flag2=StackEmpty(S); //flag2判斷堆棧是否為空 </p><p> if(!flag1 && flag2) </p><p> printf("匹配\n");</p><p><b> else </b></p><
103、p> printf("此串括號(hào)匹配不合法\n");</p><p> return OK;</p><p><b> }</b></p><p><b> 五、測(cè)試分析</b></p><p> 程序的測(cè)試分析如圖4所示。</p><p>
104、<b> 圖4 程序運(yùn)行圖</b></p><p><b> 六、用戶手冊(cè) </b></p><p> ?。?)本程序執(zhí)行文件為“括號(hào)匹配的檢驗(yàn).exe”。</p><p> ?。?)進(jìn)入本程序之后,輸入要匹配的括號(hào)序列。</p><p> ?。?)顯示“匹配”或“此串括號(hào)匹配不合法”。<
105、/p><p><b> 七、調(diào)試報(bào)告</b></p><p> 以前做實(shí)驗(yàn)題目的時(shí)候總是感覺(jué)很難,因?yàn)楦揪筒恢缽哪睦镩_始。這次課程設(shè)計(jì)讓我對(duì)編程有了新的認(rèn)識(shí)。</p><p> 拿到題目的時(shí)候也是很困惑,后來(lái)看了很多有關(guān)的例子,仔細(xì)看了書上關(guān)于棧的算法的知識(shí),覺(jué)得就是上課講到的一些內(nèi)容,不是題目難,是自己先把自己嚇住了。</p>
106、;<p> 后來(lái),參照書上的諸多例子,一個(gè)模塊一個(gè)模塊的編寫,調(diào)試,一個(gè)功能一個(gè)功能去完善。發(fā)現(xiàn)越做越順利,加上以前的實(shí)驗(yàn)中對(duì)于改錯(cuò)的經(jīng)驗(yàn)積累和幾個(gè)學(xué)得不錯(cuò)的同學(xué)的幫助,我的程序中的錯(cuò)誤也一個(gè)一個(gè)的順利解決。</p><p> 再后來(lái),等我的程序完全做好以后,我竟然可以獨(dú)立的幫同學(xué)修改一些以前根本不知所以然的錯(cuò)誤,其實(shí),從這次實(shí)驗(yàn)中我認(rèn)識(shí)到,我要學(xué)習(xí)的還有很多,編程有很多的樂(lè)趣也有很多的技巧性和
107、知識(shí)性。我將在以后的日子里繼續(xù)認(rèn)真的學(xué)習(xí)知識(shí),積累經(jīng)驗(yàn),讓自己的編程能力提高。</p><p><b> 八、程序清單</b></p><p> #include <stdio.h></p><p> #include <malloc.h></p><p> #define OK 1<
108、;/p><p> #define ERROR 0 //定義順序堆棧</p><p> #define STACK_SIZE 100 //存儲(chǔ)空間初始分配量</p><p> #define STACK_INC 10 //存儲(chǔ)空間分配增量</p><p> typedef char Elem;</p><p>
109、typedef struct{ </p><p> Elem *base; //棧底指針</p><p> Elem *top; //棧頂指針 </p><p> int size; //當(dāng)前已分配的存儲(chǔ)空間</p><p><b> }SqStack;</b></p><p> typ
110、edef int Status;</p><p> Status CreatStack(SqStack &S)//創(chuàng)建空堆棧,棧頂指針和棧底指針相等時(shí),棧為空</p><p><b> { </b></p><p> S.base=(Elem *)malloc(STACK_SIZE*sizeof(Elem)); </p>
111、;<p> S.top=S.base; S.size=STACK_SIZE; return OK;</p><p> } //棧頂指針和棧底指針相等,創(chuàng)建空堆棧</p><p> Status StackEmpty(SqStack S) //堆棧是否為空</p><p><b> { </b><
112、;/p><p> if(S.top!=S.base) </p><p> return ERROR; //棧頂指針和棧底指針不相等,則返回ERROR</p><p> return OK; </p><p><b> }</b></p><p> Status P
113、ush(SqStack &S,Elem e)//進(jìn)棧</p><p><b> { </b></p><p> if(S.top-S.base>=S.size)</p><p> { //棧滿,追加存儲(chǔ)空間 </p><p> S.base=(Elem *)realloc(S.base,(S.si
114、ze+STACK_INC)*sizeof(Elem));</p><p> S.top=S.base+S.size; S.size+=STACK_INC;</p><p><b> } </b></p><p> *S.top=e; //將e賦給棧頂指針</p><p> S.top+=1;
115、 //棧頂指針向上移加1</p><p> return OK;}</p><p> Status Pop(SqStack &S,Elem &e)//出棧</p><p><b> { </b></p><p> if(S.top==S.base) </p><
116、p> return ERROR; //判斷棧是否為空,空則返回ERROR</p><p> S.top-=1; //否則棧頂指針下移減1</p><p> e=*S.top; //將站頂元素賦給e</p><p> return OK;</p><p><b>
117、}</b></p><p> Status Bracket(SqStack &S,char *str)//檢驗(yàn)括號(hào)匹配</p><p><b> { </b></p><p> int i=0,flag1=0,flag2;</p><p><b> Elem e; </b>
118、;</p><p> while(str[i]!='\0') //括號(hào)序列不為空</p><p><b> { </b></p><p> switch(str[i])</p><p><b> { </b></p><p> case
119、9;(':Push(S,'(');</p><p> break; //'('進(jìn)棧 </p><p> case '[':Push(S,'[');</p><p> break; //'['進(jìn)棧</p><p> case ')&
120、#39;:{Pop(S,e); </p><p> if(e!='(') </p><p> flag1=1; //出棧,判斷是否為'(',不是則用flag1標(biāo)記為1</p><p><b> break;</b></p><p><b> } </b>
121、</p><p> case ']':{Pop(S,e);</p><p> if(e!='[') </p><p> flag1=1; //出棧,判斷是否為['',不是則用flag1標(biāo)記為1</p><p><b> break;</b></p>
122、<p><b> } </b></p><p> default: break; </p><p><b> } </b></p><p> if(flag1) </p><p> break; //出現(xiàn)不匹配,立即結(jié)束循環(huán) </p><p>&l
123、t;b> i++; </b></p><p><b> } </b></p><p> flag2=StackEmpty(S); //flag2判斷堆棧是否為空 </p><p> if(!flag1 && flag2) </p><p> printf("匹配\n&
124、quot;);</p><p><b> else </b></p><p> printf("此串括號(hào)匹配不合法\n");</p><p> return OK;</p><p><b> }</b></p><p> void main(){
125、 //主函數(shù)</p><p> char temp,flag='y'; </p><p> while(flag=='y'){</p><p> char str[255];</p><p> SqStack S;</p><p> printf("請(qǐng)輸入要匹配
126、的括號(hào)序列:\n");</p><p> scanf("%s",str); </p><p> scanf("%c",&temp); //接受輸入的回車鍵</p><p> CreatStack(S); </p><p> Bracket(S,str);</p>
127、<p> printf("您想再試一次嗎(按y繼續(xù)): ");</p><p> scanf("%c",&flag);</p><p> printf("\n"); </p><p><b> } </b></p><p> prin
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告 (2)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告 (2)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告
- 《數(shù)據(jù)結(jié)構(gòu)》課程設(shè)計(jì)報(bào)告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì) (2)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)--數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)----huffman編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)——課程設(shè)計(jì)報(bào)告模板
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告 (4)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)實(shí)習(xí)報(bào)告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告.doc
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告 (3)
評(píng)論
0/150
提交評(píng)論