字符串编码
http://acm.fzu.edu.cn/problem.php?pid=1479
Time Limit:1s | Memory limit:32M |
Accepted Submit:110 | Total Submit:391 |
在数据加密和数据压缩中常需要对特殊的字符串进行编码。给定的字母表A 由26 个小写英文字母组成A={a,b,…,z}。该字母表产生的升序字符串是指字符串中字母按照从左到右出现的次序与字母在字母表中出现的次序相同,且每个字符最多出现1 次。例如,a,b,ab,bc,xyz 等字符串都是升序字符串。现在对字母表A 产生的升序字符串按照字典序排列并编码如下。 1 a 2 b … 26 z 27 ab 28 ac …对于一个升序字符串,迅速计算出它在上述字典中的编码。 输入数据 输入数据第一行有一个整数n。接下来n行每行有1个升序字符串 输出数据 按输入顺序每个升序字符串输出它的编码,每个编码占一行. 输入样例 2 a ab 输出样例 1 27 |
算法思路:设置一个长为27的数组a,从下标1开始,分别表示26个字母,赋初值为0。
记录被测试的字符串的长度len,在数组a记录出现的字符----将所对应的元素赋值为1。
很明显,当len = 1时,返回的编码就是数组中值为1的下标;当len = 2时,应该先把len = 1时的
所有可能情况加起来(即从26个字母中取1个,也即组合数Combination(1, 26)),再去分析具体
的字符串。
当len = 3时,应该先把len = 1和2时的所有可能情况加起来(即从26个字母中取1个和2个,也即组
合数Combination(1, 26))和Combination(2, 26)),再去分析具体的字符串。
依次类推,当len = i时,应该先把len = 1,2,。。。i-1时的所有可能情况加起来,再去分析具体的
字符串。
那么如何分析具体的字符串呢?以"cdf"为例,它对应的数组a[27] = {0,0,0,1,1,0,1,0,0,。。。0}。
因为a[1] = 0,说明字母a没有出现,而"cdf"肯定排在以a开头的长度为3的字符串的后面,以a开头的
长度为3的字符串的个数为Combination(3-1, 26-1),即从25个字母中取2个);
同样"cdf"肯定排在以b开头的长度为3的字符串的后面,所以编码还要加上Combination(3-1, 26-2);
3号元素‘c’为1,跳过,长度减1;接着跳过4号元素,长度再减1,此时长度已经是1了,只要看最后
一个字符和倒数第2个字符相差几就行了相差几就加几,最后的和即是所要的编码。
一个例子可能不够,再举一个。
以"begi"为例,它对应的数组a[27] = {0,0,1,0,0,1,0,1,0,1,0,。。。0}。
因为a[1] = 0,说明字母a没有出现,而"begi"肯定排在以a开头的长度为4的字符串的后面,以a开头
的长度为4的字符串的个数为Combination(4-1, 26-1),即从25个字母中取3个);
2号元素‘b’为1,跳过,长度减1;剩下的字符串为"egi" ;
3号元素‘c’为0,不能跳过,"egi"肯定排在以c开头的长度为3的字符串的后面,
以c开头的长度为3的字符串的个数为Combination(3-1, 26-3),即从23个字母中取2个);
同理4号元素‘d’不能跳过, 编码还要加上Combination(3-1, 26-4);
5号元素‘e’为1,跳过,长度减1;剩下的字符串为"gi" ;
同理6号元素‘f’不能跳过, 编码还要加上Combination(2-1, 26-6);
7号元素‘g’为1,跳过,长度减1;剩下的字符串为"i" ;
此时长度已经是1了,只要看最后一个字符和倒数第2个字符(即i和g)相差几就行了相差几就加几,最
后的和即是所要的编码。