c++编程计算英文文本(.txt)文件相邻符号间的互信息(点互信息),大写字母用小写字母代替,并计算平均互信息。
时间: 2024-05-07 19:19:47 浏览: 80
这是一个相对比较复杂的编程任务,需要一定的算法和编程技巧。以下是一个简单的示例代码,供参考:
```cpp
#include <iostream>
#include <fstream>
#include <cmath>
#include <unordered_map>
using namespace std;
double log2(double x) {
return log(x) / log(2);
}
int main() {
string filename;
cout << "请输入文件名: ";
cin >> filename;
ifstream fin(filename);
if (!fin) {
cout << "无法打开文件!" << endl;
return 1;
}
unordered_map<string, int> freq; // 统计单个符号出现次数
unordered_map<string, int> freq_pair; // 统计相邻符号出现次数
char prev = ' ';
char curr;
while (fin.get(curr)) {
if (isupper(curr)) {
curr = tolower(curr);
}
if (!isalpha(curr)) {
prev = ' ';
continue;
}
string s(2, ' ');
s[0] = prev;
s[1] = curr;
freq[string(1, curr)]++; // 统计单个符号出现次数
freq_pair[s]++; // 统计相邻符号出现次数
prev = curr;
}
fin.close();
double sum_mi = 0; // 计算总互信息
int count = 0;
for (auto it = freq_pair.begin(); it != freq_pair.end(); it++) {
string s = it->first;
int count_pair = it->second;
int count1 = freq[string(1, s[1])];
int count2 = freq[string(1, s[0])];
double p_pair = (double)count_pair / (double)(prev == ' ' ? freq.size() : count1);
double p1 = (double)count1 / (double)freq.size();
double p2 = (double)count2 / (double)freq.size();
double mi = log2(p_pair / (p1 * p2));
sum_mi += mi;
count++;
cout << s << " : " << mi << endl;
}
double avg_mi = sum_mi / count; // 计算平均互信息
cout << "平均互信息: " << avg_mi << endl;
return 0;
}
```
代码中使用了两个 `unordered_map` 分别统计单个符号出现次数和相邻符号出现次数,并使用了双指针来遍历整个文本文件。在计算互信息时,需要注意除数可能为零的情况,需要进行特判。最后输出每个相邻符号的互信息和平均互信息即可。
阅读全文