这是一个例子:


4位数
第一,第二位数字的范围是:0〜5(总共六个数字)
第三,四位数的范围是:0〜4(共五位数)


因此,0000、0040、0111、4455没问题,但5555、4555、4466没问题。

我要查找的是序数2345是什么? (从零开始索引)

例如,0001在序数中为“ 1”。同样,0010为“ 5”。

可以通过


  (5 * 6 * 6 * 1)* 2 +(6 * 6 * 1)* 3 +(6 * 1)* 4 +(1)* 5 = 497


我在Python中做了一个函数

import numpy as np

def find_real_index_of_state(state, num_cnt_in_each_digit):
    """
    parameter
    =========
    state(str)
    num_cnt_in_each_digit(list) : the number of number in each digit
    """
    num_of_digit = len(state)
    digit_list = [int(i) for i in state]

    num_cnt_in_each_digit.append(1)

    real_index = 0
    for i in range(num_of_digit):
        real_index += np.product(num_cnt_in_each_digit[num_of_digit-i:]) * digit_list[num_of_digit-i-1]
    return real_index

find_real_index_of_state("2345", [5,5,6,6])


其结果与497相同。

问题是,此功能确实很慢。我需要更快的版本,但这是我能想到的最好的版本。

我真的需要您的建议来改善它的性能。 (例如矢量化等)

谢谢

最佳答案

希望我正确理解你。

我注意到的第一件事是您不需要重新计算每个循环的所有内容。即您分别计算(5 * 6 * 6 * 1),(6 * 6 * 1),(6 * 1),(1),而您只需要计算一次。

def find_real_index_of_state(state,num_cnt_in_each_digit):

    factor = 1

    total = 0

    for digit, num_cnt in zip(reversed(state), reversed(num_cnt_in_each_digit)):

        digit = int(digit)

        total += digit*factor

        factor*= num_cnt

    return total

09-25 21:41