假定一种编码的编码范围是a~y的25个字母,从1位到4位的编码,如果我们把该编码按字典序排序,形成一个数组如下: a,aa,aaa,aaaa,aaab,aaac,…,…,b,ba,baa,baaa,b

1.题目描述

假定一种编码的编码范围是a~y的25个字母,从1位到4位的编码,如果我们把该编码按字典序排序,形成一个数组如下:
a,aa,aaa,aaaa,aaab,aaac,…,…,b,ba,baa,baaa,baab,baac,… …,yyyw,yyyx,yyyy。其中a的Index为0,aa的Index为1,aaa的Index为2,以此类推。

编写一个函数,输入是任意一个编码,输出这个编码对应的index,如:

输入:baca

输出:16331

2.题目分析

例如:我们来分析一下以字母a开头的排列组合

{
    {a,aa,aaa,aaaa,aaab,aaac,...,aaay}
    {aab,aaba,aabb,aabc,...,aaby}
    {...}
    {aay,aaya,aayb,...,aayy}
    {ab,aba,abaa,abab,...,abay}
    {...}
    {ay,aya,ayaa,ayab,...,ayay}
    {...}
    {ayyy}
}

若首字母为a共有多少种组合:
①a 1种
②a _ 25种
③a _ _ 25x25种
④a _ _ _25x25x25种
若第二个字母为a共有多少种组合:
① _a_ 1种
②_a _ 25种
③_a _ _ 25x25种
若第三个字母为a共有多少种组合:
①_ _a 1种
② _ _a _ 25种
若第四个字母为a共有多少种组合:
① _ _ _a 1种

所以当baca时以b开头时,前面有a开头(b-a)*(1+25+25*25+25*25825),第二位是a,(a-a)*(1+25+25*25)+1(但不能为空),第三位为c,(c-a)*(1+25)+1,第四位为a,(a-a)*(1)+1
baca=(1+25+2525+252525)+1+2x(1+25)+1=16331

3.code

#include<stdio.h>

int CreateIndex(const char* str)
{
	if (str == NULL)	return -1;

	int carry[4] = {
		1 + 25 + 25 * 25 + 25 * 25 * 25,
		1 + 25 + 25 * 25,
		1 + 25,
		1
	};
	int Index = 0;

	for (int i = 0; i < 4;++i)
	{
		if (str[i] >= 'a' && str[i] <= 'y')
		{
			Index = Index + (str[i] - 'a') * carry[i];
			if (i != 0)	++Index;
		}
	}
	return Index;
}
int main()
{
	const char* arr = "baca";
	int res = CreateIndex(arr);
	printf("%d\n", res);
	return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 哈夫曼编码是指将字符转换为二进制编码一种方法,使得编码后的字符长度最短且不会出现编码冲突。在哈夫曼树中,每个叶子结点代表一个字符,而每个非叶子结点代表一个字符的编码。因此,我们可以通过遍历哈夫曼树,从根结点到每个叶子结点的路径上的左右分支来确定每个字符的哈夫曼编码。具体步骤如下: 1. 从根结点开始遍历哈夫曼树,如果遇到左分支就在当前编码后添加一个,如果遇到右分支就在当前编码后添加一个1,直到遍历到叶子结点。 2. 将得到的编码作为该叶子结点代表的字符的哈夫曼编码。 3. 重复以上步骤,直到遍历完整棵哈夫曼树,得到每个结点的哈夫曼编码。 需要注意的是,由于哈夫曼树的构建方式是从下往上逐步合并两个权值最小的结点,因此在遍历哈夫曼树时,左分支代表的编码一定比右分支代表的编码一个。因此,我们可以在遍历哈夫曼树时,只记录当前编码,而不需要记录每个结点的编码长度。 ### 回答2: 哈夫曼树是一种用于数据压缩的重要数据结构,利用哈夫曼树可以将频率较高的字符用较短的二进制串表示,从而减少数据存储的空间。当已有一棵哈夫曼树时,要输出每个结点的哈夫曼编码,可以采用以下方法实现: 1. 遍历哈夫曼树 首先,需要遍历哈夫曼树。由于哈夫曼树是一棵二叉树,因此可以使用先序遍历、中序遍历或后序遍历等方法进行遍历。这里我们采用后序遍历的方法,即先遍历左子树和右子树,最后再遍历根节点。这是因为在哈夫曼树中,左子树通常是编码中表示“0”(即左子节点)的分支,右子树通常是编码中表示“1”(即右子节点)的分支。 2. 给每个结点赋编码 在遍历哈夫曼树时,可以给每个结点赋一个编码。对于左子树,将其编码设置为父节点的编码加上“0”;对于右子树,将其编码设置为父节点的编码加上“1”。对于叶子节点,就是编码的最终结果。例如,如果父节点的编码是101,左子节点的编码就是1010,右子节点的编码就是1011。 3. 输出每个结点的哈夫曼编码 完成了上面两个步骤后,就可以输出每个结点的哈夫曼编码了。对于叶子节点,输出节点对应的字符和编码;对于其他节点,只需要输出节点的频率和编码即可。这样就完成了哈夫曼树输出每个结点的哈夫曼编码的过程。 以上就是完成哈夫曼树输出每个结点的哈夫曼编码一种方法。实际上,由于哈夫曼树本身就是一种编码树,因此也可以直接采用哈夫曼编码的定义来生成每个结点的编码。无论采用哪种方法,输出每个结点的哈夫曼编码都是一件相对简单的事情。 ### 回答3: 哈夫曼编码一种可变长度编码,将出现频率高的字符用短的编码表示,出现频率低的字符用长的编码表示,以达到压缩数据的目的。哈夫曼树是用来生成哈夫曼编码的。 给定一棵哈夫曼树,我们可以沿着树的每个结点进行遍历,若往左走,则记录0,若往右走,则记录1,最终得到的二进制编码就是该结点的哈夫曼编码。下面是具体步骤: 1.从根节点开始遍历哈夫曼树。 2.若遍历到的结点为叶子结点,则记录该结点表示的字符以及该结点的路径上的0和1。 3.若遍历到的结点不是叶子结点,则记录该结点的路径上的0和1,并分别往其左子树和右子树递归遍历。 4.对所有叶子结点得到的编码进行排序,可以按照编码长度升序排序,也可以按照字典序排序。 5.按照排好序的顺序输出所有叶子结点的字符以及对应的哈夫曼编码。 比如有这样一棵哈夫曼树: ``` d:10 / \ b:5 c:5 /\ /\ e:2 f:3 g:2 h:3 ``` 首先遍历根节点,向左子树遍历得到e和f的编码为“00”和“01”,向右子树遍历得到g和h的编码为“10”和“11”;接着遍历左子树的叶子结点b,得到b的编码为“000”,遍历右子树的叶子结点c,得到c的编码为“001”,最后遍历到d的编码为“1”。按照编码长度升序输出所有叶子结点的字符以及对应的哈夫曼编码为: ``` e:00 f:01 b:000 c:001 g:10 h:11 ``` 这样,我们就完成了给定哈夫曼树求解哈夫曼编码的过程。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值