【发布时间】:2019-05-22 06:19:03
【问题描述】:
我已经写了一个工作项目,但我的问题是,它比我最初的目标要慢得多,所以我有一些关于如何改进它的想法,但我不知道如何实现这些想法还是我应该首先实施这些想法?
我项目的主题是,读取一个包含推文的 CSV (Excel) 文件并计算其中的每个单词,然后显示最常用的单词。
(Excel的每一行都有关于推文和推文本身的信息,我应该只关心推文)
我不会分享整个代码,而只是简单地写下我到目前为止所做的事情,并且只询问我正在努力的部分。
首先,我想道歉,因为这将是一个很长的问题。
重要提示:我唯一应该关注的是速度、存储或大小不是问题。
所有步骤:
- 从 Excel 文件中读取一个新行。
- 从整行中找到“tweet”部分并将其存储为字符串。
- 将推文字符串拆分为单词并将其存储在数组中。
- 对于存储在数组中的每个单词,计算该单词的 ASCII 值。
(为了找到单词的 ascii 值,我只需将它具有的每个字母的 ascii 值求和)
- 将单词以 ASCII 值的键放入哈希表中。
(例如:单词“hello”的ascii值为104+101+108+108+111 = 532,所以在hast表中与key 532一起存储)
- 在哈希表中,仅存储单词“作为字符串”和键值“作为 int”,并且单词的计数(使用相同单词的次数)存储在单独的数组中。
我将分享 Insert 函数(用于向 Hashtable 插入一些内容),因为我相信如果我尝试不使用代码来解释这部分内容会令人困惑。
void Insert(int key, string value) //Key (where we want to add), Value (what we want to add)
{
if (key < 0) key = 0; //If key is somehow less than 0, for not taking any error key become 0.
if (table[key] != NULL) //If there is already something in hast table
{
if (table[key]->value == value) //If existing value is same as the value we want to add
{
countArray[key][0]++;
}
else //If value is different,
{
Insert(key + 100, value); //Call this function again with the key 100 more than before.
}
}
else //There is nothing saved in this place so save this value
{
table[key] = new HashEntry(key, value);
countArray[key][1] = key;
countArray[key][0]++;
}
}
所以“插入”功能分为三部分。
- 如果具有给定键的 hast 表为空,则将值添加到哈希表。
- 如果具有给定键的 hast 表不为空,则意味着我们已经使用此 ascii 值放置了一个单词。
因为不同的词可以有完全相同的 ascii 值。
- 程序首先检查这是否是同一个词。
- 如果是,则计数增加(在计数数组中)。
- 如果没有,则再次调用 Insert 函数,键值为 (same key value + 100),直到找到空白空间或相同的值。
读取整行并将每个单词存储在哈希表中 ->
对 Count 数组进行排序
打印前 10 个元素
程序到此结束,请问有什么问题?
现在我最大的问题是我正在读取一个包含数千行的非常大的 CSV 文件,所以每一个不必要的事情都会显着增加时间。
我的第二个问题是有很多具有相同 ASCII 值的值,我检查一百多个比正常 ascii 值方法有效的方法,但是?为查找空格或同一个单词,Insert 函数每个单词调用自身数百次。
(这导致了最大的问题)。
所以我考虑使用多个哈希表。
例如,我可以检查单词的第一个字母,如果它是
A和E之间,存储在第一个哈希表中
F和J之间,存入第二个哈希表
...
在 V 和 Z 之间,存储在最后一个哈希表中。
再次重要提示:我唯一应该关注的是速度、存储或大小不是问题。
因此,应该通过这种方式最大限度地减少冲突。
我什至可以创建数量惊人的哈希表,并且对于每个不同的字母,我都可以使用不同的哈希表。
但我不确定这是否合乎逻辑,或者我可以使用更简单的方法。
如果可以使用多个哈希表,而不是一个一个地创建哈希表,是否可以创建一个在每个位置存储一个哈希表的数组? (与数组数组相同,但这次数组存储哈希表) 如果可能且合乎逻辑,有人可以展示如何做吗?
这是我的哈希表:
class HashEntry
{
public:
int key;
string value;
HashEntry(int key, string value)
{
this->key = key;
this->value = value;
}
};
class HashMap
{
private:
HashEntry * *table;
public:
HashMap()
{
table = new HashEntry *[TABLE_SIZE];
for (int i = 0; i < TABLE_SIZE; i++)
{
table[i] = NULL;
}
}
//Functions
}
我很抱歉我问了这么长的问题,如果我不能清楚地解释每个部分,我再次非常抱歉,英语不是我的母语。
最后要注意的是,我这样做是为了一个学校项目,所以我不应该使用任何第三方软件或包含任何不同的库,因为这是不允许的。
【问题讨论】:
-
是否也禁止使用标准库?
-
@r3musn0x 在项目中写着“(您不应该使用第三方库,包括 C++ STL、Boost 等)。但是,您可以使用 iostream、ctime、fstream、类似字符串的 IO 和字符串相关的类。“所以可能是的,我需要使用自己的哈希表。
-
为什么要将字数存储在单独的数组而不是哈希表中?
-
@r3musn0x 因为我对数组进行排序比尝试使用多个值的排序哈希表更容易。我认为这不会造成太多时间损失,但如果我错了,我会尝试改变。