实验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;
}
posted @ 2024-12-22 11:56  这题太难了  阅读(19)  评论(0)    收藏  举报