python 如何计算数组中循环排列的数量(变量shift)

f87krz0w  于 2023-03-07  发布在  Python
关注(0)|答案(2)|浏览(108)

参考another question,我想打印一个数组的循环排列(并计算其数量)。我对这个函数的输入将是数组,跨距和起始值。
我的数组不一定只包含数字。
例如:给定数组X, 1, 2, 3, Y(5个元素)和跨距3,我将得到

X, 1, 2     // first line
3, Y, X
1, 2, 3
Y, X, 1
2, 3, Y     // last line since it would be repeating hereafter.

在这种情况下,计数将为“5”。在许多情况下,计数与元素数量相同,但并不总是如此。使用8个元素和跨距=4,计数为2。使用8个元素和6,计数为4。

数组也可能包含相同的值,如引入/引出和重复的数字。

示例:LEADIN, LEADIN, LEADIN, LEADIN, 1, 1, 2, 2, 3, 3, 4, 4, LEADOUT, LEADOUT(对于4个引入线,编号1..4重复 *2和2个引出线。总元素计数= 1..4。
其目的是形成一个无限的子集序列,每个子集的步长为1。子集中不能有任何空格。所有元素都必须使用,并且数字必须保持不变。
有了前导,平凡的例子:跨距为2的LI, LI, 1, 2, 3, LO, LO将为:
LI LI | 1 2 | 3 LO | LO LI | LI 1 | 2 3 | LO LO(7个重复)。
我可能会使用Python来完成这项工作。从循环数组中获取数据没有问题-但我需要找出我需要做多少“移位”。
使用这个简单的函数,我可以“计算”金额,但我会认为有一个公式来做这件事?

def getiterations(elements, stride):
    # assuming here that elements > stride
    lc = 0
    lineno = 0
    finished = False
    while not finished:
        lc = lc+stride      # simulate getting N numbers
        lineno= lineno+1
        if (lc %elements)==0:
           finished = True
    return lineno
klsxnrf1

klsxnrf11#

你只需要计算最小公倍数,然后除以步长,得到循环排列的个数。

import math

num_cycles = math.lcm(elements,stride)/stride
nmpmafwu

nmpmafwu2#

这里是完整的程序,如果它是有用的任何人。
解决方案,感谢@michael-cao。

"""
    Program to create a square array of a fixed-length list, in a sequential cyclic pattern until
    square is filled from first to last.

    Example using [*, * 1,2,3,4, X, X, X]  in a 3-column list
    2 leadin, 3 leadout, 4 values = 8 elements.

      |------------|  stride = 3  (amount per row)
      |----- first element
        *;   *;0001;1
        0002;0003;   X;2
           X;   X;   *;3
           *;0001;0002;4
        0003;   X;   X;5
           X;   *;   *;6
        0001;0002;0003;7
           X;   X;   X;8
                    |---- last element

      The purpose is to print each row on a paper, put these papers in sequence.
      After last row, the first row is printed again. For this reason, the row must be filled.

    To find amount of lines the following formula is used:

              least common multiple (elementcount, stride)
               ---------------------------------------
                        stride

             example:   lcm(8,3) = 24         24 /3  = 8 rows

    to output the list, the itertools module is used
          * cycle
          * islice

"""
import math
from itertools import cycle, islice

# ----------------------------------------------------
# -- configuration
#
leadin = '*'              # which string for leadin
leadincount =  2          # amount of lead in
leadout = 'X'             # which string for leadout
leadoutcount = 3          # amount of leadout
startvalue = 1            # first number in sequence
endvalue = 3              # last number in sequence
startindex  = 0           # zero-based start index for the list..

# ---- options for output
stride=3                  # amount of columns
numberformat='04d'        # formatting number series
textformat  = '>4s'       # formatting string (lead in/out)
listseparator = ';'       # what separates output list...
outputIndex= True         # print index number next to data
#
# ----------------------------------------------------

dataelements = [leadin]*leadincount + list(range(startvalue, endvalue+1)) + [leadout]*leadoutcount

repeats = int(math.lcm(len(dataelements), stride)/stride)

"""
   format the elements according to needs, text or number
"""
def outgroup(d):
    a = []
    for i in d:
        l = str(i)
        if l.isnumeric():
            a.append(f"{i:{numberformat}}")
        else:
            a.append(f"{l:{textformat}}")
    return a
    

for index, *group in zip(
             range(repeats), 
             *[islice(cycle(dataelements), startindex, None)] * stride
             ):
    dataline = listseparator.join(outgroup(group))
    if outputIndex:
        print(f"{dataline}{listseparator}{index+1}")
    else:
        print(f"{dataline}{listseparator}")

相关问题