计算文件中每个字母的出现次数?

Posted

技术标签:

【中文标题】计算文件中每个字母的出现次数?【英文标题】:Count occurrences of each letter in a file? 【发布时间】:2013-01-03 18:15:00 【问题描述】:

即使文件大小为 4GB 或更大,如何以优化的方式找到字母 A-Z 的出现(忽略大小写)? C++/C 中可能有哪些不同的实现?

一个实现是:

伪代码

A[26]=0
loop through each character ch in file
If isalpha(ch)
     A[tolower(ch)-'A']+ = 1
End If
end loop

【问题讨论】:

如果你操作的是4GB的文件,那么这个程序的运行时间将会被磁盘I/O支配。优化计数将毫无意义。您需要优化 I/O 部分。 根据您的应用程序和周围的东西,它可能是一个选项,可以将已经计算的统计数据缓存在磁盘上/在数据库中及其修改时间。只是给出一个想法...... 对不起,伙计。但是对于这样的问题,您必须考虑使用 apache hadoop 和 map reduce。顺便说一句,他们引入的第一个基本问题与您的重复。 @SRINI794,您的磁盘通常没有并行硬件路径。 @SRINI794,这就是 Raymond Chen 试图提出的观点——你可以将计数速度提高 1000 倍,但这并没有什么不同,你还在等待磁盘。更多线程实际上会伤害您,因为它们可能会从磁盘的不同部分读取。 【参考方案1】:

我认为剩下的优化不多。

不是为每个元素计算 tolower()-'A',而是计算每个字符的出现次数(在 char[256] 累加器中),然后进行区分大小写的计算(可能更有效或不更有效,试试吧) .

一定要使用缓冲输入(fopen,也许用setvbuf分配更大的缓冲区)。

例如:

acum[256]=0
loop through each character 'c' in file
     acum[c]++
end loop
group counts corresponding to same lowercase/uppercase letters

另外,请记住,这假定为 ASCII 或派生(一个八位字节 = 一个字符)编码。

【讨论】:

必须小心 256 的数组,因为一半的字符值将是负数。 A[c+128]++ @MarkRansom:如果使用 getcch 是 int,则不会。 @leonbloy,有趣的问题。我一直使用freadread 一次得到一堆,所以我不太了解getc 的行为。 也许内存映射文件可能有一些好处,但除此之外,这与不分块文件一样好。【参考方案2】:

对于 4GB,这不会是瞬时的。我知道如何更快地完成您正在做的事情。

此外,您的代码不会处理制表符、空格或其他字符。您需要使用isalpha(),并且只有在返回 true 时才增加计数。

请注意,isalpha() 非常快。但是,同样,如果输入非常大,这段代码不会是即时的。

TCHAR a[26] =  0 ;

for (int i = 0; i < length; i++)

    if (isalpha(text[i]))
    
        a[tolower(text[i]) - 'a']++;
    

【讨论】:

是的,我知道我的执行速度很慢!!我只是想知道是否有更快的方法来实现这个? 我想我已经回答了,除了显示你的代码缺少的东西。

以上是关于计算文件中每个字母的出现次数?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript计算每个字母出现的次数

如何计算单个字母的出现次数

PHP计算变量值出现的次数

计算单个字母在单词中出现的次数

如何计算特定字母在字符串中出现的次数? (C++)

计算每个单词在文件中出现的次数