#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <chrono>
#include <cctype>
#include <functional>
#include <utility>
using namespace std;
using namespace std::chrono;
// 辅助函数:去除单词中的标点符号并转换为小写
string processWord(const string& word) {
string processed;
for (char c : word) {
if (isalpha(c)) {
processed += tolower(c);
}
}
return processed;
}
// ====================== 1. 基于顺序表的顺序查找 ======================
class SequentialList {
private:
vector<pair<string, int>> words;
int searchCount;
public:
SequentialList() : searchCount(0) {}
void insertOrIncrement(const string& word) {
searchCount = 0;
for (auto& p : words) {
searchCount++;
if (p.first == word) {
p.second++;
return;
}
}
words.emplace_back(word, 1);
searchCount++;
}
int getFrequency(const string& word, int& asl) {
searchCount = 0;
for (const auto& p : words) {
searchCount++;
if (p.first == word) {
asl = searchCount;
return p.second;
}
}
asl = searchCount;
return -1;
}
void saveToFile(const string& filename) {
vector<pair<string, int>> sortedWords = words;
sort(sortedWords.begin(), sortedWords.end());
ofstream outFile(filename);
for (const auto& p : sortedWords) {
outFile << p.first << " " << p.second << endl;
}
outFile.close();
}
};
// ====================== 2. 基于链表的顺序查找 ======================
class LinkedList {
private:
list<pair<string, int>> words;
int searchCount;
public:
LinkedList() : searchCount(0) {}
void insertOrIncrement(const string& word) {
searchCount = 0;
for (auto& p : words) {
searchCount++;
if (p.first == word) {
p.second++;
return;
}
}
words.emplace_back(word, 1);
searchCount++;
}
int getFrequency(const string& word, int& asl) {
searchCount = 0;
for (const auto& p : words) {
searchCount++;
if (p.first == word) {
asl = searchCount;
return p.second;
}
}
asl = searchCount;
return -1;
}
void saveToFile(const string& filename) {
vector<pair<string, int>> sortedWords(words.begin(), words.end());
sort(sortedWords.begin(), sortedWords.end());
ofstream outFile(filename);
for (const auto& p : sortedWords) {
outFile << p.first << " " << p.second << endl;
}
outFile.close();
}
};
// ====================== 3. 基于顺序表的折半查找 ======================
class BinarySearchList {
private:
vector<pair<string, int>> words;
int searchCount;
int binarySearch(const string& word) {
int left = 0;
int right = words.size() - 1;
while (left <= right) {
searchCount++;
int mid = left + (right - left) / 2;
if (words[mid].first == word) {
return mid;
} else if (words[mid].first < word) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
public:
BinarySearchList() : searchCount(0) {}
void insertOrIncrement(const string& word) {
searchCount = 0;
int pos = binarySearch(word);
if (pos != -1) {
words[pos].second++;
} else {
words.emplace_back(word, 1);
sort(words.begin(), words.end());
}
}
int getFrequency(const string& word, int& asl) {
searchCount = 0;
int pos = binarySearch(word);
asl = searchCount;
return pos != -1 ? words[pos].second : -1;
}
void saveToFile(const string& filename) {
ofstream outFile(filename);
for (const auto& p : words) {
outFile << p.first << " " << p.second << endl;
}
outFile.close();
}
};
// ====================== 4. 基于二叉排序树的查找 ======================
class BST {
private:
struct TreeNode {
string word;
int count;
TreeNode* left;
TreeNode* right;
TreeNode(const string& w) : word(w), count(1), left(nullptr), right(nullptr) {}
};
TreeNode* root;
int searchCount;
vector<pair<string, int>> sortedWords;
TreeNode* insert(TreeNode* node, const string& word) {
if (!node) {
return new TreeNode(word);
}
if (word == node->word) {
node->count++;
} else if (word < node->word) {
node->left = insert(node->left, word);
} else {
node->right = insert(node->right, word);
}
return node;
}
TreeNode* search(TreeNode* node, const string& word) {
if (!node) return nullptr;
searchCount++;
if (word == node->word) {
return node;
} else if (word < node->word) {
return search(node->left, word);
} else {
return search(node->right, word);
}
}
void inOrder(TreeNode* node) {
if (!node) return;
inOrder(node->left);
sortedWords.emplace_back(node->word, node->count);
inOrder(node->right);
}
public:
BST() : root(nullptr), searchCount(0) {}
void insertOrIncrement(const string& word) {
root = insert(root, word);
}
int getFrequency(const string& word, int& asl) {
searchCount = 0;
TreeNode* node = search(root, word);
asl = searchCount;
return node ? node->count : -1;
}
void saveToFile(const string& filename) {
sortedWords.clear();
inOrder(root);
ofstream outFile(filename);
for (const auto& p : sortedWords) {
outFile << p.first << " " << p.second << endl;
}
outFile.close();
}
};
// ====================== 5. 基于开放地址法的哈希查找 ======================
class OpenAddressingHash {
private:
static const int TABLE_SIZE = 10000;
pair<string, int> table[TABLE_SIZE];
int searchCount;
int hashFunction(const string& word) {
hash<string> hasher;
return hasher(word) % TABLE_SIZE;
}
int probe(int index, const string& word, bool forInsert) {
int i = 1;
while (true) {
searchCount++;
if (table[index].first.empty()) {
if (forInsert) return index;
return -1;
}
if (table[index].first == word) {
return index;
}
index = (index + i * i) % TABLE_SIZE; // 平方探测
i++;
if (i > TABLE_SIZE) return -1; // 避免无限循环
}
}
public:
OpenAddressingHash() : searchCount(0) {
for (int i = 0; i < TABLE_SIZE; ++i) {
table[i] = make_pair("", 0);
}
}
void insertOrIncrement(const string& word) {
int index = hashFunction(word);
searchCount = 0;
int pos = probe(index, word, true);
if (pos == -1) return; // 表满,实际应用中应处理
if (table[pos].first.empty()) {
table[pos] = make_pair(word, 1);
} else {
table[pos].second++;
}
}
int getFrequency(const string& word, int& asl) {
int index = hashFunction(word);
searchCount = 0;
int pos = probe(index, word, false);
asl = searchCount;
return pos != -1 ? table[pos].second : -1;
}
void saveToFile(const string& filename) {
vector<pair<string, int>> words;
for (int i = 0; i < TABLE_SIZE; ++i) {
if (!table[i].first.empty()) {
words.push_back(table[i]);
}
}
sort(words.begin(), words.end());
ofstream outFile(filename);
for (const auto& p : words) {
outFile << p.first << " " << p.second << endl;
}
outFile.close();
}
};
// ====================== 6. 基于链地址法的哈希查找 ======================
class SeparateChainingHash {
private:
static const int TABLE_SIZE = 1000;
vector<list<pair<string, int>>> table;
int searchCount;
int hashFunction(const string& word) {
hash<string> hasher;
return hasher(word) % TABLE_SIZE;
}
public:
SeparateChainingHash() : searchCount(0), table(TABLE_SIZE) {}
void insertOrIncrement(const string& word) {
int index = hashFunction(word);
searchCount = 0;
for (auto& p : table[index]) {
searchCount++;
if (p.first == word) {
p.second++;
return;
}
}
table[index].emplace_back(word, 1);
searchCount++;
}
int getFrequency(const string& word, int& asl) {
int index = hashFunction(word);
searchCount = 0;
for (const auto& p : table[index]) {
searchCount++;
if (p.first == word) {
asl = searchCount;
return p.second;
}
}
asl = searchCount;
return -1;
}
void saveToFile(const string& filename) {
vector<pair<string, int>> words;
for (const auto& bucket : table) {
for (const auto& p : bucket) {
words.push_back(p);
}
}
sort(words.begin(), words.end());
ofstream outFile(filename);
for (const auto& p : words) {
outFile << p.first << " " << p.second << endl;
}
outFile.close();
}
};
// 主程序
int main() {
// 初始化6种数据结构
SequentialList seqList;
LinkedList linkedList;
BinarySearchList binSearchList;
BST bst;
OpenAddressingHash openHash;
SeparateChainingHash sepChainHash;
// 读取输入文件
ifstream inFile("InFile.txt");
if (!inFile) {
cerr << "无法打开输入文件 InFile.txt" << endl;
return 1;
}
string word;
while (inFile >> word) {
string processed = processWord(word);
if (!processed.empty()) {
seqList.insertOrIncrement(processed);
linkedList.insertOrIncrement(processed);
binSearchList.insertOrIncrement(processed);
bst.insertOrIncrement(processed);
openHash.insertOrIncrement(processed);
sepChainHash.insertOrIncrement(processed);
}
}
inFile.close();
// 保存结果到6个不同的文件
seqList.saveToFile("OutFile1.txt");
linkedList.saveToFile("OutFile2.txt");
binSearchList.saveToFile("OutFile3.txt");
bst.saveToFile("OutFile4.txt");
openHash.saveToFile("OutFile5.txt");
sepChainHash.saveToFile("OutFile6.txt");
// 单词检索功能
while (true) {
cout << "\n请输入要查找的单词(输入q退出): ";
string searchWord;
cin >> searchWord;
if (searchWord == "q") break;
string processedSearch = processWord(searchWord);
if (processedSearch.empty()) {
cout << "无效的单词" << endl;
continue;
}
int asl;
int freq;
auto start = high_resolution_clock::now();
// 测试每种查找方法
cout << "\n1. 基于顺序表的顺序查找:" << endl;
start = high_resolution_clock::now();
freq = seqList.getFrequency(processedSearch, asl);
auto duration = duration_cast<microseconds>(high_resolution_clock::now() - start);
if (freq != -1) {
cout << "频率: " << freq << ", ASL: " << asl << ", 时间: " << duration.count() << "微秒" << endl;
} else {
cout << "查找失败, ASL: " << asl << ", 时间: " << duration.count() << "微秒" << endl;
}
cout << "2. 基于链表的顺序查找:" << endl;
start = high_resolution_clock::now();
freq = linkedList.getFrequency(processedSearch, asl);
duration = duration_cast<microseconds>(high_resolution_clock::now() - start);
if (freq != -1) {
cout << "频率: " << freq << ", ASL: " << asl << ", 时间: " << duration.count() << "微秒" << endl;
} else {
cout << "查找失败, ASL: " << asl << ", 时间: " << duration.count() << "微秒" << endl;
}
cout << "3. 基于顺序表的折半查找:" << endl;
start = high_resolution_clock::now();
freq = binSearchList.getFrequency(processedSearch, asl);
duration = duration_cast<microseconds>(high_resolution_clock::now() - start);
if (freq != -1) {
cout << "频率: " << freq << ", ASL: " << asl << ", 时间: " << duration.count() << "微秒" << endl;
} else {
cout << "查找失败, ASL: " << asl << ", 时间: " << duration.count() << "微秒" << endl;
}
cout << "4. 基于二叉排序树的查找:" << endl;
start = high_resolution_clock::now();
freq = bst.getFrequency(processedSearch, asl);
duration = duration_cast<microseconds>(high_resolution_clock::now() - start);
if (freq != -1) {
cout << "频率: " << freq << ", ASL: " << asl << ", 时间: " << duration.count() << "微秒" << endl;
} else {
cout << "查找失败, ASL: " << asl << ", 时间: " << duration.count() << "微秒" << endl;
}
cout << "5. 基于开放地址法的哈希查找:" << endl;
start = high_resolution_clock::now();
freq = openHash.getFrequency(processedSearch, asl);
duration = duration_cast<microseconds>(high_resolution_clock::now() - start);
if (freq != -1) {
cout << "频率: " << freq << ", ASL: " << asl << ", 时间: " << duration.count() << "微秒" << endl;
} else {
cout << "查找失败, ASL: " << asl << ", 时间: " << duration.count() << "微秒" << endl;
}
cout << "6. 基于链地址法的哈希查找:" << endl;
start = high_resolution_clock::now();
freq = sepChainHash.getFrequency(processedSearch, asl);
duration = duration_cast<microseconds>(high_resolution_clock::now() - start);
if (freq != -1) {
cout << "频率: " << freq << ", ASL: " << asl << ", 时间: " << duration.count() << "微秒" << endl;
} else {
cout << "查找失败, ASL: " << asl << ", 时间: " << duration.count() << "微秒" << endl;
}
}
return 0;
}找出代码中不适合c++5.11的运行的,并修改
最新发布