【问题标题】:How to decrease running time of this particular solution?如何减少此特定解决方案的运行时间?
【发布时间】:2013-09-19 01:06:46
【问题描述】:

我正在尝试编写一段代码,该代码将生成一个排列,或一些以递归方式都不同的字符系列。

def getSteps(length, res=[]):
    if length == 1: 
        if res == []:
            res.append("l")
            res.append("r")
            return res
        else:
            for i in range(0,len(res)):
                res.append(res[i] + "l")
                res.append(res[i] + "r")
            print(res)
            return res
    else:
        if res == []:
            res.append("l")
            res.append("r")
            return getSteps(length-1,res)
        else:
            for i in range(0,len(res)):
                res.append(res[i] + "l")
                res.append(res[i] + "r")
            print(res)
            return getSteps(length-1,res)

def sanitize(length, res):
    return [i for i in res if len(str(i)) == length]

print(sanitize(2,getSteps(2)))

所以这会返回

“LL”、“LR”、“RR”、“RL”或系列的一些排列。

我马上就可以看出这个函数可能运行得很慢,因为我必须循环遍历整个数组。我试图让这个过程尽可能高效,但这是我能做到的。我知道在跑步过程中会发生一些不必要的事情,但我不知道如何让它变得更好。所以我的问题是:如何提高效率并减少这段代码的运行时间?

edit = 我希望能够将此代码移植到 java 或其他一些语言,以便理解递归的概念,而不是使用外部库并在不理解的情况下解决我的问题。

【问题讨论】:

  • 标准库是否为您提供了可以充分利用的任何工具,或构建解决方案? docs.python.org/2/library/itertools.html
  • 可以稍微提高性能的一件事是将“if res == []”更改为“if not res”,因为空列表在 Python 中的计算结果为 False。
  • 谢谢你,但我希望解决方案是递归的,因为我试图在这段代码中编写一种用于递归的“概念证明”。此外,我希望能够将其移植到 java 或 c++ 以真正理解这个概念而不是语法。
  • 一般情况下getSteps应该做什么?您想要一种排列还是全部排列?

标签: python performance time


【解决方案1】:

你的设计坏了。如果你再次调用getSteps,res 将不是一个空列表,它会从最后一次调用中留下垃圾。

我认为您想递归地生成排列,但我不明白您将使用 getSteps 函数去哪里

这是一个简单的递归函数

def fn(x):
    if x==1:
        return 'LR'
    return [j+i for i in fn(x-1) for j in "LR"]

【讨论】:

  • 我认为这就是我的目标。如果我调用某个函数 fn(x),对于某个数字让我们选择 3,fn(3) 应该返回“LLL”、“LLR”、“LRL”、“LRR”、“RRR”、“RRL”、“RLR”、 “RLL”
  • 如果你只有 2 个值,那就容易多了。想象一下替换 L=0, R=1 现在看起来就像 0-7 的二进制数
  • 确实如此。我在编码后不久就明白了,但我不知道如何递归地解决问题。有没有办法将二进制方法和递归方法结合起来?
  • 为什么要使用递归方法?效率不会更高
  • 确实如此,但我想在仍然使用递归的同时使其尽可能高效。
【解决方案2】:

有没有办法将二进制方法和递归方法结合起来?

是的,@gribbler 非常接近附有该评论的帖子中的内容。他只是按照“另一个顺序”将这些碎片拼凑在一起。

你如何构造所有长度为n的位串,以递增顺序(当被视为二进制整数时)?好吧,如果你已经有了所有长度为n-1 的位串,你可以用0 作为前缀,然后再用1 作为前缀。就这么简单。

def f(n):
    if n == 0:
        return [""]
    return [a + b for a in "RL" for b in f(n-1)]

print(f(3))

打印

['RRR', 'RRL', 'RLR', 'RLL', 'LRR', 'LRL', 'LLR', 'LLL']

将R 替换为0,将L 替换为1,这样就得到了从0 到7 的8 个二进制整数,按升序排列。

【讨论】:

  • 谢谢。这是我正在寻找的解决方案。我最初想采用这种方法,即在结果前面加上零,但我的方法有点太多余了。这样可以快速有效地完成工作。
【解决方案3】:

你应该看看 itertools。那里有一个名为 permutations 的函数,它正是您想要在这里实现的。

【讨论】:

  • 其实“排列”这个词并不合适。 itertools.product 是正确的工具。 map(''.join, product('LR', repeat=n))
猜你喜欢
  • 2014-03-07
  • 2013-10-22
  • 1970-01-01
  • 1970-01-01
  • 2016-07-24
  • 1970-01-01
  • 2013-09-07
  • 2015-06-02
  • 1970-01-01
相关资源
最近更新 更多