天津科技大學(xué)數(shù)據(jù)結(jié)構(gòu)與算法課程設(shè)計報告-源程序的相似性_第1頁
天津科技大學(xué)數(shù)據(jù)結(jié)構(gòu)與算法課程設(shè)計報告-源程序的相似性_第2頁
天津科技大學(xué)數(shù)據(jù)結(jié)構(gòu)與算法課程設(shè)計報告-源程序的相似性_第3頁
天津科技大學(xué)數(shù)據(jù)結(jié)構(gòu)與算法課程設(shè)計報告-源程序的相似性_第4頁
天津科技大學(xué)數(shù)據(jù)結(jié)構(gòu)與算法課程設(shè)計報告-源程序的相似性_第5頁
已閱讀5頁,還剩7頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、.數(shù)據(jù)結(jié)構(gòu)與算法課程設(shè)計報告設(shè)計題目:源程序的相似性專業(yè)計算機科學(xué)與技術(shù)學(xué)號14101103姓名傅開煤2017年1月 10日;.源程序的相似性一、問題描述對于兩個 C+語言的源程序代碼,用哈希表的方法分別統(tǒng)計兩個程序中使用C+語言關(guān)鍵字的情況,并最終按定量的計算結(jié)果,得出兩份程序的相似性。二、需求分析建立 C+語言關(guān)鍵字的哈希表,統(tǒng)計在每個源程序中C+關(guān)鍵字出現(xiàn)的頻度, 得到兩個向量 X1 和 X2,通過計算向量X1 和 X2 的相對距離來判斷兩個源程序的相似性。例如 :關(guān)鍵字VoidIntForCharifelsewhiledobreakclass程序 1 關(guān)鍵字頻度4304307002程序

2、 2 關(guān)鍵字頻度4205405201X1=4,3,0,4,3,0,7,0,0,2X2=4,2,0,5,4,0,5,2,0,1設(shè) s 是向量 X1和 X 的相對距離, s=sqrt( (x2),當(dāng) X1=X2時, s=0,反映出可能21i-x 2i)是同一個程序;s 值越大,則兩個程序的差別可能也越大。三、概要設(shè)計為了實現(xiàn)上述功能,可以用結(jié)構(gòu)體表示哈希表,因此需要哈希表的抽象數(shù)據(jù)類型。哈希表抽象數(shù)據(jù)類型的定義:ADT hashtable數(shù)據(jù)對象: D=ai |a i ElemType, 且各不相同, i=1,2.,n,n 0數(shù)據(jù)關(guān)系: R=基本操作:Hashfunc(char str);Hash

3、find(char *words);creathash(void);resethash(int n);isletter(char ch);readc(char * filename);getkey(char *str,int len);copycount(int x,int n);check(int *x1, int *x2);end ADT;.本程序?qū)崿F(xiàn)模塊主程序模塊哈希表程序模塊:實現(xiàn)哈希表的抽象數(shù)據(jù)類型調(diào)用關(guān)系圖如下:主程序模塊哈希表程序模塊計算相似度和向量的幾何距離的模塊四、詳細設(shè)計1、各個子函數(shù)的設(shè)計( 1)創(chuàng)建哈希表函數(shù)函數(shù)原型: void creathash(void);輸入:讀

4、取存儲了32 個關(guān)鍵字的文件keyword.txt思路:通過對 keyword.txt 文件逐行賦值給創(chuàng)建的 str 字符數(shù)組,并將該數(shù)組調(diào)入 Hashfunc 函數(shù)。( 2)將關(guān)鍵字根據(jù)哈希函數(shù)放入哈希表中的指定位置的函數(shù)函數(shù)原型: void Hashfunc(char str);思路:對調(diào)進來的 str 數(shù)組通過調(diào)用 getkey 函數(shù)得到該關(guān)鍵詞的 key 值后放入哈希表中的特定位置,并用線性探索來解決沖突。( 3)在哈希表中找是否該 words 為關(guān)鍵字,并統(tǒng)計頻度的函數(shù)函數(shù)原型: int Hashfind(char *words);思路:將調(diào)進來的word 字符數(shù)組先調(diào)用getkey

5、 函數(shù)獲取 key 值,然后在哈希表里查找是否存在該字符串,如果存在則該關(guān)鍵字對應(yīng)的頻度加1。( 4)重置哈希表函數(shù)函數(shù)原型: void resethash(int n);功能:當(dāng) n 為 0 時,將指向哈希表中關(guān)鍵字的指針置成Null ,同時將頻度全部置為0.而當(dāng) n 為 1 時,僅僅將頻度置為0。( 5)獲取單詞key 的函數(shù)函數(shù)原型: int getkey(char *str,int len);思路:用 key1 存儲關(guān)鍵字的首字母,key2 存儲關(guān)鍵字的末字母,然后通過哈希函數(shù)得到 key 的值并返回。( 6)判斷是否為字母的函數(shù);.函數(shù)原型: int isletter(char ch

6、);思路:如果調(diào)進來的ch 字符的 ASCII 值在 az 或 AZ 范圍內(nèi)的話則返回1,否則返回0。( 7)讀取源程序文件中的單詞的函數(shù)函數(shù)原型: int readc(char * filename);思路:為了讀取源程序文件中的單詞,所以一個字符一個字符的,如果讀的超過最大關(guān)鍵字長度將會跳過當(dāng)前識別區(qū)域,讀取下一個單詞,將得到的該單詞調(diào)入Hashfind函數(shù),來判斷是否為關(guān)鍵字,并統(tǒng)計頻度。( 8)將頻度拷貝到數(shù)組里的函數(shù)函數(shù)原型: void copycount(int x,int n);功能:將哈希表中關(guān)鍵字的頻度復(fù)制到x 數(shù)組中,以便進行后面相似度等的計算。( 9)檢查兩個源程序是否相

7、似的函數(shù)函數(shù)原型: void check(int *x1, int *x2);思路:對調(diào)進來的x1 和 x2 數(shù)組進行相似度計算,若相似度大于設(shè)定好的閾值,則再進行幾何距離計算,最后給出兩個文件是否相似的判斷。( 10)取模函數(shù)函數(shù)原型: float Mol(int *x);思路:通過求向量模值的數(shù)學(xué)知識求x 數(shù)組的模。( 11)點積函數(shù)函數(shù)原型: int Dot(int *x1, int *x2)思路:通過點積的數(shù)學(xué)知識對兩個向量求點積。( 12)求相似度 S 的函數(shù)函數(shù)原型: float S(int *x1,int *x2);思路:根據(jù)題目給的求相似度的公式求x1 和 x2 數(shù)組的相似度。

8、( 13)求距離 D的函數(shù)函數(shù)原型: float D(int *x1, int *x2);思路:用題目給的球幾何距離的公式求x1 和 x2 數(shù)組的幾何距離。2、主函數(shù)偽碼int main()char filename1="test1.txt"char filename2="test2.txt"char filename3="test3.txt"int x1hashlen,x2hashlen,x3hashlen; /*存儲頻度的數(shù)組,用于相似度S 的計算*/resethash(0);/*完全重置哈希表,即哈希指針置為NULL,頻度置為

9、0*/creathash();/通過文件 ckey.txt創(chuàng)建哈希表readc(filename1);/讀取第一個測試源程序文件copycount(x1,hashlen);/講統(tǒng)計好的頻度復(fù)制給x 數(shù)組resethash(1);/僅僅將頻度 count 置為 0readc(filename2);/同上copycount(x2,hashlen);resethash(1);.readc(filename3);copycount(x3,hashlen);cout<<"t"<<"哈希序號 "<<"t"<

10、;<"關(guān)鍵字 "<<"t"<<"頻度1"<<"t"<<"頻度 2"<<"t"<<"頻度 3"<<endl;for (int i = 0; i < 41; i+)if(hashti.hash1!=NULL)cout<<"t"<<i<<"t"<<hashti.hash1<&

11、lt;"t"<<x1i<<"t"<<x2i<<"t"<<x3i<<endl;cout<<filename1<<"和 "<<filename2<<"的相似情況為:"<<endl;check(x1,x2);/檢查相似度cout<<filename1<<" 和 "<<filename3<<" 的

12、相似情況為: "<<endl; check(x1,x3);cout<<filename2<<"和 "<<filename3<<"的相似情況為:"<<endl;check(x2,x3);return 0;3、調(diào)用關(guān)系圖調(diào)用關(guān)系圖如下:copycounreadcresethacreathashislettemain()hashfindhashfunccheckgetkeyS DDotMol;.五、編碼實現(xiàn)1. 使用函數(shù)void resethash(int n)來重置哈希表voi

13、d resethash(int n)/重置哈希表if(n=0)/完全重置哈希表for(int i=0;i<41;i+)hashti.hash1=NULL;hashti.count=0;else if (n=1)/僅僅重置頻度for(int i=0;i<41;i+)hashti.count=0;2. 使用 void copycount(int x,int n)來將頻度拷貝到數(shù)組里的函數(shù)void copycount(int x,int n)/拷貝頻度for (int i = 0; i < n; i+)xi=hashti.count;3. 使用 int getkey(char *s

14、tr,int len)來獲取單詞key 的函數(shù)int getkey(char *str,int len)/根據(jù)哈希函數(shù)獲取該單詞的keychar key1,key2;int key;key1=str0;key2=strlen-1;key=(int)(key1*100+key2)%41;return key;.4. 使用 void creathash(void)來創(chuàng)建哈希表函數(shù)void creathash(void)/對文件 keyword.txt中的 32 個關(guān)鍵字創(chuàng)建哈希表FILE *fp;int length;char strsize;/暫時存儲關(guān)鍵字字符的數(shù)組char *s=NULL;f

15、or (int i = 0; i < size; i+)stri='0'if(fp=fopen("keyword.txt","r")=NULL)cout<<"can't creat file!n"exit(0);while (fgets(str,size,fp)!=NULL)/讀取一行寫入一行if (str=NULL)break;length=strlen(str);strlength-1='0' / 調(diào)試后發(fā)現(xiàn)的,沒有這里就停止運行了 Hashfunc(str);fclose

16、(fp);5. 使用 void Hashfunc(char str) 來將關(guān)鍵字根據(jù)哈希函數(shù)放入哈希表中的指定位置的函數(shù)void Hashfunc(char str)/ 將關(guān)鍵字根據(jù)哈希函數(shù)放入哈希表中的指定位置 int key,len;len=strlen(str);key=getkey(str,len);while (hashtkey%41.hash1!=NULL)key+;/線性探索hashtkey%41.hash1=(char*)malloc(sizeof(char)*(len+1);strcpy(hashtkey%41.hash1,str);.6. 使用 int Hashfind(c

17、har *words) 來在哈希表中找是否該 words 為關(guān)鍵字,并統(tǒng)計頻度的函數(shù)int Hashfind(char *words) /在哈希表中找是否該words 為關(guān)鍵字,并統(tǒng)計頻度int key,len,find;len=strlen(words);key=getkey(words,len);while(hashtkey.hash1=NULL)key+;key=key%41;if(strcmp(hashtkey.hash1,words)=0)hashtkey.count+;return 1;for(find=key+1;find<hashlen;find+)/*如果不在key 位

18、置則向往后線性查找,然后再從頭找 */ 線性探查法順序查找哈希表中是否已存在關(guān)鍵字 if(hashtfind.hash1!=NULL)if(strcmp(hashtfind.hash1,words)=0)hashtfind.count+;return 1;for(find=0;find<key;find+)if (hashtfind.hash1!=NULL)if(strcmp(hashtfind.hash1,words)=0)hashtfind.count+;return 1;return 0;7. 使用 int readc(char * filename)來讀取源程序文件中的單詞的函數(shù)

19、int readc(char *filename)/讀取源程序文件中的單詞;.FILE *fp1=NULL;char wordsmaxlen,ch;int i;if(fp1=fopen (filename,"r")=NULL)cout<<"can not creat file!n"exit(0);while (!feof(fp1)/結(jié)束返回1i=0;ch=fgetc(fp1);/一個字符一個字符的讀while (isletter(ch)=0&&feof(fp1)=0)ch=fgetc(fp1);while (isletter(

20、ch)=1&&feof(fp1)=0)if (i=maxlen)while (isletter(ch)=1&&feof(fp1)=0)ch=fgetc(fp1);i=0;break; / 超過最大關(guān)鍵字長度將會跳過當(dāng)前識別區(qū)域,讀取下一個單詞elsewordsi+=ch;ch=fgetc(fp1);wordsi='0'Hashfind(words);/*將得到的該單詞調(diào)入Hashfind函數(shù), 來判斷是否為關(guān)鍵字,并統(tǒng)計頻度*/fclose(fp1);return 0;8. 使用 float Mol(int *x)來取模函數(shù)float Mol(i

21、nt *x)/取模函數(shù);.int i = 0, sum = 0;for (i = 0; i < N; i+)sum += (xi * xi);return (float)pow(float)sum,0.5);int Dot(int *x1, int *x2)/點積函數(shù)int i = 0, sum = 0;for (i = 0; i < N; i+)sum += x1i * x2i;return sum;9. 使用 float S(int *x1,int *x2)、float D(int *x1, int *x2)和 void check(int *x1,int *x2)來分別求相似

22、度S 的函數(shù)、求幾何距離D 函數(shù)和檢查兩個源程序是否相似的函數(shù)float S(int *x1,int *x2)return Dot(x1, x2)/(Mol(x1)*Mol(x2); /求相似度Sfloat D(int *x1, int *x2)/求幾何距離int xN, i = 0;for (i = 0; i < N; i+) /向量相減xi= x1i - x2i;return Mol(x);/再求模void check(int *x1, int *x2)float xs = 0, xd = 0;xs = S(x1, x2);cout<<" 相似度 xs=&quo

23、t;<<xs<<endl;if (xs > Smax) /先判斷 S,若 S 大于閾值再計算幾何距離xd = D(x1, x2);cout<<" 幾何距離xd="<<xd<<endl;if (xd < Dmin) /如果幾何距離小于閾值則判斷為相似cout << "這兩個文件內(nèi)容確實可能相似"<<endl;.elsecout << "這兩個文件內(nèi)容可能不相似"<<endl;return;cout << "這兩個文件內(nèi)容不相似"<<endl;/否則不相似return;六、實驗結(jié)果與分析實驗上機測試結(jié)果如下圖所示:;.分析: 實驗上機運行結(jié)果與實際結(jié)果相符,即可以認為該程序是正確無誤的。七、總結(jié)在本次的課程設(shè)計上機操作的時候, 在調(diào)試每個模塊設(shè)計的時候, 有些模塊由于本人的粗心大意把 =與 =的問題弄混淆了,使調(diào)試

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論