多媒体数据上机实验一(C语言实现算术编码/西电)

本文详细展示了如何在C语言中运用算术编码方法对字符串进行编码和解码,涉及字符字典处理、编码区间计算和解码过程,适用于IT技术相关内容的学习者。
摘要由CSDN通过智能技术生成

题目:算术编码


具体代码:

#include<stdio.h>
#include<string.h>
#include<float.h>
#include<windows.h>
//code decode
double lowedge(int a,double *chance);
double highedge(int a,double *chance);
int main(){
	SetConsoleOutputCP(65001);
	printf("字符字典的个数为:");
	char num[10],str[20];
	int n,count,flag;
	double chance[10],lenth;
	double low=0.0,high=1.0;
	int code2[20],m=0;
	double sum=0,b=0.5;
	scanf("%d",&n);
	getchar();
	//输入字典
	printf("请输入字符和其对应的概率以及需要编码的字符串:\n");
	for(int i=0;i<n;i++){
		scanf("%c %Lf\n",&num[i],&chance[i]);
	}
    //输入要编码的字符串
	gets(str);
	count=strlen(str);//求字符个数
    /*---------------------------------------
    //检验是否输入成功
	for(int i=0;i<n;i++){
		printf("%c %f",num[i],chance[i]);
	}
	puts(str);
    -------------------------------------------*/
    //确定编码区间
	for(int i=0;i<count;i++){
		flag=0;
		lenth=high-low;
		for(int j=0;j<n;j++){
		    if(str[i]==num[j]){
			    flag=1;
			    high=low+lenth*highedge(j,chance);
				low=low+lenth*lowedge(j,chance);
		    }	
		}
		//判断是否含有非字典元素
		if(flag==0){
			printf("字符串含有非字典元素!\n编码结束!");
			return 0;
		}
	}
	printf("编码开始:\n");
	//输出编码区间
	printf("编码区间为:%.16Lf ~ %.16Lf\n",low,high);
	//根据区间进行解码
	while(1){
		sum=sum+b;
		if(sum<low){
			code2[m]=1;
		} 
		if(sum>high){
			sum=sum-b;
			code2[m]=0;
		}
		if((sum>low)&&(sum<high)){
			code2[m]=1;
			break;
		}
		b=(double)b/2;
		m++;
	}
	//还原二进制代码并输出编码值和编码
	printf("字符串编码为:");
	for(int i=0;i<=m;i++){
		printf("%d",code2[i]);
	}
	putchar('\n');
	printf("字符串编码为:%.16Lf\n",sum);
	printf("编码结束!\n");
	//-----------------------------------------------
// start decoding
	char c[20],d[20];
	int L,N=0,countde=0;
	double e=0.5,sumde=0.0,real,lowde=0.0,highde=1.0,lenthde=0.0;
	printf("解码开始:\n输入要进行解码的二进制数组:");
	gets(c);
	L=strlen(c);
	for(int i=0;i<L;i++){
		real=c[i]-'0';
		real=real*e;
		sumde=sumde+real;
		e=e/2;
	}
	printf("解码对应的十进制表示:%.16Lf\n",sumde);
	printf("输入解码字符个数:");
	scanf("%d",&N);
	for(int i=0;i<N;i++){
		lenthde=highde-lowde;
		for(int j=0;j<n;j++){
			if((sumde-lowde)/lenthde>lowedge(j,chance)&&(sumde-lowde)/lenthde<highedge(j,chance)){
				d[i]=num[j];
				highde=lowde+lenthde*highedge(j,chance);
				lowde=lowde+lenthde*lowedge(j,chance);
			}
		}
	}
	printf("解码字符为:");
	for(int i=0;i<N;i++){
		printf("%c",d[i]);
	}
	putchar('\n');
	printf("解码结束!");
	return 0;
}
//构造求字符上下界的函数
double lowedge(int a,double *chance){
	double lows=0;
	for(int i=0;i<a;i++){
		lows=lows+chance[i];
	}
	return lows;
}
double highedge(int a,double *chance){
	double highs=0;
	for(int i=0;i<=a;i++){
		highs=highs+chance[i];
	}
	return highs;
}
	

运行结果如下:

补充说明:

1、如果使用UTF-8标准可以删去文中的头文件<windows.h>和SetConsoleOutputCP(65001);

2、C语言默认输出字符类型到小数点后6位,doublel类型有需要高精度输出的需要格式转换写成"%.16Lf"

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值