代碼在網上找的,應該可以運行的,但我運行輸入檔案名后就出現例外,請求指教。

#include <iostream>
#include <string>
#include <iomanip>
#include <stdio.h>
using namespace std;
const int TOTAL = 32; //32個關鍵字
const int MAXLEN = 10; //關鍵字長度
const int HASHLEN = 41; //哈希表長度
int cont = 0; //統計哈希表中的關鍵字個數
void Show(int key);
int Read(char *filename);
int isLetter(char ch);
int isKeyWords(char *word);
int FindHX(char *keyword);
int CreatHX(char *keyword);
int GetFreePos(int key);
void ResetHX();
int GetKey(char *keyword);
char KeyWords[TOTAL][MAXLEN] = //構造二維陣列存盤32個關鍵字
{
"auto","break","case","char","const","continue",
"default","do","double","else","enum","extern",
"float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static",
"struct","switch","typedef","union","unsigned",
"void","volatile","while",
};
/***********************************************************************
typedef struct HASH
{
char keyword[MAXLEN];
int count; //出現次數(頻度)
int con; //沖突次數
}HASH HS[HASHLEN];
/****************************************************************************/
class HASH //哈希表類
{
public:
char keyword[MAXLEN];
int count; //出現次數(頻度)
int con; //沖突次數
};
HASH HS[HASHLEN];
int main()
{
char filename[128], word[MAXLEN];
int i, key, count;
ResetHX(); //先清空哈希表
cout << "請輸入要讀取的檔案名(檔案必須與程式在同一目錄下):";
cin >> filename;
cout << endl;
Read(filename);//read函式從一個檔案讀位元組到一個指定的存盤器區域,由長度引數確定要讀的位元組數
for (i = 0; i<HASHLEN; i++)
Show(i);
cout << "關鍵字總數為:" << cont << endl;
cout << "請輸入你想要查找的關鍵字: ";
cin >> word;
cout << endl;
Show(FindHX(word));
cout << "\t沖突關鍵字串列" << endl << endl;
count = 0;
for (i = 0; i<HASHLEN; i++)
{
if (strlen(HS[i].keyword)>0)
{
key = GetKey(HS[i].keyword);
if (key != i)
{
count++;
cout << "\t[關鍵字]: " << HS[i].keyword << endl;
cout << "\t[哈希表當前位置]: " << i << endl;
cout << "\t[沖突次數]: " << HS[i].con << endl << endl;
}
}
}
if (count == 0)
cout << "沒有沖突" << endl;
else
cout << "\t沖突關鍵字共:" << count << "個" << endl;
return 0;
}
void Show(int key)//顯示出某關鍵字的頻度
{
if (key<0 || key >= HASHLEN)
{
cout << "關鍵字不存在!" << endl;
return;
}
if (strlen(HS[key].keyword) == 0)
{
cout << "哈希表位置:" << key << " 記錄是空的" << endl;
return;
}
cout << "哈希表位置: " << key << " 關鍵字: "
<< HS[key].keyword << " 出現次數 " << HS[key].count << endl;
cont++;
}
int Read(char *filename) //讀取檔案
{
char word[MAXLEN], ch;
int i;
FILE *read;
if ((read = fopen(filename, "r")) == NULL) //只讀方式打開一個文本檔案,只允許讀資料
{
cout << "檔案不存在,請確認好再輸入!" << endl;
return -1;
}
ResetHX(); //讀取檔案前先清空哈希表
while (!feof(read)) //feof()是檔案結束檢測函式,如果沒有結束,回傳值是0,結束了是1
{
i = 0;
ch = fgetc(read); //讀取一個字符
while (isLetter(ch) == 0 && feof(read) == 0) ch = fgetc(read);
//如果不是字母的話接著讀取
while (isLetter(ch) == 1 && feof(read) == 0)
{
if (i == MAXLEN)
{
while (isLetter(ch) == 1 && feof(read) == 0)
{
ch = fgetc(read);
}
i = 0;
break;
}
//超過關鍵字長度將跳過當前識別區域,讀取后一單詞
else
{ //將連續讀取的字母存在陣列里,組成一個單詞
word[i++] = ch;
ch = fgetc(read);
}
}
word[i] = '\0'; //字符陣列的結束標志
if (isKeyWords(word))
{
CreatHX(word);
}
}
fclose(read);
cout << "讀取成功,檔案中關鍵字已經存入hash表,請繼續操作" << endl;
return 1;
}
int isLetter(char ch) //判斷是否是字母,因為關鍵字都是英文單詞
{
if ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z')) return 1;
else return 0;
//是字母就回傳1,否則回傳0值
}
int FindHX(char *keyword) //查找哈希表,分塊查找
{
int key, find, tem = 0;
if (!isKeyWords(keyword)) return -1;
key = GetKey(keyword);
if (strcmp(HS[key].keyword, keyword) == 0) return key;
for (find = key + 1; find<HASHLEN; find++)
{ //線性探查法順序查找哈希表中是否已存在關鍵字
tem++; //統計沖突次數
if (strcmp(HS[find].keyword, keyword) == 0) {
HS[find].con = tem;
return find;
}
}
for (find = 0; find<key; find++)
{
tem++;
if (strcmp(HS[find].keyword, keyword) == 0) {
HS[find].con = tem;
return find;
}
}
return -1;
}
int CreatHX(char *keyword) //建立哈希表
{
int key;
if (!isKeyWords(keyword)) return -1;
key = GetKey(keyword); //計算哈希值
if (strlen(HS[key].keyword)>0) //判斷關鍵字表中該位置是否存在關鍵字
{ //已經存在有關鍵字
if (strcmp(HS[key].keyword, keyword) == 0)
{ //再判斷哈希表中該位置的關鍵字是否相同
HS[key].count++;
return 1;
}
key = FindHX(keyword); //不相同,繼續查找
if (key<0)
{
key = GetFreePos(GetKey(keyword));
if (key<0) return -1;
strcpy(HS[key].keyword, keyword); //將關鍵字插入哈希表
}
if (key<0) return -1;
HS[key].count++;
}
else //該位置為空,直接將關鍵字插入該位置中
{
strcpy(HS[key].keyword, keyword);
HS[key].count++;
}
return 1;
}
int GetFreePos(int key) //在哈希表中給關鍵字找個位置插進去
{
int find, tem = 0;
if (key<0 || key >= HASHLEN) return -1;
for (find = key + 1; find<HASHLEN; find++) //先找后面的位置
{
tem++;
if (strlen(HS[find].keyword) == 0) {
HS[find].con = tem;
return find;
}
}
for (find = 0; find<key; find++) //再找前面的位置
{
tem++;
if (strlen(HS[find].keyword) == 0) {
HS[find].con = tem;
return find;
}
}
return -1; //哈希表已滿
}
void ResetHX() //重置哈希表,
{
int i;
for (i = 0; i<HASHLEN; i++)
{
strcpy(HS[i].keyword, ""); //不能用等號賦值
HS[i].count = 0;
HS[i].con = 0;
}
}
int GetKey(char *keyword) //哈西函式
{ //Hash函式為:Hash(Key)=[(Key的首字母序號)*100+(Key的尾字母序號)] Mod 41
return (keyword[0] * 100 + keyword[strlen(keyword) - 1]) % 41; //這里不要忘了減1
}
int isKeyWords(char *word) //判斷是否關鍵字
{
int i;
for (i = 0; i<TOTAL; i++)
if (strcmp(word, KeyWords[i]) == 0) return 1;
return 0;
}
uj5u.com熱心網友回復:
崩潰的時候在彈出的對話框按相應按鈕進入除錯,按Alt+7鍵查看Call Stack即“呼叫堆疊”里面從上到下列出的對應從里層到外層的函式呼叫歷史。雙擊某一行可將游標定位到此次呼叫的源代碼或匯編指令處,看不懂時雙擊下一行,直到能看懂為止。uj5u.com熱心網友回復:
出現陣列越界了,看看你的陣列操作是否下標有問題轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/103834.html
標籤:基礎類
