【问题标题】:Problems in code to Print the possibilities of wins in a Coin game打印硬币游戏中获胜可能性的代码问题
【发布时间】:2018-06-20 12:19:45
【问题描述】:

我正在使用回溯递归解决以下问题。第一个代码“CoinGame1”提供了正确的解决方案,但第二个代码“CoinGame2”提供了错误的解决方案。我想,发生了一些不好的事情,因为我在递归调用之前先反转了字符串。

*硬币游戏:Alice 和 Bob 正在使用一堆硬币玩游戏。玩家依次从一堆硬币中挑选出几个硬币。每个玩家每回合可以选择 1、2 或 4 个硬币。每次允许玩家挑选硬币时, 获得最后一枚硬币的玩家为获胜者。众所周知,最后,当剩下1、2或4个硬币时,第一个回合的玩家肯定会根据需要选择1、2或4个硬币并获胜。例如,如果最后有 2 个硬币,而 Alice 是第一个选择的玩家,那么她肯定会选择 2 个硬币并获胜。给定硬币的数量和玩家的顺序(这意味着第一个和第二个挑选硬币的玩家),编写一个程序来打印获胜者的所有可能性 游戏中,

F(1, {爱丽丝,鲍勃}) 爱丽丝 F(6, {爱丽丝,鲍勃}) 爱丽丝, 鲍勃, 鲍勃, 爱丽丝, 鲍勃, 鲍勃 F(4, {爱丽丝,鲍勃}) 爱丽丝 F(3, {爱丽丝,鲍勃}) 鲍勃,鲍勃* f(6,{A,B}) / \ \ f(5,{B,A}) f(4,{B,A}) f(2,{B,A}) / | \ B 赢 B 赢 f(4,{A,B}) f(3,{A,B}) f(1,{A,B}) A胜/| \A胜 / | \ f(2,{B,A}) f(1,{B,A}) f(-1,{B,A}) B 赢 B 赢

//解决方案1

public class CoinGame1
{
   public static void Count(int n, String[] s)   // n: no. of coins 
                                               //s:{"Alice","Bob"} (order) 
  {
       if(n>0)
       {
           if(n==1 || n==2 || n==4) System.out.println( s[0] );  // if 1/2/4 
                                 //coins left, the one with first chance wins
           else
           { 
               Count(n-1,new String[]{s[1],s[0]});
               Count(n-2,new String[]{s[1],s[0]});
               Count(n-4,new String[]{s[1],s[0]});  
           }
       }
  }

  public static void main(String[] args)
      {
          String[] order = new String[]{"A","B"};
          Count(6,order);
      }
}

java CoinGame1 一种 乙 乙 一种 乙 乙

//解决方案2

public class CoinGame2
{
   public static void Count(int n, String[] s)          // n: no. of coins    
                                                 //s:{"Alice","Bob"} (order) 
  {
       if(n>0)
       {
           if(n==1 || n==2 || n==4) System.out.println( s[0] );  // if 1/2/4 
                                //coins left, the one with first chance wins
           else
           {
               String temp = s[0]; s[0] = s[1]; s[1] = temp;     // reverse s
               Count(n-1,s);
               Count(n-2,s);
               Count(n-4,s);  
           }
       }
  }

  public static void main(String[] args)
      {
          String[] order = new String[]{"A","B"};
          Count(6,order);
      }
}

java CoinGame2 一种 乙 乙 乙 乙 乙

【问题讨论】:

  • 在您的第二个 sn-p 中,您正在改变数组,但是在所有迭代中都使用相同的数组实例。将System.out.println(Arrays.asList(s)); 放在每个Count(...) 之前。见stackoverflow.com/q/40480/1225328
  • @sp00m 谢谢....第二个代码只给出了不正确的第四个值..我无法通过调试来理解。我尝试调试第二个代码,发现 f(-1,{B,A}) 正在返回 f(5,{B,A}) (而不是 f(5,{A,B}) ),最终调用 f(1,{B,A})) (而不是 f(1,{A,B}) )返回 B 。为什么 f(-1,{B,A}) 不返回 f(5,{A,B})?

标签: java recursion tail-recursion backtracking recursive-backtracking


【解决方案1】:

它有时有助于简化递归问题。我重写了你的问题,但我从 5 个硬币开始,然后选择 1 或 2。这样,第一个选择者总是会获胜。你唯一能输的方法就是连续选择两次,结果不言而喻。运行这段代码,结论就很清楚了,就像上面所说的,整个过程都在运行同一个s实例。

    public static void Count(int n, String[] s)          // n: no. of coins
    //s:{"Alice","Bob"} (order)
    {
        if(n>0)
        {
            if(n==1 || n==2 ) System.out.println( s[0] );  // if 1/2/4
                //coins left, the one with first chance wins
            else
            {
                String temp = s[0]; s[0] = s[1]; s[1] = temp;     // reverse s
                Count(n-1,s);
                Count(n-2,s);

            }
        }
    }

    public static void main(String[] args)
    {
        String[] order = new String[]{"A","B"};
        Count(5,order);
    }
    // the result is B,B,B,A,A

【讨论】:

  • 在这种情况下,正确答案应该是 B, B, A, A, A 。代码应该返回 B、B、A、A、A。我们在这段代码中也面临同样的问题。在这种情况下,同样的 Array 's' 实例也在运行。
【解决方案2】:

SOLUTION2 的变化(现在给出正确的结果)

导入 java.util.*; 公开课 CoinGame2 { public static void Count(int n, String[] s) // n: 没有。硬币数量,s:{"Alice","Bob"} (order) { 如果(n>0) { if(n==1 || n==2 || n==4) System.out.println( s[0] ); // 如果还剩 1/2/4 个硬币,先有机会的获胜 别的 { // 字符串 temp = s[0]; s[0] = s[1]; s[1] = 温度; // 反转 s String[] t = Arrays.copyOfRange(s,0,s.length); 字符串温度 = t[0]; t[0] = t[1]; t[1] = 温度; 计数(n-1,t); 计数(n-2,t); 计数(n-4,t); } } } 公共静态无效主要(字符串 [] 参数) { String[] order = new String[]{"A","B"}; 计数(6,顺序); } }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多