资源描述
package mypackage;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.lang.*;
import javax.swing.Box;
public class hufman {
public static void main(String[] args)
{
myFrame my=new myFrame();
}
}
class myFrame extends Frame implements ActionListener,Runnable
{
public double[] frequences=new double[50];
public char[] letters=new char[50];
public Panel pan=new Panel(new BorderLayout());
public Label letter=new Label("输入编码字母:",Label.CENTER);
public Label frequence=new Label("对应频数(以逗号分隔):",Label.CENTER);
public Label words=new Label("输入报文:" ,Label.CENTER);
public Label mawen=new Label("输入码文:",Label.CENTER);
public Label translatedWords=new Label("语句:",Label.CENTER);
public TextField word=new TextField(12);
public TextField input1=new TextField(12);
public TextField input2=new TextField(12);
public TextField input3=new TextField(12);
public TextField input4=new TextField(12);
public Button compel=new Button("画树和编码");
public TextArea code=new TextArea("",10,3,TextArea.SCROLLBARS_BOTH);
public TextArea translation=new TextArea("",10,3,TextArea.SCROLLBARS_BOTH);
public TextField tranwords=new TextField(12);
public Label brand=new Label("编码后的码文");
public Label bras=new Label("编码情况");
public Label name=new Label("码文的翻译");
public Button trans=new Button("编码语句");
public Button controlTrads=new Button("译码");
public String yiwen="";
public String keyinformation="";
public painting paint=new painting();
public int lens;
public String bianma="";
public Thread dataLine=null;
public List list=null;
public Panel panaction=new Panel(new BorderLayout());
public myFrame()
{
super();
setSize(800,700);
this.setTitle("哈夫曼解码/译码器");
Font font=new Font("",Font.BOLD,20);
trans.addActionListener(this);
controlTrads.addActionListener(this);
code.setFont(font);
tranwords.setFont(font);
translation.setFont(font);
input1.setFont(font);
input2.setFont(font);
word.setFont(font);
input3.setFont(font);
input4.setFont(font);
Box boxh=Box.createVerticalBox();
Box boxa=Box.createVerticalBox();
Box boxu=Box.createHorizontalBox();
Box boxv=Box.createVerticalBox();
boxh.add(letter);
boxh.add(frequence);
boxh.add(words);
boxh.add(translatedWords);
boxh.add(mawen);
boxa.add(input1);
boxa.add(input2);
boxa.add(word);
boxa.add(input3);
boxa.add(input4);
boxu.add(boxh);
boxu.add(boxa);
boxv.add(boxu);
boxv.add(compel);
boxv.add(trans);
boxv.add(controlTrads);
boxv.add(name);
boxv.add(tranwords);
boxv.add(brand);
boxv.add(translation);
boxv.add(bras);
boxv.add(code);
pan.add("Center",boxv);
panaction.add("Center",paint);
Box boxg=Box.createHorizontalBox();
pan.setBackground(Color.gray);
boxg.add(pan);
boxg.add(panaction);
setLayout(new BorderLayout());
add("Center",boxg);
setVisible(true);
compel.addActionListener(this);
Thread kongzhi=new Thread(this);
kongzhi.start();
this.addWindowListener(new mywindowlistener());
}
public void run()
{
while(true)
if(input1.getText().length()!=0||input2.getText().length()!=0)
{
word.setEditable(false);
}
else if(word.getText().length()!=0)
{
input1.setEditable(false);
input2.setEditable(false);
}
else if(input1.getText().length()==0&&input2.getText().length()==0&&word.getText().length()==0)
{
input1.setEditable(true);
input2.setEditable(true);
word.setEditable(true);
}
}
public int getData()
{
String inputs1=input1.getText();
String inputs2=input2.getText();
String baowen=word.getText();
if(baowen.length()!=0)
{
bianma="";
input1.setText("");
input2.setText("");
code.setText("");
list=null;
int []flag=new int[50];
char[]arrayLetter=baowen.toCharArray();
int []count=new int[50];
int i,j;
for(i=0;i<arrayLetter.length;i++)
{
flag[i]=0;
count[i]=1;
}
for(i=0;i<arrayLetter.length;i++)
{
for(j=i+1;j<arrayLetter.length;j++)
{
if(flag[i]==0)
{
if(arrayLetter[i]==arrayLetter[j])
{
count[i]++;
flag[j]=-1;
}
}
}
}
for(i=0,j=0;j<arrayLetter.length;i++,j++)
{
if(flag[j]==-1)
{
i--;
}
else
{
frequences[i]=count[j]*1.0;
letters[i]=arrayLetter[j];
}
}
lens=i;
int total=0;
for(i=0;i<lens;i++)
{
total+=frequences[i];
}
for(i=0;i<lens;i++)
{
frequences[i]=frequences[i]/(total*1.0);
}
return 1;
}
else if((inputs1.length()!=0)&&(inputs2.length()!=0))
{
bianma="";
word.setText("");
code.setText("");
list=null;
String[]frequencesLike=inputs2.split(",");
if(frequencesLike.length==inputs1.length())
{
int i;
double total=0;
char[] letterLike=inputs1.toCharArray();
lens=letterLike.length;
for(i=0;i<letterLike.length;i++)
{
letters[i]=letterLike[i];
frequences[i]=Double.parseDouble(frequencesLike[i]);
total=total+frequences[i];
}
for(i=0;i<letterLike.length;i++)
{
frequences[i]=frequences[i]/(total*1.0);
}
lens=letterLike.length;
return 1;
}
else
return 0;
}
else
return 0;
}
public void DispLeaf(Node b)
{
if(b!=null)
{
if(b.lchild==null&&b.rchild==null)
{
if(keyinformation.startsWith(pelcode,0))
{
yiwen=yiwen+b.data;
int pointer=pelcode.length();
keyinformation=keyinformation.substring(pointer, keyinformation.length());
}
}
DispLeaf(b.lchild);
DispLeaf(b.rchild);
}
}
public void createCode(Node b)
{
if(b!=null)
{
if((b.lchild==null)&&(b.rchild==null))
{
Node currNode=b;
Node p=null;
int start=40;
char[] codeletter=new char[40];
while(currNode.parent!=null)
{
p=currNode.parent;
if(p.lchild==currNode)
{
start--;
codeletter[start]='0';
}
else if(p.rchild==currNode)
{
start--;
codeletter[start]='1';
}
currNode=p;
}
pelcode=new String(codeletter,start,40-start);
bianma=bianma+b.data+":"+pelcode+" ";
}
createCode(b.lchild);
createCode(b.rchild);
}
}
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("画树和编码"))
{
if(getData()==1)
{
list=new List(letters,frequences,lens);
paint.list=list;
paint.repaint();
}
createCode(list.head);
code.setText(bianma);
}
else if(e.getActionCommand().equals("编码语句"))
{
if(getData()==1)
{
char[]respondingCode;
Node importantNode=null;
String translatedWords="";
int i;
String wordsInformation=input3.getText();
respondingCode=wordsInformation.toCharArray();
for(i=0;i<respondingCode.length;i++)
{
importantNode=findNode(respondingCode[i]);
translatedWords=translatedWords+importantNpelcode;
this.translation.setText(translatedWords);
}
}
}
else if(e.getActionCommand().equals("译码"))
{
keyinformation=input4.getText();
while(keyinformation.length()>=1)
DispLeaf(paint.list.head);
tranwords.setText(yiwen);
}
}
public Node findNode(char letter)
{
Node returnNode=searchNode(paint.list.head,letter);
return returnNode;
}
public Node searchNode(Node currNode,char letter)
{
Node p;
if(currNode==null)
{
return null;
}
else if(currNode.data==letter)
{
return currNode;
}
else
{
p=searchNode(currNode.lchild,letter);
if(p!=null)
return p;
else
return searchNode(currNode.rchild,letter);
}
}
}
class painting extends Canvas implements ActionListener
{
public double r=14,l=100;
public int inix;
public int iniy;
public List list=null;
public Node[] queue=new Node[40];
public painting()
{
super();
setSize(400,300);
}
public void actionPerformed(ActionEvent e)
{
repaint();
}
public void paint(Graphics g)
{
Font font=new Font("",Font.BOLD,20);
int count=0;
if(list!=null)
{
inix=this.getWidth()/2;
iniy=30;
int head=-1;
int tail=0;
Node node=list.head;
node.x=(int)inix;
node.y=(int)iniy;
queue[tail]=node;
while(tail!=head)
{
head=(head+1)%40;
node=queue[head];
g.setColor(Color.blue);
g.drawOval((int)(node.x-r),(int)(node.y-r),(int)(2*r),(int)(2*r));
if(count==0)
{
g.setColor(Color.red);
g.setFont(font);
g.drawLine((int)(node.x-r*0.85),(int)(node.y+r/2),(int)(node.x-(l-r)*0.85),(int)(node.y+(l-r)/2));
g.drawString("0", (int)((node.x-r*0.85+node.x-(l-r)*0.85)/2), (int)((node.y+r/2+node.y+(l-r)/2)/2));
g.drawLine((int)(node.x+r*0.85),(int)(node.y+r/2),(int)(node.x+(l-r)*0.85),(int)(node.y+(l-r)/2));
g.drawString("1", (int)((node.x+r*0.85+node.x+(l-r)*0.85)/2),(int)((node.y+r/2+node.y+(l-r)/2)/2));
node.lchild.x=(int)(node.x-l*0.85);
node.lchild.y=(int)(node.y+l/2);
node.rchild.x=(int)(node.x+l*0.85);
node.rchild.y=(int)(node.y+l/2);
tail=(tail+1)%40;
queue[tail]=node.lchild;
tail=(tail+1)%40;
queue[tail]=node.rchild;
}
else
{
l=60;
if(node.lchild!=null&&node.rchild!=null)
{
g.setColor(Color.red);
g.setFont(font);
g.drawLine((int)(node.x-r/2),(int)(node.y+r*0.85),(int)(node.x-(l-r)/2),(int)(node.y+(l-r)*0.85));
g.drawString("0", (int)((node.x-r*0.85+node.x-(l-r)*0.85)/2), (int)((node.y+r/2+node.y+(l-r)/2)/2));
g.drawLine((int)(node.x+r/2),(int)(node.y+r*0.85),(int)(node.x+(l-r)/2),(int)(node.y+(l-r)*0.85));
g.drawString("1", (int)((node.x+r*0.85+node.x+(l-r)*0.85)/2),(int)((node.y+r/2+node.y+(l-r)/2)/2));
node.lchild.x=(int)(node.x-l/2);
node.lchild.y=(int)(node.y+l*0.85);
node.rchild.x=(int)(node.x+l/2);
node.rchild.y=(int)(node.y+l*0.85);
tail=(tail+1)%40;
queue[tail]=node.lchild;
tail=(tail+1)%40;
queue[tail]=node.rchild;
}
else
{
g.drawString(new Character(node.data).toString(),(int)(node.x)-3,(int)(node.y)+3);
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count++;
}
}
else
{
g.setFont(font);
g.drawString("画 布",this.getWidth()/2-5,this.getHeight()/2);
}
}
}
class Node
{
public String compelcode=null;
public double frequence;
public char data;
public Node lchild;
public Node rchild;
public Node parent;
public int x;
public int y;
public Node(double frequencelike,char datalike)
{
this.frequence=frequencelike;
this.data=datalike;
lchild=rchild=null;
parent=null;
}
}
class List
{
public double[] frequences=new double[50];
public char[] letters=new char[50];
public int lens;
public Node head=null;
public int[] flag=new int[50];
public List(char[] letterOut,double[] frequencesout,int len)
{
int i=0;
lens=len;
for(;i<len;i++)
{
frequences[i]=frequencesout[i];
letters[i]=letterOut[i];
flag[i]=0;
}
select();
}
public void select()
{
Node[] queue=new Node[50];
int []flagqueue=new int[50];
int b;
for(b=0;b<50;b++)
{
flagqueue[b]=0;
}
int top=-1;
while(check()==1)
{
double min2=1;
double min1=1;
int i=1;
int j=1;
double margin;
int k;
for(k=0;k<lens;k++)
{
if(flag[k]!=-1)
{
if(frequences[k]<min1)
{
min2=min1;
min1=frequences[k];
j=i;
i=k;
}
else if(frequences[k]<min2)
{
min2=frequences[k];
j=k;
}
}
}
//得到两个频率值最小的节点
margin=min1+min2;
Node single=new Node(margin,'j');
//对找出的这两个节点,建立在树中,建立父子的节点 关系,将新建的节点入队
if(flag[i]==1)
{
int counters;
for(counters=0;counters<=top;counters++)
if((queue[counters].frequence==frequences[i])&&flagqueue[counters]==0)
{
flagqueue[counters]=-1;
queue[counters].parent=single;
single.lchild=queue[counters];
break;
}
}
else
{
Node single1=new Node(frequences[i],letters[i]);
single1.parent=single;
single.lchild=single1;
}
if(flag[j]==1)
{
int counters;
for(counters=0;counters<=top;counters++)
if(queue[counters].frequence==frequences[j]&&flagqueue[counters]==0)
{
flagqueue[counters]=-1;
queue[counters].parent=single;
single.rchild=queue[counters];
flag[j]=-1;
break;
}
}
else
{
Node single2=new Node(frequences[j],letters[j]);
single.rchild=single2;
single2.parent=single;
flag[j]=-1;
}
flag[i]=1;
frequences[i]=margin;
top++;
queue[top]=single;
head=single;
}
}
public int check()
{
int counter=0;
int i;
for(i=0;i<lens;i++)
{
if((flag[i]==0)||(flag[i]==1))
{
counter++;
}
}
if(counter==1)
return 0;
else
return 1;
}
}
class mywindowlistener extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
}
}
展开阅读全文