跟踪多个文件中一系列字符的频率

Keeping Track of the Frequencies of a Range of Characters in Multiple Files

本文关键字:字符 频率 一系列 文件 跟踪      更新时间:2023-10-16

想知道如何统计许多文本文件中的一系列字符(特别是ASCII 10和ASCII 32到ASCII 126(。目前有类似的东西:

for (int i = 0; i < 96; i++)
{
while (!File1.eof())
{
data[i] = File1.get();
frequencies[i]++;
}
while (!File2.eof())
{
data[i] = File2.get();
frequencies[i]++;
}
while (!words1.eof())
{
data[i] = words1.get();
frequencies[i]++;
}

while (!ST1.eof())
{
data[i] = ST1.get();
frequencies[i]++;
}
while (!ST2.eof())
{
data[i] = ST2.get();
frequencies[i]++;
}
while (!ST3.eof())
{
data[i] = ST3.get();
frequencies[i]++;
}
while (!ST4.eof())
{
data[i] = ST4.get();
frequencies[i]++;
}
while (!ST5.eof())
{
data[i] = ST5.get();
frequencies[i]++;
}
while (!ST6.eof())
{
data[i] = ST6.get();
frequencies[i]++;
}
while (!ST7.eof())
{
data[i] = ST7.get();
frequencies[i]++;
}
while (!ST8.eof())
{
data[i] = ST8.get();
frequencies[i]++;
}
while (!ST9.eof())
{
data[i] = ST9.get();
frequencies[i]++;
}
while (!ST10.eof())
{
data[i] = ST10.get();
frequencies[i]++;
}
while (!chesterton.eof())
{
data[i] = chesterton.get();
frequencies[i]++;
}
while (!dickens.eof())
{
data[i] = dickens.get();
frequencies[i]++;
}
while (!earth.eof())
{
data[i] = earth.get();
frequencies[i]++;
}
while (!mystery.eof())
{
data[i] = mystery.get();
frequencies[i]++;
}
while (!myths.eof())
{
data[i] = myths.get();
frequencies[i]++;
}
while (!simak.eof())
{
data[i] = simak.get();
frequencies[i]++;
}
while (!wodehouse.eof())
{
data[i] = wodehouse.get();
frequencies[i]++;
}

}

for循环转到第96个元素,因为我必须计算96个字符。

data[]已初始化,因此data[0]是ASCII 10字符,data[1]是ASCII 32字符,data[3]是ASCII 33字符。。。直到CCD_ 6是ASCII 126字符。

frequencies[]已初始化为0,并且是包含data[]中第i个字符的对应计数的数组。

这样行吗?

我认为您根本不需要保留数据数组;所以如果你想计算ascii字符,我只需要创建一个128大小的数组,然后直接访问它。所以你可以做这样的事情:

int main () {
int frequencies[128] ={};
std::ifstream is("example.txt"); 
CountCharacters(is, frequencies);
}
void CountCharacters(std::ifstream &is, int frequencies[])
{
while (!is.eof())
{
char c = is.get();
frequencies[c]++;
}
is.close();
}

IMHO,您应该使用块读取来完成此操作。

const unsigned int BUFFER_SIZE = 1024*1024;
char buffer[BUFFER_SIZE];
//...
while (File1.read(&buffer[0], BUFFER_SIZE))
{
const size_t chars_read = File1.gcount();
for (size_t i = 0; i < chars_read; ++i)
{
frequencies[i]++;
}
}

内存的搜索和访问速度总是比硬盘更快。硬盘是流媒体设备;保持流媒体播放时效果最好。由于设置的原因,一次读取一个字符浪费时间的几率很高。使用块读取时,开销(设置等(与数据传输的比率更好(每个开销有更多数据(。

您没有区分单词或句子,因此不必担心单词或句子是否在缓冲区读取中被拆分。

如果您想要更高的性能,可以将其分为两个线程:一个用于读取数据,另一个用于处理数据。您还需要使用双缓冲或多缓冲来减少处理线程执行的等待量。

编辑1:阅读后
阅读完成后,可以打印直方图:

for (int i = ' '; i < 127; ++i)
{
std::cout << i << ": " << frequencies[i] << "n";
}