说来惭愧,大一用codeblock学了C++后就没再碰过C++。最近开始学图像压缩,需要C++实现,我就下载了VS。
结果问题很多,首先软件没用过,然后就是C++语法忘了很多,得补一补。刚刚抄了数据结构课本的哈夫曼算法代码,编译后各种报错,一谷歌发现都是小问题。诶,丢人啊。
代码
头文件:hfTree.h
#pragma once
#include <string>
#include <iostream>
using namespace std;
#ifndef _hfTree_h
#define _hfTree_h
template<class Type>
class hfTree {
private:
struct Node //数组中的元素类型
{
Type data;
int weight;
int parent, left, right;
};
Node* elem;
int length;
public:
struct hfCode
{
Type data;
string cod;
};
hfTree(const Type *x,const int *w,int size);
void getCode(hfCode result []);
~hfTree() { delete[] elem; }
};
#endif
//构造函数定义
template<class Type>
hfTree<Type>::hfTree(const Type* v, const int* w, int size)
{
const int MAX_INT = 32767;
int min1, min2; //最小树和次小树的权值
int x, y; //。。。的下标
//设置处置
length = 2 * size;
elem = new Node[length];
for (int i = size; i < length; ++i) {
elem[i].weight = w[i - size];
elem[i].data = v[i - size];
elem[i].parent = elem[i].left = elem[i].right = 0;
}
//归并树
for (int i = size - 1; i > 0; --i) {
min1 = min2 = MAX_INT;
x = y = 0;
for (int j = i + 1; j < length; ++j)
if (elem[j].parent == 0)
if (elem[j].weight < min1) {
min2 = min1;
min1 = elem[j].weight;
x = y;
y = j;
}
else if (elem[j].weight < min2) {
min2 = elem[j].weight;
x = j;
}
elem[i].weight = min1 + min2;
elem[i].left = x;
elem[i].right = y;
elem[i].parent = 0;
elem[x].parent = i;
elem[y].parent = i;
}
}
//getCode函数定义
template<class Type>
void hfTree<Type>::getCode(hfCode result[])
{
int size = length / 2;
int p, s;
for (int i = size; i < length; ++i) {
result[i - size].data = elem[i].data;
result[i - size].cod = "";
p = elem[i].parent;
s = i;
while (p) {
if (elem[p].left == s)
result[i - size].cod = '0' + result[i - size].cod;
else result[i - size].cod = '1' + result[i - size].cod;
s = p;
p = elem[p].parent;
}
}
}
cpp文件
#include "hfTree.h"
#include <iostream>
using namespace std;
int main()
{
char ch[] = { "aeistdn" };
int w[] = { 10,15,12,3,4,13,1 };
hfTree<char> tree(ch, w, 7);
hfTree<char>::hfCode result[7];
tree.getCode(result);
for (int i = 0; i < 7; ++i)
cout << result[i].data << ' ' << result[i].cod << endl;
return 0;
}
注意
1 LNK2019: 无法解析的外部符号
不要把头文件中的模板类定义和声明分成两个文件,不然会报错。当然也有办法分开且不报错,但没必要。
2 未知重写说明符
类中有string,得在头文件加上using namespace std;
如果用到了<<运算符,还得加上#include <string>