为什么我的print_linked_list_in_reverse函数不起作用?

时间:2017-03-25 21:26:45

标签: ruby recursion hash linked-list

我正在做的Ruby课程中的一个挑战是打印以下链接列表的:data值,反之: {:data=>3, :next=>{:data=>2, :next=>{:data=>1, :next=>nil}}} 所以当我的方法传递上面的代码时,它应该返回

1
2
3

这是我的尝试,对上述代码不起作用。我无法弄清楚原因,如果有人能解释我做错了什么,我会很感激:

def print_list_in_reverse(hash)
  if hash[:next].nil?                       #i.e. is this the final list element?
    print "#{hash[:data]}\n"
    return true
  else
    #as I understand it, the next line should run the method on `hash[:next]` as well as checking if it returns true.
    print "#{hash[:data]}\n" if print_list_in_reverse(hash[:next])   
  end
end

这是一个解决方案,万一它可以帮助你发现我的错误。

def print_list_in_reverse(list)
  return unless list
  print_list_in_reverse list[:next]
  puts list[:data]
end

谢谢。

3 个答案:

答案 0 :(得分:1)

代码中的问题是在else-case中。您需要返回true才能打印hash[:data]

您的方法始终打印最后2个元素。

答案 1 :(得分:1)

最好迭代哈希中的每个值,并推送值,直到主哈希中没有任何其他哈希作为值。

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.pivotal.spring.cloud</groupId>
            <artifactId>spring-cloud-services-dependencies</artifactId>
            <version>1.2.0.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
      ...
    </dependencies>
</dependencyManagement>
<dependencies>
    ...
    <dependency>
        <groupId>io.pivotal.spring.cloud</groupId>
        <artifactId>spring-cloud-services-starter-service-registry</artifactId>
    </dependency>
    ...
</dependencies>

答案 2 :(得分:1)

您的解决方案依赖于返回值,并且您未在else子句中明确提供。实际上,你隐式地这样做是因为Ruby返回了最后一个语句的结果,print语句的结果是nil。在Ruby中,falsenil在逻辑上都是错误的,导致print除了最后两个调用之外都被绕过。您的选择是在true的末尾添加else,或者制作一个不依赖于返回值的解决方案。

要取消对返回值的需要,只需根据当前调用中的信息检查哪些逻辑是犹太教的。您可以通过利用“真实性”非零对象来简化您的生活。你反过来的基本递归逻辑是“从列表的其余部分打印内容,然后打印我的东西。”基于真实性的直接实现将是:

def print_list_in_reverse(hash)
  print_list_in_reverse(hash[:next]) if hash[:next]
  print "#{hash[:data]}\n"
end

问题在于你可能已被交给一个空列表,在这种情况下你不想打印任何东西。这很容易检查:

def print_list_in_reverse(hash)
  print_list_in_reverse(hash[:next]) if hash[:next]
  print "#{hash[:data]}\n" if hash
end

只要你拿到一个哈希值就行了,即使它是空的。如果你对于交给nil

感到妄想
def print_list_in_reverse(hash)
  print_list_in_reverse(hash[:next]) if hash && hash[:next]
  print "#{hash[:data]}\n" if hash
end

另一种方法是首先检查当前列表元素是否为nil并在此情况下立即返回。否则,请遵循上面概述的基本递归逻辑。这导致您提供的解决方案。