检查2链表是否具有相同的元素,无论顺序如何

时间:2014-11-13 14:37:54

标签: smalltalk squeak

有没有办法检查2个链接列表是否具有相同的元素,无论顺序如何。

编辑问题: 我修复了代码并提供了更多细节:

这是比较2个列表的方法

 compare: object2
     ^ ((mylist asBag) = ((objetc2 getList) asBag)).

该方法属于myClass类,它有一个字段:myLList。 myList是type元素的linkedList。

我在工作区编译了它:

  a: = element new id:1.
  b:= element new id:2.
  c:=element new id:3.

  d: = element new id:1.
  e:= element new id:2.
  f:=element new id:3.

  elements1 := myClass new. 
  elements addFirst:a.
   elements addFirst:b.
   elements addFirst:c.

   elements2 := myClass new. 
   elements addFirst:d.
   elements addFirst:e.
   elements addFirst:f. 
   Transcript show: (elements1 compare:elements2).

所以我变得虚假..似乎它通过引用检查相等而不是通过值检查等等。

所以我认为要问的正确问题是:如何按价值比较2个包?我试过了'=='..但它也返回了false。

2 个答案:

答案 0 :(得分:4)

修改 问题也改变了太多 - 我认为它本身应该有一个新问题。

这里的问题是(element new id: 1) = (element new id: 1)正在给你false。除非它的特定类(或超类)重新定义它,否则=消息默认情况下通过标识(==)进行比较。这就是为什么您的代码仅适用于与自身进行比较的集合的原因。

使用例如数字列表(其中重新定义=方法以反映人类通过数字相等理解的内容)来测试它,并且它将起作用。

您应该重新定义element的课程' =(和hashCode)方法可以实现此目的。

Smalltalk通过引用处理所有:所有存在的对象都知道( reference )其他对象。


如果两个列表的顺序不同,则说明两个列表是等价的,因为的顺序是列表的一部分。没有订单的列表就是我们所说的

asBag消息(与所有其他as<anotherCollectionType>消息一样)返回指定类型的新集合以及接收者的所有元素。因此,#(1 2 3 2)是四个元素的Array#(1 2 3 2) asBag是包含这四个元素的包。因为它是一个包,它没有任何特定的顺序。

执行bagA := Bag new.时,您正在创建新的Bag实例,并使用bagA变量引用它。但是你做了bagA := myList asBag,所以你丢失了对前一个包的引用 - 第一个作业在你的代码中没有做任何有用的,因为你不能使用那个包。

aBool ifTrue: [^true] ifFalse: [^false]^aBool的含义完全相同 - 所以我们更愿意这样说。而且,由于您只创建了这两个新包来比较它们,您可以像这样简化整个方法:

compareTo: anotherList
  ^ myList asBag = anotherList asBag

大声朗读:此对象(无论是什么)另一个列表进行比较,如果它没有考虑顺序的列表与其他列表相同没有订单。

名称compareTo:对于返回布尔值有点奇怪(containsSameElements:会更具描述性),但使用此代码可以更快地获得更多点。


准确地说明你的问题:

1)它不起作用,因为您正在比较bag1bag2,但只是定义了bagAbagB

2)创建这两个额外的行李只是因为并发送无意义的ifTrue:消息效率不高,但其他方式还可以。您可以实施更好的方式来比较列表,但是依靠asBag的实施以及Bag的{​​{1}}消息表现更好

3)我认为你可以看到=源代码,但是,是的,你可以假设它是这样的:

asBag

当然,Collection>>asBag |instance| instance := Bag new. instance addAll: self. ^instance 方法可以是:

addAll:

所以,是的 - 它创造了一个包含所有接收器元素的新包。

答案 1 :(得分:4)

mgarciaisaia的答案很好......也许太好了!这可能听起来很刺耳,但是如果你认真学习,我希望你能成功,所以我再次提出我的另一个问题的建议,就是你立即拿起一本好的Smalltalk基础教科书。根据放纵的做法,将无意义的片段重新编写为可行的代码是学习编程的一种非常低效的方式;)

编辑:问题发生了巨大变化。以下是原来的三部分问题的内容,所以我将内联的原始问题解释了。

  1. 问:问题是什么?答:问题是缺乏对Smalltalk的基本理解。
  2. 问:转换成行李是一种有效的比较方法吗?答:虽然它可能效率不高,但现在不用担心。总的来说,特别是在你没有对它有很好的直觉的开始时,避免过早优化 - &#34;让它工作&#34;,然后只有&#34;快速做到&#34;如果通过真实的剖析来证明这一点。
  3. 问:#asBag如何运作?答:#asBag的实现与您自己的代码在同一个生活世界中可用。学习的最佳方式是直接查看实施(可能是通过浏览实施者和#34;如果您不确定它的定义和#34;)并回答您自己的问题!如果您无法理解该实现,请参阅#1。