㈠ 哈夫曼編、解碼器
這個是我課程設計弄的,也是哈弗曼編碼解碼器
#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
typedef struct{
int weight;
int parent,lchild,rchild;
int asc;
}HTNode,*HuffmanTree; //定義赫夫曼存儲結構
struct node{
int ASCII;
int n;
};
struct node a[127];
struct node w[127];
//一些全局變數
int count;
HTNode H_T[250];
char ** HC;
char filename[20];
//函數聲明
void menu1(); //菜單1
HuffmanTree HeapSort(HuffmanTree HT,int length); //堆排序
void MinHeapify(HuffmanTree HT, int k,int len); //調整成一個小頂堆
void buildMinHeap(HuffmanTree HT,int len); //建一個小頂堆
void swap(HTNode &t1,HTNode &t2); //交換兩結構體
void savefile(); //把輸入的英文文章保存到文件
void loadfile(); //從文件中讀取文章
HuffmanTree CreateHuffman(HuffmanTree &HT,struct node *w,int n); //建立赫夫曼數並存入文件
void BianMa(HuffmanTree HT,int n ); //字元編碼
void BianMa_all(HuffmanTree HT,char**HC,char *filename); //整篇文章編碼
int loadfile2(); //從文件讀入文章
void JieMa(); //解碼
//主函數
int main()
{
char s;
while(s!='0')
{
system("cls");
cout<<"\n\n\n";
cout<<"\t\t\t\t赫夫曼編碼/解碼器"<<endl<<endl<<endl<<endl<<endl;
cout<<"\t\t\t\t 1.編碼"<<endl<<endl<<endl<<endl;
cout<<"\t\t\t\t 2.解碼"<<endl<<endl<<endl<<endl;
cout<<"\t\t\t\t 0.退出"<<endl<<endl<<endl<<endl;
cout<<"\t請輸入0—2進行選擇,按回車確認";
cin>>s;
switch(s)
{
case '1': menu1(); break;
case '2':
{
system("cls");
JieMa();
system("pause");
break;
}
}
}
}
//菜單1
void menu1(){
char s;
int i;
int a;
char c;
char fpname[20]="article.txt";
HuffmanTree HT;
while(s!='0'){
system("cls");
cout<<"\n\t\t\t\t編碼界面";
cout<<"\n\n\n\t\t\t\t1.輸入英文文章"<<endl;
cout<<"\n\n\t\t\t\t2.從文件中讀入文章"<<endl;
cout<<"\n\n\t\t\t\t0.返回上一層"<<endl;
cout<<"\n\t請輸入0—2進行選擇,按回車確認";
cin>>s;
switch(s){
case'1':
system("cls");
savefile();
loadfile();
CreateHuffman(HT,w,count);
BianMa(HT,count);
BianMa_all(HT,HC,fpname);
system("cls");
cout<<"出現字元種類共計:";
cout<<count<<endl;
for(i=1;i<=count;i++)
{ a=HT[i].asc;
c=(char)a;
cout<<"________________________________________________________________________________"<<endl;
cout<<"\t\t\t字元:";
cout<<c<<endl;
cout<<"\t\t\tASCII碼:";
cout<<a<<endl;
cout<<"\t\t\t頻數:";
cout<<HT[i].weight<<endl;
cout<<"\t\t\t赫夫曼編碼:";
cout<<HC[i]<<endl;
}
cout<<"________________________________________________________________________________";
cout<<"\n\t\t整篇文章的編碼已存入文件「赫夫曼編碼.txt」"<<endl;
system("pause");
break;
case'2':
system("cls");
if(loadfile2())
{ system("pause");
return;}
CreateHuffman(HT,w,count);
BianMa(HT,count);
BianMa_all(HT,HC,filename);
system("cls");
cout<<"出現字元種類共計:";
cout<<count<<endl;
for(i=1;i<=count;i++)
{ a=HT[i].asc;
c=(char)a;
cout<<"________________________________________________________________________________"<<endl;
cout<<"\t\t\t字元:";
cout<<c<<endl;
cout<<"\t\t\tASCII碼:";
cout<<a<<endl;
cout<<"\t\t\t頻數:";
cout<<HT[i].weight<<endl;
cout<<"\t\t\t赫夫曼編碼:";
cout<<HC[i]<<endl;
}
cout<<"________________________________________________________________________________";
cout<<"\n\t\t整篇文章的編碼已存入文件「赫夫曼編碼.txt」"<<endl;
system("pause");
break;
}
}
}
//交換結構體
void swap(HTNode &t1,HTNode &t2)
{
HTNode m;
m = t1;
t1 = t2;
t2 = m;
}
//從鍵盤輸入文章並保存
void savefile(){
FILE *fp;
char article;
if((fp=fopen("article.txt","w"))==NULL){
printf("打開文件不成功!");
exit(0);
}
cout<<"請輸入英文文章,以#結束:";
getchar();
article=getchar();
while(article!='#'){
fputc(article,fp);
article=getchar();
}
fclose(fp);
}
//從文件讀取文章,並統計字元出現頻數
void loadfile(){
FILE *fp;
char ch;
int i,k,j=0;
count=0;
for(i=0;i<=127;i++) //把所有字元的ascii碼存在數組
{ a[i].ASCII=i;
a[i].n=0;
}
if((fp=fopen("article.txt","r"))==NULL){
printf("打開文件不成功!");
exit(0);
}
ch=fgetc(fp);
k=(int)ch;
a[k].n++;
while(!feof(fp)){
ch=fgetc(fp);
k=(int)ch;
a[k].n++;
}
fclose(fp);
for(i=0;i<=127;i++) //統計字元種類總數
{
ch=(char)i;
if(a[i].n){
count++;
}
}
for(i=0;i<=127;i++)
{
for(;j<count;)
{
if(a[i].n)
{
w[j].n=a[i].n;
w[j].ASCII=a[i].ASCII;
j++;
break;
}
else break;
}
}
}
//調整為小頂堆
void MinHeapify(HuffmanTree HT, int k,int len)
{
int left=k*2;
int right=k*2+1;
int large;
int l=len;
large = k;
if (left<=l&&HT[left].weight<HT[large].weight)
large = left;
if (right<=l&& HT[right].weight<HT[large].weight)
large=right;
if (large!=k)
{
swap(HT[k],HT[large]);
MinHeapify(HT,large,l);
}
}
//建立小頂堆
void buildMinHeap(HuffmanTree HT,int len)
{
int i;
for (i=len/2;i>=1;i--)
{
MinHeapify(HT,i,len);
}
}
//堆排序
HuffmanTree HeapSort(HuffmanTree HT,int length)
{
int i;
int l=length;
buildMinHeap(HT,length);
for (i=length;i>= 2;i--)
{
swap(HT[1],HT[i]);
length--;
MinHeapify(HT,1,length);
}
return HT;
}
//建立赫夫曼數
HuffmanTree CreateHuffman(HuffmanTree &HT,struct node *w,int n)
{
int i,m,s1,s2,k1,k2,j,x,a;
FILE *fp,*fp2;
if(n<=1) return HT;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0不用
for(i=1,j=0;i<=n;i++,j++)
{ HT[i].asc=w[j].ASCII;
HT[i].weight=w[j].n;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(;i<=m;i++)
{ a=250+i;
HT[i].asc=a;//父親節點的asc可以是大於127的任意值
HT[i].weight=0;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(i=1;i<=n;i++){
H_T[i].asc=HT[i].asc;
H_T[i].parent=HT[i].parent;
H_T[i].lchild=HT[i].lchild;
H_T[i].rchild=HT[i].rchild;
H_T[i].weight=HT[i].weight;
}
for(i=n+1,x=n;i<=m;i++,x--)
{
HeapSort(H_T,x);
k1=H_T[x].asc;
k2=H_T[x-1].asc;
for(j=1;j<=127;j++)
{
if(HT[j].asc==k1)
}
for(j=1;j<=127;j++)
{
if(HT[j].asc==k2)
}
HT[s2].parent=i;
HT[s1].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
H_T[x-1].asc=HT[i].asc;
H_T[x-1].lchild=HT[i].lchild;
H_T[x-1].parent=HT[i].parent;
H_T[x-1].rchild=HT[i].rchild;
H_T[x-1].weight=HT[i].weight;
}
if((fp2=fopen("count.txt","w"))==NULL) //保存赫夫曼樹
{
cout<<"文件打開不成功!"<<endl;
exit(0);
}
fputc(count,fp2);
if((fp=fopen("HuffmanTree.dat","wb"))==NULL)
{ cout<<"文件打開不成功!"<<endl;
exit(0);
}
for(i=1;i<=(2*count-1);i++){
fwrite(&HT[i],sizeof(HTNode),1,fp);
}
fclose(fp);
fclose(fp2);
return HT;
}
//逆向編碼
void BianMa(HuffmanTree HT,int n){
char *cd,temp;
int c,f,i,j,len,p,q;
cd=(char *)malloc(n*sizeof(char));
HC=(char * *)malloc(n*sizeof(char*));
for(i=1;i<=n;i++){
for(c=i,f=HT[i].parent,j=0;f!=0;c=f,f=HT[f].parent,j++)
{ if(HT[f].lchild==c) cd[j]='0';
else cd[j]='1';
if(HT[f].parent==0)
cd[j+1]='\0';
}
len=strlen(cd);
for(p=0,q=len-1;p<=q;p++,q--)
{
temp=cd[q];
cd[q]=cd[p];
cd[p]=temp;
}
cd[len]='\0';
HC[i]=(char*)malloc((len+10)*sizeof(char));
strcpy(HC[i],cd);
}
}
//整篇文章編碼,並存入文件
void BianMa_all(HuffmanTree HT,char**HC,char *filename){
char ch;
int k,i;
FILE *fp,*fp2;
char code[100];
if((fp=fopen(filename,"r"))==NULL){
printf("打開文件不成功!");
exit(0);
}
if((fp2=fopen("赫夫曼編碼.txt","w"))==NULL){
printf("打開文件不成功!");
exit(0);
}
ch=fgetc(fp);
k=(int)ch;
while(!feof(fp))
{
for(i=1;i<=count;i++)
{
if(k==HT[i].asc)
strcpy(code,HC[i]);
}
fputs(code,fp2);
ch=fgetc(fp);
k=(int)ch;
}
fclose(fp);
fclose(fp2);
}
void JieMa(){
int i,k,a,t,n=0;
FILE *fp1,*fp2,*fp3;
char ch,c;
HuffmanTree ht;
if((fp3=fopen("count.txt","r"))==NULL) //從文件讀出字元總數
{
printf("打開文件不成功!");
exit(0);
}
n=fgetc(fp3);
ht=(HuffmanTree)malloc(2*n*sizeof(HTNode));
if((fp1=fopen("赫夫曼編碼.txt","r"))==NULL)
{
printf("打開文件不成功!");
exit(0);
}
if((fp2=fopen("HuffmanTree.dat","rb"))==NULL)
{ cout<<"文件打開不成功!"<<endl;
exit(0);
}
for(i=1;i<=2*n-1;i++)
fread(&ht[i],sizeof(HTNode),1,fp2);
for(i=1;i<=2*n-1;i++)
{
if(ht[i].parent==0)
}
ch=fgetc(fp1);
while(!feof(fp1)){
if(ch=='0')
{
k=ht[k].lchild;
if(ht[k].lchild==0)
{a=ht[k].asc;
c=(char)a;
printf("%c",c);;
k=t;
}
}
if(ch=='1')
{
k=ht[k].rchild;
if(ht[k].lchild==0)
{ a=ht[k].asc;
c=(char)a;
printf("%c",c);
k=t;
}
}
ch=fgetc(fp1);
}
fclose(fp1);
fclose(fp2);
}
//讀取文件中的文章,可自己選擇文件
int loadfile2(){
FILE *fp;
char ch;
int i,k,j=0;
count=0;
for(i=0;i<=127;i++)
{ a[i].ASCII=i;
a[i].n=0;
}
cout<<"\n\n\n\t\t\t請輸入你要打開的文件名:";
cin>>filename;
if((fp=fopen(filename,"r"))==NULL){
printf("打開文件不成功!");
return 1;
}
ch=fgetc(fp);
k=(int)ch;
a[k].n++;
while(!feof(fp)){
ch=fgetc(fp);
k=(int)ch;
a[k].n++;
}
fclose(fp);
for(i=0;i<=127;i++){
ch=(char)i;
if(a[i].n){
count++;
}
}
for(i=0;i<=127;i++)
{
for(;j<count;)
{
if(a[i].n)
{
w[j].n=a[i].n;
w[j].ASCII=a[i].ASCII;
j++;
break;
}
else break;
}
}
return 0;
}
串口直接丟過去收到就是了,為啥還要編碼解碼?加密么
㈢ 簡易編解碼電路怎麼實現編碼和解碼的
編碼和解碼電路需要數字邏輯運算,常見的邏輯運算是:與門、或門、非門,只要你設計好輸入和輸出,解碼和編碼就可以用邏輯運算實現,
㈣ PCM編解碼系統由哪些部分構成各部分的作用是什麼
PCM
編解碼系統由哪些部分構成
?
各部分的作用是什麼
?
回答:
其中,低通濾波器:把話音信號帶寬限制為
3.4KHz
,把高於這個頻率的信號過濾掉。
抽樣:
對模擬信號以其信號帶寬
2
倍以上的頻率進行周期性的掃描,
把時間上連續的信號變
成時間上離散的信號。
量化:把經抽樣得到的瞬時值進行幅度離散化,即指定
M
個規定的電平,把抽樣值用最接
近的電平標示。
編碼:用二進制碼組表示有固定電平的量化值。
解碼:與編碼器的作用相反,把收到的
PCM
信號還原成相應的
PAM
信號,實現數模變換
㈤ MATLAB: 數字通信系統信道編碼 AMI 編解碼
程序如下,現在原始序列長度20的隨機0,1串,要變自己改。
clc;
clear;
source = randint(1,20);
%%%%%%%%%%%% Encode %%%%%%%%%%%%%
perbit = -1;
for i=1:length(source);
if source(i)==1
encoded(i) = (-1)*perbit;
perbit = encoded(i);
else
encoded(i) = source(i);
end
end
%%%%%%%%%%%% Decode %%%%%%%%%%%%
for i=1:length(source);
if encoded(i)~=0
decoded(i) = 1;
else
encoded(i) = 0;
end
end
source
encoded
decoded
㈥ 什麼是曼徹斯特編解碼技術
曼徹斯特編碼是一種自同步的編碼方式,即時鍾同步信號就隱藏在數據波形中。在曼徹斯特編碼中,每一位的中間有一跳變,位中間的跳變既作時鍾信號,又作數據信號;從高到低跳變表示"1",從低到高跳變表示"0"。還有一種是差分曼徹斯特編碼,每位中間的跳變僅提供時鍾定時,而用每位開始時有無跳變表示"0"或"1",有跳變為"0",無跳變為"1"。
㈦ 計算機編譯就是指編碼和解碼兩個過程嗎
在微指令的控制欄位中,每一位代表一個微命令,在設計微指令時,是否發出某個微命令,只要將控制欄位中相應位置成"1"或"0",這樣就可打開或關閉某個控制門,這就是直接控製法.
在6.3節中所講的就是這種方法.但在某些復雜的計算機中,微命令甚至可多達三四百個,這使微指令字長達到難以接受的地步,並要求機器有大容量控制存儲器,為了改進設計出現了以下各種編譯法.
6.4.1 微指令的編譯法(編碼解碼方法)(2)
2.欄位直接編譯法
在計算機中的各個控制門,在任一微周期內,不可能同時被打開,而且大部分是關閉的(相應的控制位為"0").所謂微周期,指的是一條微指令所需的執行時間.如果有若干個(一組)微命令,在每次選擇使用它們的微周期內,只有一個微命令起作用,那麼這若干個微命令是互斥的.
例如,向主存儲器發出的讀命令和寫命令是互斥的;又如在ALU部件中,送往ALU兩個輸入端的數據來源往往不是唯一的,而每個輸入端在任一微周期中只能輸入一個數據,因此控制該輸人門的微命令是互斥的.
選出互斥的微命令,並將這些微命令編成一組,成為微指令字的一個欄位,用二進制編碼來表示, 就是欄位直接編譯法.
6.4.1 微指令的編譯法(編碼解碼方法)(3)
例如,將7個互斥的微命令編成一組,用三位二進制碼分別表示每個微命令,那麼在微指令中,該欄位就從7位減成3位,縮短了微指令長度.而在微指令寄存器的輸出端,為該欄位增加一個解碼器,該解碼器的輸出即為原來的微命令.
6.4.1 微指令的編譯法(編碼解碼方法)(4)
欄位長度與所能表示的微命令數的關系如下:
欄位長度 微命令數
2位 2~3
3位 4~7
4位 8~15
一般每個欄位要留出一個代碼,表示本段不發出任何微命令,因此當欄位長度為3位時,最多隻能表示7個互斥的微命令,通常代碼000表示不發微命令.
6.4.1 微指令的編譯法(編碼解碼方法)(5)
3.欄位間接編譯法
欄位間接編譯法是在欄位直接編譯法的基礎上,進一步縮短微指令字長的一種編譯法.
如果在欄位直接編譯法中,還規定一個欄位的某些微命令,要兼由另一欄位中的某些微命令來解釋,稱為欄位間接編譯法.
本方法進一步減少了指令長度,但很可能會削弱微指令的並行控制能力,因此通常只作為直接編譯法的一種輔助手段.
6.4.1 微指令的編譯法(編碼解碼方法)(6)
欄位A(3位)的微命令還受欄位B控制,當欄位B發出b1微命令時,欄位A發出a1,1,a1,2,…,a1,7中的一個微命令;而當欄位B發出b2微命令時,欄位A發出a2,1,a2,2,…,a2,7中的一個微命令,僅當A為000時例外,此時什麼控制命令都不產生.
6.4.1 微指令的編譯法(編碼解碼方法)(7)
4.常數源欄位E
在微指令中,一般設有一個常數源欄位E就如指令中的直接操作數一樣.E欄位一般僅有幾位,用來給某些部件發送常數,故有時稱為發射欄位.
該常數有時作為操作數送入ALU運算;有時作為計算器初值,用來控制微程序的循環次數等.
6.4.2 微程序流的控制 (1)
當前正在執行的微指令,稱為現行微指令,現行微指令所在的控制存儲器單元的地址稱現行微地址,現行微指令執行完畢後,下一條要執行的微指令稱為後繼微指令,後繼微指令所在的控存單元地址稱為後繼微地址.
所謂微程序流的控制是指當前微指令執行完畢後,怎樣控制產生後繼微指令的微地址.
與程序設計相似,在微程序設計中除了順序執行微程序外還存在轉移功能和微循環程和微子程序等,這將影響下址的形成.
下面介紹幾種常見的產生後繼微指令地址的方法.
6.4.2 微程序流的控制 (2)
(1)以增量方式產生後繼微地址.
在順序執行微指令時,後繼微地址由現行微地址加上一個增量(通常為1)形成的;而在非順序執行時則要產生一個轉移微地址.
機器加電後執行的第一條微指令地址(微程序入口)來自專門的硬體電路,控制實現取令操作,然後由指令操作碼產生後繼微地址.接下去,若順序執行微指令,則將現行微地址主微程序計數器( PC中)+1產生後繼微地址;若遇到轉移類微指令,則由 PC與形成轉移微地址的邏輯電路組合成後繼微地址.
6.4.2 微程序流的控制 (3)
6.4.2 微程序流的控制 (4)
(2)增量與下址欄位結合產生後繼微地址
將微指令的下址欄位分成兩部分:轉移控制欄位BCF和轉移地址欄位BAF,當微程序實現轉移時,將BAF送 PC,否則順序執行下一條微指令( PC+1).
執行微程序條件轉移時,決定轉移與否的硬體條件有好幾種.例如,"運算結果為零","溢出","已完成指定的循環次數"等.
我們假設有八種轉移情況,定義了八個微命令(BCF取3位),在圖中設置計數器CT用來控制循環次數.如在執行乘(或除)法指令時,經常採用循環執行"加,移位"(或減,移位)的方法,指令開始執行時,在CT中置循環次數)每執行一次循環,計數器減1,當計數器為零時結束循環.又考慮到執行微子程序時,要保留返回微地址,因此圖中設置了一個返回寄存器RR.
㈧ 編解碼電路MC145026/MC145027實現的是什麼功能請內行朋友告訴一下,謝謝!
此組晶元是摩托羅拉公司生產的用於通信配對使用的最新晶元。編碼晶元MC145026可對9位輸入信息(地址位A1~A5,數據位D6~D9)進行編碼,編碼後每個數據位用兩個脈沖表示:「1」編碼為兩個寬脈沖;「0」編碼為兩個窄脈沖;「開路」編碼為一寬脈沖和一窄脈沖交叉。當TE端輸入脈沖上升沿時,編碼後的數據流開始由D0串列輸出。對於每9位數據信息,能看作是個數據字,為了提高通信的安全性,編解碼晶元對每個數據字發送兩次,接收兩次。
MC145027解碼器用於接收MC145026輸出的編碼數據流。當解碼器地址和編碼器地址狀態相並連續收到兩組相同編碼信號時,VT端由低電平跳變為高電平以指示接收有效,同時中斷計算機進行接收。
簡單的說,就是用來編碼地址,識別地址。配對用的。
㈨ 調制 解調 編碼 解碼的關系與區別
調制解調,不同信號轉換,數字音頻轉換,和紅燈停綠燈行差不多編碼解碼,數字信號間的轉換,和加密解密差不多