我用的是clion编辑器
/Applications/CLion.app/Contents/bin/cmake/bin/cmake --build /Users/guchenghao/Library/Caches/CLion2016.1/cmake/generated/DataStructure_Huffman-c73727c9/c73727c9/Debug --target DataStructure_Huffman -- -j 4
[ 33%] Linking CXX executable DataStructure_Huffman
duplicate symbol __Z6SelectP6HTNodei in:
CMakeFiles/DataStructure_Huffman.dir/main.cpp.o
CMakeFiles/DataStructure_Huffman.dir/Huffman.cpp.o
duplicate symbol __Z18create_HuffmanTreePi in:
CMakeFiles/DataStructure_Huffman.dir/main.cpp.o
CMakeFiles/DataStructure_Huffman.dir/Huffman.cpp.o
duplicate symbol __Z11TestHufTreeP6HTNode in:
CMakeFiles/DataStructure_Huffman.dir/main.cpp.o
CMakeFiles/DataStructure_Huffman.dir/Huffman.cpp.o
ld: 3 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [DataStructure_Huffman] Error 1
make[2]: *** [CMakeFiles/DataStructure_Huffman.dir/all] Error 2
make[1]: *** [CMakeFiles/DataStructure_Huffman.dir/rule] Error 2
make: *** [DataStructure_Huffman] Error 2
main.cpp
#include <iostream>
#include <stdlib.h>
#include "Huffman.cpp"
using namespace std;
int main() {
cout<< "=========Huffman文件压缩=========" <<endl;
cout<<"请输入文件名:";
char filename[256];
cin>>filename;
int weight[256] = {0};
FILE *in = fopen(filename,"rb");
int ch;
while ((ch = fgetc(in)) != EOF) {
weight[ch]++;
}
fclose(in);
cout<<"Byte"<<" Weight"<<endl;
for (int i = 0; i < 256 ; ++i) {
printf("0x%02X %d\n",i,weight[i]);
}
HuffmanTree HT = create_HuffmanTree(weight);
cout<<"Byte"<<" Weight"<<" Parent"<<" Lchild"<<" Rchild"<<endl;
TestHufTree(HT);
return 0;
}
Huffman.cpp
#include "Huffman.h"
#include <iostream>
int Select(HuffmanTree pHT,int nSize) {
int minValue = 0x7FFFFFFF;
int min = 0;
for (int i = 0; i <= nSize ; ++i) {
if(pHT[i].parent == -1 && pHT[i].weight < minValue) {
minValue = pHT[i].weight;
min = i;
}
}
pHT[min].parent = 1;
return min;
}
HuffmanTree create_HuffmanTree(int weight[]) {
/*
根据给定的n个权值构造一棵赫夫曼树,wet中存放n个权值
*/
HuffmanTree HT = (HuffmanTree)malloc(511*sizeof(HTNode));
int i;
//一棵有n个叶子节点的赫夫曼树共有2n-1个节点
//以下初始化序号全部用-1表示,
//这样在编码函数中进行循环判断parent或lchild或rchild的序号时,
//不会与HT数组中的任何一个下标混淆
//HT[0],HT[1]...HT[n-1]中存放需要编码的n个叶子节点
for(i=0;i<256;i++)
{
HT[i].parent = -1;
HT[i].lchild = -1;
HT[i].rchild = -1;
HT[i].weight = weight[i];
}
//HT[n],HT[n+1]...HT[2n-2]中存放的是中间构造出的每棵二叉树的根节点
for(;i< 511;i++)
{
HT[i].parent = -1;
HT[i].lchild = -1;
HT[i].rchild = -1;
HT[i].weight = 0;
}
int min1,min2; //用来保存每一轮选出的两个weight最小且parent为0的节点
//每一轮比较后选择出min1和min2构成一课二叉树,最后构成一棵赫夫曼树
for(i = 256;i< 511;i++)
{
min1 = Select(HT,i);
min2 = Select(HT,i);
HT[min1].parent = i;
HT[min2].parent = i;
//这里左孩子和右孩子可以反过来,构成的也是一棵赫夫曼树,只是所得的编码不同
HT[i].lchild = min1;
HT[i].rchild = min2;
HT[i].weight =HT[min1].weight + HT[min2].weight;
}
return HT;
}
void TestHufTree(HuffmanTree pHT) {
for (int i = 0; i < 511 ; ++i) {
printf("pHT[%d]\t\d\t\d\t\d\t\d\n",i,pHT[i].weight,pHT[i].parent,pHT[i].lchild,pHT[i].rchild);
}
}
Huffman.h
#ifndef DATASTRUCTURE_HUFFMAN_HUFFMAN_H
#define DATASTRUCTURE_HUFFMAN_HUFFMAN_H
struct HTNode {
int weight;
int parent;
int lchild;
int rchild;
};
typedef HTNode *HuffmanTree;
#endif //DATASTRUCTURE_HUFFMAN_HUFFMAN_H
cmake_minimum_required(VERSION 3.5)
project(DataStructure_Huffman)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp Huffman.cpp)
add_executable(DataStructure_Huffman ${SOURCE_FILES} Huffman.h)
迷茫2017-04-17 13:41:07
I will use g++ to compile your source code
in main.cpp,
#include "Huffman.cpp"
should be changed to
#include "Huffman.h"
And add function declaration in Huffman.h.
HuffmanTree create_HuffmanTree(int weight[]);
void TestHufTree(HuffmanTree pHT);
You can take this opportunity to learn more about header file inclusion and why this is wrong.