【问题标题】:Print all permutations of possible outcomes given N rounds of RPS using a stack使用堆栈打印给定 N 轮 RPS 可能结果的所有排列
【发布时间】:2017-01-13 14:04:13
【问题描述】:

给定n轮,以堆栈为主要策略,将所有可能的排列打印到剪刀石头布上。

我曾经知道如何做到这一点,但是在一段时间没有锻炼后我就陷入了困境。

有人可以提供有关如何填充堆栈的有用提示吗?

我知道 n 个输入有 3^n 个输出。

对于 n = 1,预期答案是 3。可能的解决方案是:

def rps(n)
  stack = []
  answer = []

  if n > 0
    stack.push([r,p,s])
    n -= 1

  while !stack.isEmpty()
    array = stack.pop();

    forEach elem in array
      // I still can't figure out where to go from here!!

我知道在递归解决方案中,n=1 时会变为 r,p,s

对于 n=2,答案会附加 rr, rp, rs, pr, pp, ps, sr, sp, ss

对于 n=3,它将是 rrr、rrp、rrs、rpr 等...

【问题讨论】:

  • 您可以添加您当前的方法吗?这对我们来说将是一个很好的起点。
  • 我知道我应该有一个堆栈和一个while循环。堆栈最初是空的,我不确定要推入堆栈以开始。假设 n = 3,我不确定我是否开始 1. push [] 2. push ['r','p',s'] 3. concatenating ['r','p','s'] 4 . 将 3 推入堆栈。我知道并且已经完成了递归解决方案,但它并不能很好地适应我。我觉得我这样做是出于记忆,而不是真正掌握逻辑或培养强烈的直觉。
  • 如果你已经准备好你的代码,那么插入和取出逻辑和解释会容易得多。如果没有,请在您的问题中添加伪代码或类似内容(不要评论)
  • 当然,我会试一试。老实说,我觉得我在一个路障。我不知道从哪里开始,但我会尝试输入我的想法。
  • 是的,请这样做,这有助于更好地理解问题。你也可以举一些例子吗?例如 4 轮如何运作?

标签: algorithm recursion stack


【解决方案1】:

根据我的理解,我们可以从空堆栈开始,对于每个从堆栈弹出的排列,我们将所有可能性附加到排列中,然后将其添加回堆栈。

Stack s = new Stack();
s.add("");
ArrayList<String> result;
while(!s.isEmpty()){
    String v = s.pop();
    if(v.length() == n){//All n rounds finished, add to final result
       result.add(v);
       continue;
    }
    //Now, add the result of this round to the current permutation.

    s.push(v + "r");
    s.push(v + "s");
    s.push(v + "p");

}
return result;

【讨论】:

  • 谢谢!现在这很有意义。我的方法很偏离。我看到您只是将“r”、“p”和“s”附加到堆栈中的每个元素,而元素的长度没有达到 n。在 n=4 的情况下,我可以可视化 81 个输出和 81 + 27 + 9 + 3 次推送(代表我想到的树)。
  • @beginner 很高兴有帮助:)
【解决方案2】:

我将这个问题概括为查找从 0 到 N 的所有数字排列(在本例中 N 为 3)。解决这个问题的一种方法是使用递归:

def rec(stack, used):
    if len(stack) == len(L):
        print stack
        i = stack.pop(-1)
        used[i] = 0
        return
    for i in range(len(L)):
        if used[i] == 0:
            stack.append(i)
            used[i] = 1
            rec(stack,used)
    if len(stack):
        i = stack.pop(-1)
        used [i] = 0
    else:
        return
N = 3
rec([],[0]*N,N) 

我们所做的是将第一个未使用的项目附加到我们的列表中并再次调用该函数(回溯)。当我们的列表已满时打印该列表。这给出了所有可能的排列:

[0, 1, 2]
[0, 2, 1]
[1, 0, 2]
[1, 2, 0]
[2, 0, 1]
[2, 1, 0]

虽然此方法使用堆栈,但我怀疑这实际上是问题的意图。

问题的主要思想是实现一个回溯方法以在迭代方法中查找列表的所有排列。这就是堆栈的用武之地。

我们可以简单地通过堆栈来模拟递归函数:

stack = [(0,1)]
used = [1,0,0]
N = 3

def iterative():
    while 1:
        if len(stack) == N:
            print [x[0] for x in stack]
            i,x = stack.pop(-1)
            used[i] = 0
            continue
        top = stack.pop(-1)
        index = top[1]
        for i in range(index,N):
            if used[i] == 0:
                stack.append( (top[0],i+1) )
                stack.append( (i,0) )
                used[i] = 1
                break
        else:
            used[top[0]] = 0
            if len(stack)==0:
                if top[0]+1 < N:
                    stack.append((top[0]+1,0))
                    used[top[0]+1] = 1
                else:
                    break

唯一的区别是递归函数内部有一些局部变量,在恢复执行时它们会记住它们。我们可以将这些局部变量放入我们的堆栈中。在这种情况下,除了我们放入列表中的实际项目之外,我们还记得我们应该从什么值恢复我们的检查(这是递归函数中for 循环的变量)。这就是发生的事情:

#[stack] [used]
[(0, 1)] [1, 0, 0]
[(0, 2), (1, 0)] [1, 1, 0]
[(0, 2), (1, 3), (2, 0)] [1, 1, 1]
A new permutation:  [0, 1, 2]
[(0, 2), (1, 3)] [1, 1, 0]
[(0, 2)] [1, 0, 0]
[(0, 3), (2, 0)] [1, 0, 1]
[(0, 3), (2, 2), (1, 0)] [1, 1, 1]
A new permutation:  [0, 2, 1]
[(0, 3), (2, 2)] [1, 0, 1]
[(0, 3)] [1, 0, 0]
[(1, 0)] [0, 1, 0]
[(1, 1), (0, 0)] [1, 1, 0]
[(1, 1), (0, 3), (2, 0)] [1, 1, 1]
A new permutation:  [1, 0, 2]
[(1, 1), (0, 3)] [1, 1, 0]
[(1, 1)] [0, 1, 0]
[(1, 3), (2, 0)] [0, 1, 1]
[(1, 3), (2, 1), (0, 0)] [1, 1, 1]
A new permutation:  [1, 2, 0]
[(1, 3), (2, 1)] [0, 1, 1]
[(1, 3)] [0, 1, 0]
[(2, 0)] [0, 0, 1]
[(2, 1), (0, 0)] [1, 0, 1]
[(2, 1), (0, 2), (1, 0)] [1, 1, 1]
A new permutation:  [2, 0, 1]
[(2, 1), (0, 2)] [1, 0, 1]
[(2, 1)] [0, 0, 1]
[(2, 2), (1, 0)] [0, 1, 1]
[(2, 2), (1, 1), (0, 0)] [1, 1, 1]
A new permutation:  [2, 1, 0]
[(2, 2), (1, 1)] [0, 1, 1]
[(2, 2)] [0, 0, 1]
Finished

【讨论】:

    猜你喜欢
    • 2016-03-02
    • 2010-11-23
    • 1970-01-01
    • 2016-01-02
    • 2014-07-11
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多