再セット可能な符号化と復号化について
1812 ワード
すなわちabbacdbの繰返し可能な文字列を組合せで辞書順に並べたシーケンス番号に変換したり、与えられたシーケンス番号と与えられた集合に基づいて復号したりして、符号化と復号の複雑さはいずれもO(n*k^2)であり、nは要素の個数であり、kは要素の種類である.
エンコーディング
デコード
エンコーディング
int count[26];
int fac[13];
int code(char *s, int len)
{
int ret = 0, limit = 0;
memset(count, 0, sizeof(count));
for(int i = 0; i < len; ++i)
{
++count[s[i]-'a'];
limit = max(limit, s[i]-'a');
}
for(int i = 0; i < len; ++i)
{
for(int j = 0; j < s[i]-'a'; ++j)
if(count[j])
{
int tret = fac[len-i-1];
--count[j];
for(int k = 0; k <= limit; ++k)
tret /= fac[count[k]];
++count[j];
ret += tret;
}
--count[s[i]-'a'];
}
return ret;
}
char str[15];
int main()
{
fac[0] = 1;
for(int i = 1; i <= 12; ++i)
fac[i] = i*fac[i-1];
while(~scanf("%s", str))
{
printf("%d
", code(str, strlen(str))+1);
}
return 0;
}
デコード
int fac[13];
int count[26];
char ans[20];
char *decode(int num, int len)
{
int temp;
for(int i = 0; i < len; ++i)
{
int ind;
for(ind = 0; ind < 26; ++ind)
if(count[ind])
{
--count[ind];
temp = fac[len-i-1];
for(int k = 0; k < 26; ++k)
temp /= fac[count[k]];
if(temp < num)
num -= temp;
else
break;
++count[ind];
}
ans[i] = ind+'a';
}
ans[len] = '\0';
return ans;
}
int main()
{
fac[0] = 1;
for(int i = 1; i <= 12; ++i)
fac[i] = i*fac[i-1];
int num;
while(~scanf("%d", &num))
{
memset(count, 0, sizeof(count));
char temp[2];
int len = 0;
while(~scanf("%s", temp))
{
scanf("%d", count+temp[0]-'a');
len += count[temp[0]-'a'];
}
printf("%s
", decode(num, len));
}
return 0;
}