【问题标题】:Python program with strange algorithm具有奇怪算法的 Python 程序
【发布时间】:2022-01-13 03:24:24
【问题描述】:

我真的不知道如何解释它,但我需要编写一个 Python 程序来输出这个:

1
2
1-2
3
4
3-4
1-2-3-4
5
6
5-6
7
8
7-8
5-6-7-8
1-2-3-4-5-6-7-8

有人可以帮我解释一下怎么做吗?

谢谢你:)

【问题讨论】:

  • 你试过什么?你能给我们看看你的一些代码吗?
  • 或许可以考虑以下问题。给定一个长度为 L 的字符串 S,你必须输出一个字符串 F(S),如果 L = 1,则 F(S) = S,如果 L = F(S) = F(S1) + F(S2) + S > 1,S1 是 S 的前半部分,S2 是 S 的后半部分。你如何计算函数 F?

标签: python algorithm numbers output binary-tree


【解决方案1】:

好的,一种解决方案如下:

lst = list(range(1,9))

def func(l):
    lst_str = list(map(str, lst))
    for i in l:
        print(i)
        for dvd in (2, 4, 8):
            if i % dvd == 0:
                print("-".join(lst_str[i-dvd:i]))
        
func(lst)

输出

1
2
1-2
3
4
3-4
1-2-3-4
5
6
5-6
7
8
7-8
5-6-7-8
1-2-3-4-5-6-7-8

这对于其他系列来说会失败,所以也许我们想要检查列表中的它的位置,而不是序列中的元素本身。 例如:

lst = list(range(9,17))

def func(l):
    lst_str = list(map(str, lst))
    for n, i in enumerate(l):
        print(i)
        n += 1
        for dvd in (2, 4, 8):
            if n % dvd == 0:
                print("-".join(lst_str[n-dvd:n]))
        
func(lst)

输出

9
10
9-10
11 
12
11-12
9-10-11-12
13
14
13-14
15
16
15-16
13-14-15-16
9-10-11-12-13-14-15-16

您可以将其扩展到二的更多幂,因此您可以使用 [2**n for n in range(1,max_exp + 1)] 而不是仅针对 (2, 4, 8) 进行迭代,其中 max_exp 是您选择的输入

【讨论】:

    【解决方案2】:

    看起来这个程序需要像这样运行:

    output first number
    output second number
    output first-second numbers
    output third number
    output fourth number
    output third-fourth numbers
    output first to fourth numbers
    (same for five to eight)
    output all eight
    

    想一想这里的模式,看看能不能解决!

    【讨论】:

      【解决方案3】:

      我意识到问题已经解决并且已经选择了答案,但是我想到了一个更通用的算法,我觉得有必要分享一下。我们重复连接先前的模式(由“-”分隔),并且对于我们的迭代次数可被整除的 2 的每个完美幂,这种连接发生 1 次。因此,通过一些位检查和堆栈操作,我们可以很容易地将问题抽象为一个适用于任何大小输入、任何字符集等的解决方案,甚至在非二次方大小的情况下表现良好输入。

      def print_patterns(alphabet, delimiter="-"):
          stack = []
      
          def push(pattern):
              print(pattern)
              stack.append(pattern)
      
          def pop():
              pat1 = stack.pop()
              pat2 = stack.pop()
              return f"{pat2}{delimiter}{pat1}"
      
          for index, char in enumerate(alphabet, 1):
              push(char)
      
              for bit in reversed(bin(index)):
                  if bit != '0':
                      break
                  push(pop())
      

      示例输出:

      >>> print_patterns("12345678")
      1
      2
      1-2
      3
      4
      3-4
      1-2-3-4
      5
      6
      5-6
      7
      8
      7-8
      5-6-7-8
      1-2-3-4-5-6-7-8
      

      还有一个极端情况:

      >>> print_patterns("abcdef", "*")
      a
      b
      a*b
      c
      d
      c*d
      a*b*c*d
      e
      f
      e*f
      

      【讨论】:

        【解决方案4】:

        这是@fanfly's comment 的实现,使用递归生成器:

        def f(s):
            if len(s) >= 2:
                m = (len(s)+1)//2
                yield from f(s[:m])
                yield from f(s[m:])
            yield '-'.join(iter(s))
        

        测试:

        >>> print('\n'.join(   f('abcd')   ))
        a
        b
        a-b
        c
        d
        c-d
        a-b-c-d
        
        >>> print('\n'.join(   f(''.join(map(str, range(1,9))))  ))
        1
        2
        1-2
        3
        4
        3-4
        1-2-3-4
        5
        6
        5-6
        7
        8
        7-8
        5-6-7-8
        1-2-3-4-5-6-7-8
        

        【讨论】:

          猜你喜欢
          • 2013-09-23
          • 2012-12-23
          • 1970-01-01
          • 1970-01-01
          • 2017-06-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多