字典序问题(Python C++)

本文介绍了一种用于数据加密和压缩的字典序编码算法,该算法针对升序字符串进行编码,快速计算其在字典中的位置。通过递归方法计算长度小于目标字符串的所有升序字符串数量,以及相同长度但字典序小于目标字符串的数量,实现精确编码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

字典序问题:在数据加密和数据压缩中需要对特殊的字符串进行编码。给定的字母表由262626个小写字母组成。该字母表产生的升序字符串是指字符串中字母从左到右出现的次序与字母在字母表中出现的次序相同,且每个字符最多出现111次。对于任意长度不超过666的升序字符中,迅速计算出它在上述字典中的编码。

题意:

顾名思义,字典序,也就是要求给定字符串在升序字典中字典序的编号。

思路:

字典序编号如表:

1234262728
abcdzabac

计算字典序编号,可以转化为计算该字符串前面有多少个字符串。

  1. 计算长度小于kkk的升序字符串的总个数。
  2. 计算长度等于kkk的字典序小于(即编号在其前面)给定串的总个数。

dfs(i,k)dfs(i,k)dfs(i,k)递归求以iii开头长度为kkk的升序字符串的总个数。
fun(k)fun(k)fun(k)计算长度为kkk的升序字符串总个数。

参考代码:

C++C++C++:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

LL dfs(int i, int k) { //递归求以i开头长度为k的升序字符串的总个数
  LL sum = 0;
  if (k == 1) {
    return 1;
  }
  for (int j = i + 1; j <= 26; j++) {
    sum += dfs(j, k - 1);
  }
  return sum;
}

LL fun(int k) { //长度为k的升序字符串总个数
  LL sum = 0;
  for (int i = 1; i <= 26; i++) {
    sum += dfs(i, k);
  }
  return sum;
}
signed solve() {
  string s;
  while (cin >> s) {
    LL ans = 1;
    int len = s.size();
    //先把所有长度小于所求字符串长度的字符串的个数求出来
    for (int i = 1; i < len; i++) {
      ans += fun(i);
    }
    LL temp = 0;
    for (int i = 0; i < len; i++) {
      int num = s[i] - 'a' + 1; //下一位字符
      int len2 = len - i;       //获取当前的长度
      for (int j = temp + 1; j < num; j++) {
        ans += dfs(j, len2);
      }
      temp = num;
    }
    cout << ans << endl;
  }
}
signed main() {
  solve();
  return 0;
}

Python:Python:Python:

def dfs(i, k):
    sum = 0
    if k == 1:
        return 1
    for j in range(i + 1, 27):
        sum += dfs(j, k - 1)
    return sum


def fun(k):
    sum = 0
    for i in range(1, 27):
        sum += dfs(i, k)
    return sum


def main():
    s = input()
    if False == s.isalpha():
        print('请输入升序字母字符串')
    else:
        ans, l, temp = 1, len(s), 0
        for i in range(1, l):
            ans += fun(i)
        for i in range(l):
            num = ord(s[i]) - ord('a') + 1
            len2 = l - i
            for j in range(temp + 1, num):
                ans += dfs(j, len2)
            temp = num
        print(ans)


if __name__ == "__main__":
    main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nuoyanli

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值