使用递归函数操作数组

时间:2012-03-02 21:42:38

标签: ruby

def rps_tournament_winner(tournament)
  for i in 0..1 do
    if tournament[i][1].is_a? Array then
      rps_tournament_winner(tournament[i])
    else 
      tournament=rps_game_winner(tournament)
      return
    end
  end
  return tournament
end

这是Ruby中摇滚剪刀实现的一部分

rps_game_winner

采用格式为

的两个数组的数组
[ ["Allen", "S"], ["Omer", "P"] ]

其中第一个元素是玩家的名字,第二个元素是他们的决定并返回获胜者。

rps_tournament_winner

输入具有任意深度的嵌套数组,如

[
  [
    [ ["Armando", "P"], ["Dave", "S"] ],
    [ ["Richard", "R"], ["Michael", "S"] ],
  ],
  [
    [ ["Allen", "S"], ["Omer", "P"] ],
    [ ["David E.", "R"], ["Richard X.", "P"] ]
  ]
]

我正在尝试做的是修改原始输入,因为函数有进展但输入结果出来了。合并全局变量是一个解决方案,但这是一个用自动分级器评分的工作,我怀疑它只是将一些输入直接推送到函数并比较输出,因此它不是一个选项。

3 个答案:

答案 0 :(得分:3)

原始代码有几个问题:

  • 您将迭代与递归混合
  • 您丢弃了递归(rps_tournament_winner(tournament[i])
  • 的结果
  • 您不会返回任何有用的内容(return只返回nil,但这无关紧要,因为您仍然不使用结果)

使用原始逻辑的固定版本将是:

def rps_tournament_winner(tournament)
  result = []
  for i in 0..1 do
    if tournament[i][0][0].is_a? Array then
      result << rps_tournament_winner(tournament[i])
    else
      result << rps_game_winner(tournament[i])
    end
  end
  return result    
end

但实际上这相当于一个简单的

def rps_tournament_winner(tournament)
  if tournament[0][0].is_a? String
    rps_game_winner(tournament)
  else
    tournament.map { |t| rps_tournament_winner(t) }
  end
end

使用对象会更好:

class Game < Struct.new(:player1, :choice1, :player2, :choice2)
  def winner
    'PRSP'.include?(choice1 + choice2) ? player1 : player2
  end
end

def rps_tournament_winner(tourn)
  return tourn.winner if tourn.is_a? Game
  tourn.map { |t| rps_tournament_winner(t) }
end

答案 1 :(得分:3)

除非确定最终获胜者,否则您的递归解决方案应继续选择获胜者。 Niklas's second solution在第一级获胜者决定时停止。它应该改进如下:

def rps_tournament_winner(tournament)
    if(tournament[0][0].is_a? String)
        rps_game_winner(tournament)
    else
        rps_tournament_winner(
            [rps_tournament_winner(tournament[0]),
            rps_tournament_winner(tournament[1])]
        )
    end
end

答案 2 :(得分:1)

以下函数也可以是使用递归函数操作数组的解决方案:

def rps_tournament_winner(tournament)
    while not tournament[0].is_a? String do
        i = i == 0 ? 1 : 0
        if tournament[i][0].is_a? String
            return rps_game_winner(tournament)
        else
            tournament[i] = rps_tournament_winner(tournament[i])
        end
    end
    return tournament
end