ACM--Entrophy(哈希+數組 建樹)

//採用哈希的思想建哈夫曼樹 
//0-9對應的數組地址1-10   A-Z對應的數組11-36  '_'則是37  
//新生成的N-1課樹從38開始建立 


#include<iostream>
#include<string.h>
#include<iomanip>
using namespace std;
int T[100][5];
void select(int &min,int &max)
{
	int Min_val=9999999;
	int Min_i;
	for(int i=min;i<=max;i++)	
	if(T[i][0]<Min_val&&T[i][1]==0)//選擇沒父親的樹 
	{
	   	  Min_val=T[i][0];
	   	  Min_i=i;
	}
	int Max_i;
	int Max_val=9999999;
	for(int i=min;i<=max;i++)	
	{
    	if(i==Min_i)
	      continue;
	    if(T[i][0]<Max_val&&T[i][1]==0)
	   {
	   	  Max_val=T[i][0];
	   	  Max_i=i;
   	   }
	}
	min=Min_i;
	max=Max_i;	
}
int main()
{
	string n;	
	while(getline(cin,n),n!="END")
	{  
	   int lenth=n.size();
		for(int i=1;i<100;i++)
		{
		    T[i][1]=-1;T[i][0]=0;//所有結點的權重初始爲0,父親爲-1 
		}
	  for(int i=0;i<lenth;i++)
	  {
	     if(n[i]>='A'&&n[i]<='Z')
		{
		    T[n[i]-54][0]++; T[n[i]-54][1]=0;
		}
	    if(n[i]>='0'&&n[i]<='9')
		{
		    T[n[i]-47][0]++;T[n[i]-47][1]=0;
		}
	    if(n[i]=='_')
		{		   
		    T[n[i]-58][0]++; T[n[i]-58][1]=0; 	
	    }	   
	  }  	
	  int sum=0;
	  for(int i=1;i<100;i++)
	     if(T[i][0])
	       sum++;	  
	  int flag=0;
	  if(sum==1)
	    flag=1;	  	  
	  int max=37;
	  int j=max;
      int min=1;
	  while(j<=37+sum-2)
      {  
	     select(min,max);
      	 T[j+1][0]=T[min][0]+T[max][0];//新的樹的權重等於兩個孩子的權重和 
      	 T[j+1][2]=min;T[j+1][3]=max;//新的樹的左右孩子的地址 
      	 T[j+1][1]=0;//新的樹的父親爲0       	 
      	 T[min][1]=j+1;T[max][1]=j+1; //左右子樹的父親爲 j+1      	 
      	 j++;
		 max=j;
		 min=1;     	
      }
      for(int i=1;i<=37;i++)
	  {
	  	if(T[i][1]!=-1)
	  	{   	  	     	      
            int j=i; 
	  		int temp=0;
	  		while(T[j][1])
	  		{   
	  		   temp++;
	  			j=T[j][1];
	  			
	  		}
	  		T[i][4]=temp;
	  	}
	  }
	  sum=0;
      for(int i=0;i<lenth;i++)
      {
      	if(n[i]>='A'&&n[i]<='Z')
		{
		    sum+=T[n[i]-54][4];
		}
	    if(n[i]>='0'&&n[i]<='9')
		{
		    sum+=T[n[i]-47][4];
		}
	    if(n[i]=='_')
		{		   
		    sum+=T[n[i]-58][4]; 
	    }	        	
      }
      if(flag)
         sum=lenth;
      cout<<lenth*8<<" "<<sum<<" ";
      cout<<fixed<<setprecision(1)<<(float)lenth*8/(float)sum<<endl;	
	}
	
	
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章