算法設計
- 預處理:讀取全文,轉小寫,過濾非字母字符,得字母序列
S[0..N-1]。
- 共現矩陣:定義
int co[26][26] = {0}。滑動窗口寬度 W(如 5),對每個位置 i,統計 S[i] 與 S[i+1..i+W] 內字母共現,co[a][b]++、co[b][a]++。
- 查詢:輸入字母
c,取第 c-'a' 行,構建最小堆(大小 3)選出計數最大的 3 個字母。
複雜度
- 時間:
O(N * W + 26 log 3) ≈ 線性。
- 空間:
O(26^2) = 常數。
C++ 關鍵代碼
string text = readAll("article.txt");
vector seq;
for (char ch : text) if (isalpha(ch)) seq.push_back(tolower(ch)-'a');
int co[26][26] = {};
const int W = 5;
for (int i = 0; i < seq.size(); ++i) {
for (int j = i+1; j < seq.size() && j <= i+W; ++j) {
int a = seq[i], b = seq[j];
co[a][b]++; co[b][a]++;
}
}
auto top3 = [&](int c) {
priority_queue, vector>, greater<>> pq;
for (int k = 0; k < 26; ++k) if (k != c) {
pq.emplace(co[c][k], k);
if (pq.size() > 3) pq.pop();
}
vector res;
while (!pq.empty()) { res.push_back('a'+pq.top().second); pq.pop(); }
reverse(res.begin(), res.end());
return res;
};
優化方向
- 窗口權重衰減:距離越近權重越高。
- 稀疏矩陣壓縮:僅存儲非零計數。|