比較兩個大型文字檔(數千行),找出差異行並輸出。要求:
string,檔案內容存入 STL 容器(vector<string>/list<string>/set<string>)。Container_Differences 模板函數,接受兩個輸入容器、一個輸出容器,計算對稱差集。populate_set_from_file、addElementToSet 模板化,支援任意容器類型。
int main(int argc, char* argv[]) {
if (argc != 3) { /* 使用說明 */ return 1; }
typedef vector StringSet; // 一處修改即可切換容器
StringSet file1, file2, diff;
populate_set_from_file(file1, argv[1]);
populate_set_from_file(file2, argv[2]);
Container_Differences(file1, file2, diff);
for_each(diff.begin(), diff.end(), printElement);
return 0;
}
template
bool populate_set_from_file(Container& c, const char* filename) {
ifstream in(filename);
if (in.fail()) return false;
string line;
try {
while (getline(in, line)) {
addElementToSet(c, line);
}
} catch (bad_alloc& e) { /* 錯誤處理 */ }
return true;
}
// 通用版本:支援有 insert() 的容器 (set, list)
template
void addElementToSet(C& c, const V& v) { c.insert(v); }
// vector 特例化:使用 push_back
template <>
void addElementToSet, string>(vector& c, const string& v) {
c.push_back(v);
}
template
void Container_Differences(const Container& c1, const Container& c2, Container& result) {
Container temp;
if (&c1 != &c2) {
// c1 有、c2 無
for (auto it = c1.begin(); it != c1.end(); ++it) {
if (find(c2.begin(), c2.end(), *it) == c2.end())
addElementToSet(temp, static_cast(*it));
}
// c2 有、c1 無
for (auto it = c2.begin(); it != c2.end(); ++it) {
if (find(c1.begin(), c1.end(), *it) == c1.end())
addElementToSet(temp, static_cast(*it));
}
}
temp.swap(result); // 高效轉移結果
}
main 中一行 typedef 即可切換 vector/list/set。insert vs push_back 統一封裝。find、for_each、swap 皆為 STL 標準組件。const ref,輸出容器 non-const ref,避免拷貝。find 為 O(N),整體 O(N²)。大檔案建議改用 set (O(log N) 查找) 或先排序後 set_symmetric_difference (O(N log N))。trim 預處理。STL 容器、迭代器、算法、模板特例化的有機結合,讓複雜的檔案比較邏輯化為清晰、可重用、可擴展的元件。這正是泛型程式設計的威力所在。