1.C++霍夫曼解压程序源代码
2.ClickHouse 源码解析: MergeTree Merge 算法
3.求VC++源代码,源码200行左右,源码要有详细注释,源码悬赏!源码!源码!源码注册会员表单源码
C++霍夫曼解压程序源代码
#include<stdio.h>
#include<string.h>
#include<conio.h>
#include<stdlib.h>
#define MAX
struct link
{
int freq;
char ch[MAX];
struct link* right;
struct link* left;
};
typedef struct link node;
void sort(node *[],源码 int);
node* create(char[], int);
void sright(node *[], int);
void Assign_Code(node*, int [], int);
void Delete_Tree(node *);
main()
{
node* ptr, * head;
int i, n, total = 0, u, c[];
char str[MAX];
node* a[];
int freq;
clrscr();
printf( "Huffman Algorithm\n");
printf("\nEnter the no. of letter to be coded:");/*input
the no. of letters*/
scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("Enter the letter &
frequency:");/*input the letter & frequency*/
scanf("%s %d", str, &freq);
a[i] = create(str, freq);
}
while (n > 1)
{
sort(a, n);
u = a[0]->freq + a[1]->freq;
strcpy(str,a[0]->ch);
strcat(str,a[1]->ch);
ptr = create(str, u);
ptr->right = a[1];
ptr->left = a[0];
a[0] = ptr;
sright(a, n);
n--;
}
Assign_Code(a[0], c, 0);
getch();
Delete_Tree(a[0]);
}
node* create(char a[], int x)
{
node* ptr;
ptr = (node *) malloc(sizeof(node));
ptr->freq = x;
strcpy( ptr->ch , a);
ptr->right = ptr->left = NULL;
return(ptr);
}
void sort(node* a[], int n)
{
int i, j;
node* temp;
for (i = 0; i < n - 1; i++)
for (j = i; j < n; j++)
if (a[i]->freq > a[j]->freq)
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
void sright(node* a[], int n)
{
int i;
for (i = 1; i < n - 1; i++)
a[i] = a[i + 1];
}
void Assign_Code(node* tree, int c[], int n)
{
int i;
if ((tree->left == NULL) && (tree->right == NULL))
{
printf("%s code:", tree->ch);
for (i = 0; i < n; i++)
{
printf("%d", c[i]);
}
printf("\n");
}
else
{
c[n] = 1;
n++;
Assign_Code(tree->left, c, n);
c[n - 1] = 0;
Assign_Code(tree->right, c, n);
}
}
void Delete_Tree(node * root)
{
if(root!=NULL)
{
Delete_Tree(root->left);
Delete_Tree(root->right);
free(root);
}
}
ClickHouse 源码解析: MergeTree Merge 算法
ClickHouse MergeTree 「Merge 算法」 是对 MergeTree 表引擎进行数据整理的一种算法,也是源码 MergeTree 引擎得以高效运行的重要组成部分。
理解 Merge 算法,源码首先回顾 MergeTree 相关背景知识。源码ClickHouse 在写入时,源码将一次写入的源码数据存放至一个物理磁盘目录,产生一个 Part。源码然而,源码随着插入次数增多,源码查询时数据分布不均,形成问题。一种常见想法是合并小 Part,类似 LSM-tree 思想,网页打开app源码形成大 Part。
面临合并策略的选择,"数据插入后立即合并"策略会迅速导致写入成本失控。因此,需要在写入放大与 Part 数量间寻求平衡。ClickHouse 的 Merge 算法便是实现这一平衡的解决方案。
算法通过参数 base 控制参与合并的 Part 数量,形成树形结构。随着合并进行,okhttp源码系列之形成不同层,总层数为 MergeTree 的深度。当树处于均衡状态时,深度与 log(N) 成比例。base 参数用于判断参与合并的 Part 是否满足条件,总大小与最大大小之比需大于等于 base。
执行合并时机在每次插入数据后,但并非每次都会真正执行合并操作。对于给定的php执行linux源码多个 Part,选择最适合合并的组合是一个数学问题,ClickHouse 限制为相邻 Part 合并,降低决策复杂度。最终,通过穷举找到最优组合进行合并。
合并过程涉及对有序数组进行多路合并。ClickHouse 使用 Sort-Merge Join 类似算法,通过顺序扫描多个 Part 完成合并过程,保持有序性。影视析iapp源码算法复杂度为 Θ(M * N),其中 M 为 Part 长度,N 为参与合并的 Part 数量。
对于非主键字段,ClickHouse 提供两种处理方式:Horizontal 和 Vertical。Vertical 分为两个阶段,分别处理非主键字段的合并和输出。
源码解析包括 Merge 触发时机、选择需要合并的 Parts、执行合并等部分。触发时机主要在写入数据时,考虑执行 Mutate 任务后。选择需要合并的 Parts 通过 SimpleMergeSelector 实现,考虑了与 TTL 相关的特殊 Merge 类型。执行合并的类为 MergeTask,分为三个阶段:ExecuteAndFinalizeHorizontalPart、VerticalMergeStage。
Merge 算法是 MergeTree 高性能的关键,平衡写入放大与查询性能,是数据整理过程中的必要步骤。此算法通过参数和决策逻辑实现了在不同目标之间的权衡。希望以上信息能帮助你全面理解 Merge 算法。
求VC++源代码,行左右,要有详细注释,悬赏!!!
哈弗曼压缩
#include <string.h>
#include <stdlib.h>
#include<iostream.h>
#include<fstream.h>
#define MaxNodes
#define MaxBufSize
#define MaxBits
struct Node
{
unsigned char b;
int count;
int parent,lch,rch;
char bits[MaxBits];
}Nodes[MaxNodes];
ifstream ifile;
ofstream ofile;
char *fname=new char();
unsigned char c;
char buf[MaxBufSize];
int flen;
int NodesNum;
void decompress();
void compress();
void charCount();
void initNodes();
void creatHuffTree();
void huffCoding();
void sortByCount();
int FindMin(int curlen);
void comToFile();
void decomToFile();
void clearSDS();
void locChar(int loc,int i);
void main()
{
char choice;
while(1)
{
cout<<" ------------------------------------------------------"<<endl;
cout<<" # 0.退出 #"<<endl;
cout<<" # 1.压缩 #"<<endl;
cout<<" # 2.解压 #"<<endl;
cout<<" ------------------------------------------------------"<<endl;
do
{
cout<<"请选择:"<<endl;
cin>>choice;
if(choice!='0' && choice!='1' && choice!='2')
{
cout<<"输入出错!请重新输入!"<<endl;
}
}
while(choice!='0' && choice!='1' && choice!='2');
switch(choice)
{
case '0':cout<<"成功退出!"<<endl;exit(0); break;
case '1':compress();break;
case '2':decompress();break;
}
}
}
void compress()
{
cout<<"请输入待压缩的文件名:";
cin>>fname;
ifile.open(fname,ios::nocreate|ios::binary);
if(!ifile)
{
cout<<"文件不存在!"<<endl;
return;
}
charCount();
initNodes();
sortByCount();
creatHuffTree();
huffCoding();
cout<<"请输入压缩后的文件名:";
cin>>fname;
ofile.open(fname,ios::binary);
ofile.write((char*)&NodesNum,sizeof(NodesNum));
ofile.write((char*)&flen,sizeof(flen));
for(int i=0;i<NodesNum;i++)
{
ofile.write((char*)&Nodes[i].b,sizeof(Nodes[i].b));
ofile.write((char*)&Nodes[i].count,sizeof(Nodes[i].count));
}
comToFile();
ifile.close();
ofile.close();
clearSDS();
}
void decompress()
{
clearSDS();//不加此句,关闭程序再解压,会提示BUF出错
cout<<"请输入待解压的文件名:";
cin>>fname;
ifile.open(fname,ios::nocreate|ios::binary);
if(!ifile)
{
cout<<"文件不存在!"<<endl;
return;
}
ifile.read((char*)&NodesNum,sizeof(NodesNum));
ifile.read((char*)&flen,sizeof(flen));
cout<<NodesNum<<" "<<flen<<endl;
for(int i=0;i<NodesNum;i++)
{
ifile.read((char*)&Nodes[i].b,sizeof(Nodes[i].b));
ifile.read((char*)&Nodes[i].count,sizeof(Nodes[i].count));
}
creatHuffTree();
cout<<"请输入解压后的文件名:";
cin>>fname;
ofile.open(fname);
decomToFile();
ifile.close();
ofile.close();
clearSDS();
}
void clearSDS()//SDS is short for Shared Data Structure
{
NodesNum=flen=c=0;
for(int i=0;i<MaxNodes;i++)
{
Nodes[i].b=0;
Nodes[i].count=0;
Nodes[i].parent=Nodes[i].lch=Nodes[i].rch=-1;
buf[i]=0;
for(int j=0;j<MaxBits;j++) Nodes[i].bits[j]=0;
}
}
void comToFile()
{
ifile.clear();
ifile.seekg(0);
char tbuf[]="";
while(ifile.get(c))
{
for(int i=0;i<NodesNum;i++)
{
if(c==Nodes[i].b)
{
strcat(buf,Nodes[i].bits);
break;
}
}
while(strlen(buf)>=8)
{
memcpy(tbuf,buf,8);
c=(char)strtol (tbuf,NULL,2);
memmove(buf,buf+8,strlen(buf)+1-8);
ofile.write((char*)&c,sizeof(c));
}
}
if(strlen(buf)>0)//剩余
{
strcat(buf,"");//最多接7个0即可
memcpy(tbuf,buf,8);
c=(char)strtol (tbuf,NULL,2);
ofile.write((char*)&c,sizeof(c));
}
}
void decomToFile()
{
while (ifile.get(c)) //while(!ifile.eof()),老样子
{ //ifile.read((char*)&c,sizeof(c));
char tbuf[]="";
char rbuf[]="";
itoa((int)c,rbuf,2);
strcpy(tbuf+8-strlen(rbuf),rbuf);
memmove(buf+strlen(buf),tbuf,8);//末尾会多一个tbuf,无碍
while(strlen(buf)>&&flen>0) locChar(2*NodesNum-2,0);
}
while(strlen(buf)>0&&flen>0) locChar(2*NodesNum-2,0);
}
void locChar(int loc,int i)//递归得出字符
{
if((Nodes[loc].lch==-1)&&(Nodes[loc].rch==-1))
{
ofile.write((char*)&Nodes[loc].b,sizeof(Nodes[loc].b));
flen--;
//memmove(buf,buf+i,strlen(buf)-i+1);
//memmove(buf,buf+i,-i);//Very improtant code modified at here!
memcpy(buf,buf+i,-i);//Same result Like the line Above!Maybe not effective
return;
}
else
{
switch( buf[i])
{
case '0': loc=Nodes[loc].lch;break;
case '1': loc=Nodes[loc].rch;break;
default: cout<<"buf中出错!"<<endl;break;
}
i++;
locChar(loc,i);
}
}
void charCount()//统计字符出现次数
{
while(ifile.get(c))
{
Nodes[c].count++;
flen++;//得出文件长度
}
}
void initNodes()//初始化
{
for(int i=0;i<MaxNodes;i++)
{
if(Nodes[i].count!=0)
Nodes[i].b=(unsigned char)i;
else Nodes[i].b=0;
Nodes[i].parent=Nodes[i].lch=Nodes[i].rch=-1;
}
}
void creatHuffTree()//建树
{
int t=2*NodesNum-1;
for(int i=NodesNum;i<t;i++)
{
int loc=FindMin(i);
Nodes[i].count=Nodes[loc].count;
Nodes[loc].parent=i;
Nodes[i].lch=loc;
loc=FindMin(i);
Nodes[i].count+=Nodes[loc].count;
Nodes[loc].parent=i;
Nodes[i].rch=loc;
}
Nodes[t-1].parent=-1;
}
int FindMin(int curlen)//找没有父结点,且Count最小的节点
{
int loc=curlen-1;//找不到,返回最后一个,最后一个不在查找范围
for(int i=0;i<curlen;i++)
{
if(Nodes[i].count<=Nodes[loc].count)
{
if(Nodes[i].parent==-1)
loc=i;
}
}
return loc;
}
void huffCoding()//根据树来编码
{
int Pid,t;//Parent id
for(int i=0;i<NodesNum;i++)
{
t=i;
while(Nodes[t].parent!=-1)
{
Pid=Nodes[t].parent;
if(Nodes[Pid].lch==t) //置左分支编码0
{ //函数原型:void *memmove( void *dest, const void *src, size_t count );
memmove(Nodes[i].bits+1,Nodes[i].bits,strlen(Nodes[i].bits)+1);
Nodes[i].bits[0]='0';
}
else //置右分支编码1
{
memmove(Nodes[i].bits+1,Nodes[i].bits,strlen(Nodes[i].bits)+1);
Nodes[i].bits[0]='1';
}
t=Pid;
}
}
}
//降序
void sortByCount()
{
Node tempNode;
for(int i=0;i<MaxNodes;i++)
for(int j=MaxNodes-1;j>i;j--)
{
if(Nodes[i].count<Nodes[j].count)
{
tempNode=Nodes[i];
Nodes[i]=Nodes[j];
Nodes[j]=tempNode;
}
}
for(i=0;i<MaxNodes;i++) if(Nodes[i].count==0) break;
NodesNum=i;//关键得出有效叶子结点个数NodesNum
}