You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求逆函数:根据给定排列获取其字典序索引

问题分析

你已经实现了从索引生成排列的函数get_nth_permutation,现在需要的是它的逆函数:从排列计算字典序索引。核心思路是把正向过程倒过来,逐步累加每个元素对应的阶乘贡献值。

逆过程的核心逻辑

正向过程中,我们通过index = p_index // factorial(n-1)确定当前选哪个元素,remainder = p_index % factorial(n-1)进入下一层递归。逆过程则是:

  • 维护一个当前剩余的原始元素列表(初始是完整的deck)
  • 遍历目标排列的每一个元素:
    1. 找到该元素在当前剩余列表中的位置k
    2. 计算k * factorial(len(剩余列表)-1),把这个值加到总索引里
    3. 从剩余列表中移除这个元素
  • 遍历完成后,总索引就是所求的字典序索引
伪代码
函数 get_permutation_index(permuted_deck):
    剩余列表 = 原始deck的副本(避免修改原列表)
    总索引 = 0
    对于 permuted_deck 中的每个元素 card:
        n = 剩余列表的长度
        f = (n-1)的阶乘
        k = 剩余列表中card的索引位置
        总索引 += k * f
        从剩余列表中删除card
    返回 总索引
Python实现示例

结合你提供的deck列表,实现如下:

import math

deck = ["AC", "2C", "3C", "4C", "5C", "6C", "7C", "8C", "9C", "TC", "JC", "QC", "KC",
        "AD", "2D", "3D", "4D", "5D", "6D", "7D", "8D", "9D", "TD", "JD", "QD", "KD",
        "AH", "2H", "3H", "4H", "5H", "6H", "7H", "8H", "9H", "TH", "JH", "QH", "KH",
        "AS", "2S", "3S", "4S", "5S", "6S", "7S", "8S", "9S", "TS", "JS", "QS", "KS",]

def get_permutation_index(permuted_deck):
    remaining = deck.copy()  # 用副本,不修改原deck
    index = 0
    for card in permuted_deck:
        n = len(remaining)
        if n == 0:
            break
        f = math.factorial(n - 1)
        k = remaining.index(card)
        index += k * f
        del remaining[k]
    return index

# 修正你原函数的可变默认参数问题,避免递归副作用
def get_nth_permutation(p_index, in_list):
    if p_index >= math.factorial(len(in_list)):
        return []
    if not in_list:
        return []
    f = math.factorial(len(in_list)-1)
    idx = p_index // f
    remainder = p_index % f
    selected = in_list[idx]
    new_in_list = in_list[:idx] + in_list[idx+1:]
    return [selected] + get_nth_permutation(remainder, new_in_list)

# 测试:生成排列后还原索引
test_index = 123456
perm = get_nth_permutation(test_index, deck.copy())
restored_index = get_permutation_index(perm)
print(test_index == restored_index)  # 输出True说明逻辑正确
关键注意点
  1. 避免可变默认参数:你原函数里的out_list=[]会导致递归时复用同一个列表,多次调用会出错,修正后的get_nth_permutation改用列表拼接方式规避这个问题。
  2. 大整数处理:52的阶乘是极大的数,但Python的int支持任意精度,不用担心溢出。
  3. 性能优化:如果需要更快的元素查找,可以提前给deck建立{card: 原始索引}的字典,把查找位置的时间复杂度从O(n)降到O(1),对于52张牌来说差异不大,但数据量大时效果明显。

内容的提问来源于stack exchange,提问作者ep84

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 13:34:54