检查Ruby中两个链表是否相等?

时间:2014-08-26 01:25:37

标签: ruby

我在Ruby中有以下链表实现:

class Node
  attr_accessor :data, :next

  def initialize(data = nil)
    @data = data
    @next = nil
  end
end

class LinkedList
  def initialize(items)
    @head = Node.new(items.shift)
    items.inject(@head) { |last, data| @tail = last.next = Node.new(data) }
  end

  def iterate
    return nil if @head.nil?

    entry = @head
    until entry.nil?
      yield entry
      entry = entry.next
    end
  end

  def equal?(other_list)
    #How do I check if all the data for all the elements in one list are the same in the other one?
  end
end

我尝试过使用像这样的.iterate:

def equals?(other_list)
  other_list.iterate do |ol|
    self.iterate do |sl|
      if ol.data != sl.data
         return false
      end
    end
  end
  return true
end

但这是做嵌套的方法。我没看到怎么做。

2 个答案:

答案 0 :(得分:2)

您无法使用当前定义的方法轻松完成,因为无法访问单个下一个元素。此外,如果您实施each而不是iterate,则会非常有用,然后会为您提供Enumerable mixin的全部功能。

class LinkedList
  include Enumerable  # THIS allows you to use `zip` :)

  class Node # THIS because you didn't give us your Node
    attr_accessor :next, :value
    def initialize(value)
      @value = value
      @next = nil
    end
  end

  def initialize(items)
    @head = Node.new(items.shift)
    items.inject(@head) { |last, data| @tail = last.next = Node.new(data) }
  end

  def each
    return enum_for(__method__) unless block_given?  # THIS allows block or blockless calls
    return if @head.nil?

    entry = @head
    until entry.nil?
      yield entry.value  # THIS yields node values instead of nodes
      entry = entry.next
    end
  end

  def ==(other_list)
    # and finally THIS - get pairs from self and other, and make sure all are equal
    zip(other_list).all? { |a, b| a == b }
  end
end

a = LinkedList.new([1, 2, 3])
b = LinkedList.new([1, 2, 3])
c = LinkedList.new([1, 2])

puts a == b  # => true
puts a == c  # => false

编辑:我在第一次运行时错过了这个:equal?应该是参照标识,即如果它们包含对同一个引用的两个变量equal?宾语。即使可能,也不应重新定义该方法。相反,==是“相同”的一般共同语言含义,如“具有相同的价值”,所以我将其改为。

答案 1 :(得分:0)

我认为您在LinkedList中的初始化方法有问题,无论这是否是您需要的

...
def equal?(other_list) other_index = 0 cur_index = 0 hash = Hash.new other_list.iterate do |ol| hash[ol.data.data] = other_index other_index += 1 end self.iterate do |node| return false if hash[node.data.data] != cur_index return false if !hash.has_key?(node.data.data) cur_index += 1 end return true end ...

假设您使用代码的方式

a = Node.new(1)
b = Node.new(2)
c = Node.new(3)

listA = [a,b,c]

aa = Node.new(1)
bb = Node.new(2)  
cc = Node.new(3)

listB = [aa,bb,cc]

linkA = LinkedList.new(listA)
linkB = LinkedList.new(listB)

puts linkA.equal?(linkB)