实验5到实验8
实验五 哈夫曼编码算法的实现
点击查看代码
#include <iostream>
#include <fstream>
#include <queue>
#include <map>
#include <vector>
#include <string>
#include <bitset>
#include <sstream>
using namespace std;
struct Huffm {
char chrs;
int fre;
Huffm* left;
Huffm* right;
Huffm(char c, int freq) : chrs(c), fre(freq), left(nullptr), right(nullptr) {}
Huffm(Huffm* l, Huffm* r) : chrs('\0'), fre(l->fre + r->fre), left(l), right(r) {}
};
struct Compare {
bool operator()(Huffm* lhs, Huffm* rhs) {
return lhs->fre > rhs->fre;
}
};
// 生成哈夫曼编码
void g_Huffm(Huffm* root, const string& str, map<char, string>& hu) {
if (!root) return;
if (!root->left && !root->right)
hu[root->chrs] = str;
g_Huffm(root->left, str + "0", hu);
g_Huffm(root->right, str + "1", hu);
}
// 统计字符频率
map<char, int> c_Chr(const string& filename) {
ifstream file(filename);
map<char, int> fre_Map;
char c;
if (!file.is_open()) {
cerr << "无法打开文件 " << filename << endl;
exit(EXIT_FAILURE);
}
while (file.get(c))
fre_Map[c]++;
return fre_Map;
}
// 创建哈夫曼树
Huffm* huffmtree(const map<char, int>& fremap) {
priority_queue<Huffm*, vector<Huffm*>, Compare> minHeap;
for (const auto& pair : fremap)
minHeap.push(new Huffm(pair.first, pair.second));
while (minHeap.size() > 1) {
Huffm* left = minHeap.top(); minHeap.pop();
Huffm* right = minHeap.top(); minHeap.pop();
Huffm* merged = new Huffm(left, right);
minHeap.push(merged);
}
return minHeap.top();
}
// 将编码写入文件
void w_HuffmF(const map<char, string>& huff, const string& filename) {
ofstream outFile(filename);
if (!outFile.is_open()) {
cerr << "无法打开文件 " << filename << endl;
exit(EXIT_FAILURE);
}
for (const auto& pair : huff)
outFile << pair.first << ": " << pair.second << endl;
}
// 对文件内容进行哈夫曼编码
void en_File(const string& s_File, const map<char, string>& huff, const string& r_File) {
ifstream inFile(s_File);
ofstream outFile(r_File, ios::binary);
stringstream enText;
char c;
if (!inFile.is_open()) {
cerr << "无法打开文件 " << s_File << endl;
exit(EXIT_FAILURE); // 如果无法打开源文件,则退出程序
}
while (inFile.get(c))
if (huff.find(c) != huff.end()_
enText << huff.at(c);
else {
cerr << "字符 " << c << " 未在哈夫曼编码表中找到" << endl;
exit(EXIT_FAILURE);
}
string bitString = enText.str();
while (bitString.size() % 8 != 0)
bitString += '0';
for (size_t i = 0; i < bitString.size(); i += 8) {
bitset<8> byte(bitString.substr(i, 8));
outFile.put(static_cast<char>(byte.to_ulong()));
}
}
int main() {
string s_File = "SourceFile.txt";
string codeFile = "Code.txt";
string resultFile = "ResultFile.txt";
map<char, int> fre_Map = c_Chr(s_File);
if (fre_Map.empty()) {
cerr << "源文件中没有有效字符!" << endl;
return EXIT_FAILURE;
}
Huffm* root = huffmtree(fre_Map);
map<char, string> huffmanCodes;
g_Huffm(root, "", huffmanCodes);
w_HuffmF(huffmanCodes, codeFile);
en_File(s_File, huffmanCodes, resultFile);
cout << "哈夫曼编码系统已完成!" << endl;
return 0;
点击查看代码
#include <iostream>
#include <vector>
#include <string>
#include <climits>
#include <map>
#include <fstream>
#include <algorithm>
using namespace std;
const int INF = INT_MAX;
// 邻接矩阵表示图
class Graph {
public:
vector<vector<int>> adjMatrix;
vector<string> places;
map<string, string> placesInfo;
Graph(int n) {
adjMatrix.resize(n, vector<int>(n, INF)); // 初始化邻接矩阵为无穷大
for (int i = 0; i < n; i++) {
adjMatrix[i][i] = 0;
}
}
void addEdge(int u, int v, int weight) {
adjMatrix[u][v] = weight;
adjMatrix[v][u] = weight;
}
void addPlaceInfo(const string& place, const string& info) {
placesInfo[place] = info;
}
void getPlaceInfo(const string& place) {
if (placesInfo.find(place) != placesInfo.end()) {
cout << place << ": " << placesInfo[place] << endl;
}
else {
cout << "景点未找到!" << endl;
}
}
// Dijkstra 算法计算最短路径
void dijkstra(int start, int end) {
int n = places.size();
vector<int> dist(n, INF);
vector<int> prev(n, -1);
vector<bool> visited(n, false);
dist[start] = 0;
for (int i = 0; i < n; i++) {
int u = -1;
for (int j = 0; j < n; j++) {
if (!visited[j] && (u == -1 || dist[j] < dist[u])) {
u = j;
}
}
if (dist[u] == INF) break;
visited[u] = true;
for (int v = 0; v < n; v++) {
if (adjMatrix[u][v] != INF && dist[u] + adjMatrix[u][v] < dist[v]) {
dist[v] = dist[u] + adjMatrix[u][v];
prev[v] = u;
}
}
}
// 追溯路径
vector<string> path;
for (int u = end; u != -1; u = prev[u]) {
path.push_back(places[u]);
}
reverse(path.begin(), path.end());
if (dist[end] == INF) {
cout << "没有路径从 " << places[start] << " 到 " << places[end] << endl;
}
else {
cout << "从 " << places[start] << " 到 " << places[end] << " 的最短路径是:";
for (const string& p : path) {
cout << p << " ";
}
cout << "路径长度:" << dist[end] << endl;
}
}
};
void readGraphFromFile(const string& filename, Graph& graph) {
ifstream file(filename);
if (!file.is_open()) {
cerr << "文件打开失败!" << endl;
return;
}
string u, v;
int weight;
map<string, int> placeIndex;
vector<string> places;
while (file >> u >> v >> weight) {
if (u == "0") break;
if (placeIndex.find(u) == placeIndex.end()) {
placeIndex[u] = places.size();
places.push_back(u);
}
if (placeIndex.find(v) == placeIndex.end()) {
placeIndex[v] = places.size();
places.push_back(v);
}
int uIndex = placeIndex[u];
int vIndex = placeIndex[v];
graph.addEdge(uIndex, vIndex, weight);
}
// 读取景点介绍信息
for (const auto& place : places) {
string info;
cout << "请输入景点 '" << place << "' 的介绍:";
cin.ignore();
getline(cin, info);
graph.addPlaceInfo(place, info);
graph.places.push_back(place);
}
file.close();
}
int main() {
Graph graph(10);
readGraphFromFile("graph.txt", graph);
while (true) {
cout << "\n菜单:" << endl;
cout << "1. 查询景点信息" << endl;
cout << "2. 查询最短路径" << endl;
cout << "3. 查看所有景点" << endl;
cout << "4. 退出" << endl;
cout << "请输入选择:";
int choice;
cin >> choice;
if (choice == 1) {
string place;
cout << "请输入景点名称:";
cin.ignore();
getline(cin, place);
graph.getPlaceInfo(place);
}
else if (choice == 2) {
string start, end;
cout << "请输入起始景点:";
cin.ignore();
getline(cin, start);
cout << "请输入目的景点:";
getline(cin, end);
int startIndex = find(graph.places.begin(), graph.places.end(), start) - graph.places.begin();
int endIndex = find(graph.places.begin(), graph.places.end(), end) - graph.places.begin();
graph.dijkstra(startIndex, endIndex);
}
else if (choice == 3) {
cout << "所有景点:\n";
for (const auto& place : graph.places) {
cout << place << endl;
}
}
else {
cout << "祝你玩得开心!" << endl;
break;
}
}
return 0;
}
点击查看代码
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
struct stu {
string name;
long long st;
double test;
}k[10000];
bool pan(stu a, stu b) { return a.st < b.st; } //sort函数的排序设定
int chu() { //初始化
int i = 0;
cout << "请按姓名、学号、成绩的顺序输入成绩:\n";
while (1) {
cout << "姓名(输入\"#\"结束): ";
cin >> k[i].name;
if (k[i].name == "#") break;
cout << "学号: ";
cin >> k[i].st;
cout << "成绩: ";
cin >> k[i++].test; cout << endl;
}
sort(k, k + i,pan); //按学号排序
return i;
}
void find1(string na,int n) { /姓名查找
for(int i=0;i<n;i++)
if (k[i].name == na) {
cout << "查找成功!信息如下:\n";
cout << "姓名:" << k[i].name << endl;
cout << "学号:" << k[i].st << endl;
cout << "成绩:" << k[i].test<< endl << endl;
return;
}
cout << "查无此人!" << endl << endl;
}
void find2(long long te,int n) { //学号查找
int l = 0, r = n - 1;
while (l <= r) {
int mid = l + r >> 1;
if (k[mid].st<te) l = mid+1;
else r = mid - 1;
}
if (k[l].st == te) {
cout << "查找成功!信息如下:\n";
cout << "姓名:" << k[l].name << endl;
cout << "学号:" << k[l].st << endl;
cout << "成绩:" << k[l].test << endl << endl;
return;
}
cout << "查无此人!" << endl << endl;
}
int main() {
int n=chu();
//for (int i = 0; i < n; i++) cout << k[i].name << ' ';
int m;
while (1) {
cout << "请输入1(按姓名查找)或 2 (按学号查找),其他(退出)\n";
cin >> m;
if (m == 1) {
string str;
cout << "请输入要查找的姓名: ";
cin >> str;
find1(str,n);
}
else if (m == 2) {
long long s;
cout << "请输入要查找的学号: ";
cin >> s;
find2(s,n);
}
else {
cout << "再见!";
break;
}
}
return 0;
}
点击查看代码
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
struct stu {
string name;
long long st;
double test;
}k[10000], k2[10000];
bool pan(stu a, stu b) { return a.st < b.st; }
int chu() {
int i = 0;
cout << "请按姓名、学号、成绩的顺序输入成绩:\n";
while (1) {
cout << "姓名(输入\"#\"结束): ";
cin >> k[i].name;
if (k[i].name == "#") break;
cout << "学号: ";
cin >> k[i].st;
cout << "成绩: ";
cin >> k[i].test; cout << endl;
k2[i] = k[i]; i++;
}
//sort(k, k + i, pan);
return i;
}
void xier(int len) {
int gap = len / 2;
for (; gap > 0; gap /= 2) {
for (int i = gap; i < len; i++) {
stu cur = k[i]; int j;
for (j = i - gap; j >= 0 && k[j].st > cur.st; j -= gap)
k[j + gap] = k[j];
k[j + gap] = cur;
}
}
}
void qui(int l, int r)
{
if (l >= r) return;
int i = l - 1, j = r + 1, x = k[l + r >> 1].test;
while (i < j)
{
do i++; while (k[i].test < x);
do j--; while (k[j].test > x);
if (i < j) swap(k[i], k[j]);
}
qui(l, j), qui(j + 1, r);
}
void printfs(stu p[], int n) {
printf("%5s%15s%5s\n", "姓名", "学号", "成绩");
for (int i = 0; i < n; i++) {
cout << p[i].name;
printf("%15lld%5.1lf\n", p[i].st, p[i].test);
}
}
int main() {
int i = chu();
int a;
while (1) {
cout << "请进行你的操作:\n";
cout << "1:按原始成绩单输出\n";
cout << "2:按学号输出\n";
cout << "3:按成绩排序输出\n";
cout << "其他:退出\n";
cin >> a;
switch (a)
{
case 1:printfs(k2, i); break;
case 2:xier(i);
printfs(k, i); break;
case 3:qui(0, i);
printfs(k, i); break;
default:
break;
}
if (a < 1 || a>3) break;
}
return 0;
}

浙公网安备 33010602011771号