C++哈希表报数组越界警告及读取文件统计唯一单词功能实现求助
数组越界警告问题修复
你收到的越界警告来自两处非法数组访问:
- 你定义的
costArr、updateArr长度都是HASHSIZE=4001,合法下标范围为0~4000,但代码中probes()函数里的costArr[HASHSIZE] = probeCount;和size()函数里的updateArr[HASHSIZE] = updateCount;直接访问了下标4001,超出了数组边界,直接删除这两行无效代码即可消除警告。
单词计数功能异常全量修复
现有代码存在多处逻辑错误,导致无法实现需求,逐点修复如下:
- 类成员未初始化:
probeCount、updateCount未赋初始值,运行时会使用随机值,需在类构造函数中初始化为0 update函数逻辑混乱:- 现有逻辑重复计数,前半段判断已经修改了
sizeUnique、updateCount、probeCount,后半段又全局加了一次,导致计数完全失真 - 线性探测冲突处理未做边界判断,
k++时没有限制小于HASHSIZE,哈希表满时会直接越界 - 新插入单词时仅赋值
word,未给frequency置1,逻辑不完整
- 现有逻辑重复计数,前半段判断已经修改了
size函数功能完全错位:你已经定义了sizeUnique变量存储唯一单词数,直接返回该值即可,现有代码计算的是平均探测次数,和计数需求无关main函数读取逻辑完全错误:- 没有从文件中读取单词到变量,始终传入空字符串到
update函数 !thisfile.eof写法错误,eof是成员函数需要加括号,且正确读取单词的写法是直接用>>操作符判断读取结果- 缺少文件打开失败的错误提示
- 没有从文件中读取单词到变量,始终传入空字符串到
修复后完整代码
#include <iostream> #include <string> #include <fstream> #define HASHSIZE 4001 using namespace std; class entry { public: string word; int frequency; entry() { frequency = 0; } }; class Hashtable { private: entry entryArr[HASHSIZE]; int sizeUnique = 0; int probeCount; int updateCount; public: // 新增构造函数初始化成员变量 Hashtable() { probeCount = 0; updateCount = 0; } int HashKey(string key) { int totalsum = 0; for (int i = 0; i < key.length(); i++) totalsum += int(key[i]); return (totalsum % HASHSIZE); } void update(string key) { // 空字符串直接跳过 if (key.empty()) return; int k = HashKey(key); probeCount++; // 线性探测找位置,加边界判断 while (k < HASHSIZE && entryArr[k].frequency != 0 && entryArr[k].word != key) { k++; probeCount++; } // 哈希表满的情况直接返回,避免越界 if (k >= HASHSIZE) return; if (entryArr[k].frequency == 0) { // 新单词插入 entryArr[k].word = key; entryArr[k].frequency = 1; sizeUnique++; updateCount++; } else { // 已有单词计数+1 entryArr[k].frequency++; } } int probes() { return probeCount; } int size() { return sizeUnique; } }; int main() { Hashtable h; ifstream thisfile("RomeoAndJuliet.txt"); if (thisfile.is_open()) { string word; // 直接读取单词,自动跳过空格、换行 while (thisfile >> word) { h.update(word); } thisfile.close(); cout << "The total number of unique words are: " << h.size() << endl; } else { cout << "文件打开失败,请检查文件路径是否正确" << endl; } return 0; }
内容的提问来源于stack exchange,提问作者Harsh Mohan Sason
相关产品推荐
相关产品推荐

