📄 3gpp_interleaver.cpp
字号:
#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
#include "windows.h" /*包含用到的头文件*/
int p,v,*T,*s,*q,*rj,**U,**matrix,**inter_matrix;
/* 定义全局变量,p代表素数,v代表素数对应的原根,*/
const int T_5[5]={4,3,2,1,0};
const int T_10[10]={9,8,7,6,5,4,3,2,1,0};
const int T_20_1[20]={19,9,14,4,0,2,5,7,12,18,16,13,17,15,3,1,6,11,8,10};
const int T_20_2[20]={19,9,14,4,0,2,5,7,12,18,10,8,13,17,3,1,16,6,15,11};
const int p_table[52]={7 ,11 ,13 ,17 ,19 ,23 ,29 ,31 ,37 ,41 ,43 ,47 ,53 ,59 ,
61 ,67 ,71 ,73 ,79 ,83 ,89 ,97 ,101,103,107,109,113,127,
131,137,139,149,151,157,163,167,173,179,181,191,193,197,
199,211,223,227,229,233,239,241,251,257} ;
const int v_table[52]={3,2,2,3,2,5,2,3,2,6,3,
5,2,2,2,2,7,5,3,2,3,5,
2,5,2,6,3,3,2,3,2,2,6,
5,2,5,2,2,2,19,5,2,3,2,
3,2,6,3,7,7,6,3 };
gcd(int a,int b) /*求最大公约数*/
{
int temp,fgcd;
if (a<b)
{
temp=a;a=b;b=temp;
}
if (a%b==0)
{
fgcd=b;
return(fgcd);
}
else
{
gcd(b,a%b);
}
}
row_T(int k) /*确定交织矩阵行数和行内交织模式T*/
{int i,r;
if(k>=40&&k<=159)
{
r=5;
T=new int[r];
if(T==0)
{printf("分配内存失败!\n请按键继续!\n");
getch();
exit(0);
}
for(i=0;i<r;i++)
T[i]=T_5[i];
}
else if((k<=200&&k>=160)||(k<=530&&k>=481))
{
r=10;
T=new int[r];
if(T==0)
{
printf("分配内存失败!\n请按键继续!\n");
getch();
exit(0);
}
for(i=0;i<r;i++)
T[i]=T_10[i];
}
else if((k<=2480&&k>=2281)||(k<=3210&&k>=3161))
{
r=20;
T=(int *)malloc(r*sizeof(int));
if(T==0)
{
printf("分配内存失败!\n请按键继续!\n");
getch();
exit(0);
}
for(i=0;i<r;i++)
T[i]=T_20_1[i];
}
else
{
r=20;
T=new int[r];
if(T==0)
{
printf("分配内存失败!\n请按键继续!\n");
getch();
exit(0);
}
for(i=0;i<r;i++)
T[i]=T_20_2[i];
}
return(r);
}
column_p_v(int k,int r) /*确定交织矩阵列数*/
{int i,c;
if(k>=481&&k<=530)
{
p=53;
c=p;
v=2;
}
else
{for(i=0;i<52;i++)
if(k<=r*(p_table[i]+1))
{p=p_table[i];
v=v_table[i];
if(k<=r*(p-1)) c=p-1;
else if(k>r*(p-1)&&k<=r*p) c=p;
else c=p+1;
break;
}
}
return(c);
}
void make_s() /*构造行内置换序列s(i)*/
{int i;
s=new int[p-1];
if(s==0)
{
printf("分配内存失败!\n请按键继续!\n");
getch();
exit(0);
}
s[0]=1;
for(i=1;i<=p-2;i++)
s[i]=(v*s[i-1])%p;
}
void make_q(int r) /*选择合适的连续质数集q(j)*/
{int i,j,k=0,tem;
q=new int[r];
if(q==0)
{
printf("分配内存失败!\n请按键继续!\n");
getch();
exit(0);
}
q[0]=1;
for(j=1;j<=r-1;j++)
{for(i=k;i<52;i++)
{
tem=gcd(p_table[i],p-1);
if(tem==1)
{
q[j]=p_table[i];
k=i+1;
break;
}
}
}
}
void make_rj(int r) /*置换序列q(j)得到r(j)*/
{int i,j;
rj=new int[r];
if(rj==0)
{
printf("分配内存失败!\n请按键继续!\n");
getch();
exit(0);
}
for(j=0;j<r;j++)
{
for(i=0;i<r;i++)
if(i==T[j])
{
rj[i]=q[j];
break;
}
}
}
void make_U(int r,int c,int k) /* 构造行内交织模式矩阵*/
{
int i,j,m,tem;
U=new int*[r];
for(i=0;i<r;i++)
{
U[i]=new int[c];
}
if(c==p)
{for(i=0;i<r;i++)
{
for(j=0;j<p-1;j++)
{
for(m=0;m<p-1;m++)
if(m==((j*rj[i])%(p-1)))
{
U[i][j]=s[m];
break;
}
}
U[i][p-1]=0;
}
}
else if(c==p+1)
{for(i=0;i<r;i++)
{
for(j=0;j<p-1;j++)
{
for(m=0;m<p-1;m++)
if(m==((j*rj[i])%(p-1)))
{
U[i][j]=s[m];
break;
}
}
U[i][p-1]=0;
U[i][p]=p;
}
if(r*c==k)
{
tem=U[r-1][0];
U[r-1][0]=U[r-1][p];
U[r-1][p]=tem;
}
}
else if(c==p-1)
{for(i=0;i<r;i++)
{
for(j=0;j<p-1;j++)
{
for(m=0;m<p-1;m++)
if(m==((j*rj[i])%(p-1)))
{
U[i][j]=s[m]-1;
break;
}
}
}
}
}
void inter_row(int r,int c) /*对交织矩阵进行行内交织*/
{
int i,j,k;
inter_matrix=new int*[r];
for (i=0;i<r;i++)
{
inter_matrix[i]=new int[c];
}
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
for(k=0;k<c;k++)
if(k==U[i][j])
{
inter_matrix[i][j]=matrix[i][k];
break;
}
}
}
}
void intra_row(int r,int c) /*对交织矩阵进行行间交织*/
{
int i,j,k;
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
for(k=0;k<r;k++)
if(k==T[i])
{
matrix[i][j]=inter_matrix[k][j];
break;
}
}
}
}
void displayHelp()
{
printf("\n\n说明:");
printf("\n 1.本程序用于生成3GPP交织器. ");
printf("\n 2.当输入数据序列的长度之后,");
printf("程序将会自动生成与之相对应的3GPP交织器. ");
printf("\n 3.程序将以TXT文本文件的形式输出生成的交织器.");
printf("\n 4.数据序列的长度必须大于等于40,小于等于5114!");
}
void displayManu() /*显示菜单*/
{
printf("\n\n\n\n\n");
printf("\t\t====================================\n");
printf("\t\t|| 3GPP 交 织 器 生 成 程 序 ||\n");
printf("\t\t|| ||\n");
printf("\t\t|| 1.开 始 交 织 ||\n");
printf("\t\t|| ||\n");
printf("\t\t|| 2.程 序 说 明 ||\n");
printf("\t\t|| ||\n");
printf("\t\t|| 3.退 出 程 序 ||\n");
printf("\t\t|| ||\n");
printf("\t\t====================================\n");
printf("\n\t\t 请 选 择 操 作: ");
}
void checkWrong(int k,int r,int c) /*检查程序是否出错,若出错,则退出*/
{
int i,j;
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
if((matrix[i][j]<0)||(matrix[i][j]>k))
{
system("cls");
printf("\n程序出错!\n请重新运行程序!\n");
getch();
exit(0);
}
}
}
void WriteDat(int k,int r,int c) /*输出文本文件*/
{
int i,j,m;
FILE *out;
char name[5],name2[25];
system("cls");
printf("\n请输入文件名:"); /*输入文本文件的名称*/
scanf("%s",name);
strcpy(name2,"3GPP_");
strcat(name2,name);
strcat(name2,".txt");
out=fopen(name2,"w"); /*创建一个文件*/
if(out==NULL) /*创建文件失败则退出*/
{
printf("无法读写文件");
exit(0);
}
fprintf(out,"\t\t\t3GPP Turbo编码交织器\n");
fprintf(out,"\t\t L=%d (从上至下,从左至右)\n",k);
m=0;
for(i=0;i<c;i++)
{
for(j=0;j<r;j++)
if(matrix[j][i]!=0)
{
fprintf(out,"%5d",matrix[j][i]-1);
m++;
if(m==20)
{
fprintf(out,"\n");
m=0;
}
}
}
fclose(out); /*关闭文件*/
}
void releaseMemory(int r,int c)
{
int i;
for(i=0;i<r;i++) /*释放占用的内存空间*/
{
delete[c] U[i];
delete[c] matrix[i];
delete[c] inter_matrix[i];
}
delete[r] U;
delete[r] matrix;
delete[r] inter_matrix;
delete[p-1] s;
delete[r] q;
delete[r] rj;
delete[r] T;
}
/******************************************************************************/
/******************************************************************************/
void main()
{
int i,j,k,r,c,*a,option;
char set;
printf("\n\n\n\n\n\n\n");
printf("\t欢 迎 使 用 3GPP 交 织 器 生 成 程 序");
printf("\n\n\n\t\t请 按 任 意 键 继 续.");
printf("\n\n\n\n\n\n\t\t\t\t\t设 计 人: 黎 家 祥");
getch();
system("cls");
while(1)
{
system("cls");
displayManu();
scanf("%d",&option);
switch(option)
{case 1:
{
system("cls");
printf("\n输入数据序列的长度: K=");
scanf("%d",&k);
if(k<40||k>5114) /*输入检查,若有错,则返回上一级菜单*/
{
printf("\n输入错误!\nK必须为40到5114的整数\n");
printf("请按任意键返回上层菜单.");
getch();
break;
}
a=new int[k]; /*生成长度为K的原信息序列序号*/
for(i=0;i<k;i++)
a[i]=i+1;
r=row_T(k);
c=column_p_v(k,r);
printf("\n 行数=%d 列数=%d\n\n 质数p=%d 本原根v=%d\n",r,c,p,v);
matrix=new int*[r]; /*创建大小为R*C的交织矩阵*/
for (i=0;i<r;i++)
{
matrix[i]=new int[c];
}
for(i=0;i<r;i++) /*将数据序列读入交织矩阵*/
for(j=0;j<c;j++)
{
if((c*i+j)==k) /*若序列不足以写满交织矩阵,则补0*/
goto L2;
matrix[i][j]=a[c*i+j];
}
L2:for(;i<r;i++) /*补0*/
{
for(;j<c;j++)
matrix[i][j]=0;
break;
}
i=i+1;
for(;i<r;i++)
for(j=0;j<c;j++)
matrix[i][j]=0;
delete[r] a; /*释放数组a占据的内存空间*/
make_s(); /*调用函数,构造行内置换序列s(i)*/
make_q(r); /*调用函数,选择合适的连续质数集q(j)*/
make_rj(r); /*调用函数,置换序列q(j)得到r(j)*/
make_U(r,c,k); /*调用函数, 构造行内交织模式矩阵*/
inter_row(r,c); /*调用函数, 对交织矩阵进行行内交织*/
intra_row(r,c); /*调用函数, 对交织矩阵进行行间交织*/
checkWrong(k,r,c); /*调用错误检查函数*/
getch();
system("cls");
printf("生成的交织器:\n"); /*打印交织完成后的矩阵*/
for(i=0;i<c;i++)
for(j=0;j<r;j++)
if(matrix[j][i]!=0)
printf("%5d",matrix[j][i]-1);
getch();
L3:system("cls"); /*选择是否打印数据*/
printf("\n是否存储生成的3GPP交织器?");
printf("\n\nY 存储并返回");
printf("\nN 不存储直接返回\n");
printf("\n选择:");
scanf("%c",&set);
if(set=='Y'||set=='y')
{
WriteDat(k,r,c); /*调用函数,输出文本文件*/
system("cls");
printf("\n\n\n\n\n\n\t\t\t交织器存储成功!");
}
else if(set=='N'||set=='n')
break;
else
goto L3;
releaseMemory(r,c); /*调用内存空间释放函数*/
break ; /*退出程序*/
}
case 2:
{
system("cls");
displayHelp(); /*调用帮助显示函数*/
getch();
break;
}
case 3:{ /*退出程序*/
system("cls");
printf("\n请按任意键退出程序.\n");
getch();
exit(0);
}
default:{ /*对输入选择项错误的处理*/
system("cls");
printf("\n输入错误!\n请按任意键返回上层菜单.");
getch();
break;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -