以下是我的Element
课程的代码:
public class Element<T> {
Element<T> next;
Element<T> previous;
T info;
}
...以及CircularList
:
public class CircularList<T> {
Element<T> first=null;
public void add(Element<T> e){
if (first==null){
first=e;
e.next=e;
e.previous=e;
}
else { //add to the end;
first.previous.next=e;
e.previous = first.previous;
first.previous=e;
e.next=first;
}
}
public boolean equals(Object o){
// TODO
}
}
我不知道如何为循环列表制作一个equals方法......
只检查是否o instanceof CircularList<T>
?? (if!return false else true?)mmm .. dunno怎么做:(
我知道(从学校开始)我必须检查3个条件:
if this == o return true
if o == null return false
if !o instanceof CircularList<T> return false
...
我现在不知道是否必须检查从list1
到o
的元素,并while
...帮帮我:)
是大学考试,我不能修改或添加方法到元素类..我只需要实现equals
类的CircularList<T>
方法!
答案 0 :(得分:3)
我认为关键点是列表是循环。因此,我假设列表
A, B, C, D, E
B, C, D, E, A
应被视为相等。因为他们是。当你旋转一个圆圈时,它仍然是一个圆圈。
所以我猜诀窍就是检查另一个列表的每个元素,看看从这个元素开始时列表是否相等。在上面的例子中,人们会测试
B, C, D, E, A
是否等于A, B, C, D, E
?否C, D, E, A, B
是否等于A, B, C, D, E
?否D, E, A, B, C
是否等于A, B, C, D, E
?否E, A, B, C, D
是否等于A, B, C, D, E
?否A, B, C, D, E
是否等于A, B, C, D, E
?是。最后。快速实现一些测试用例,我希望涵盖最重要的案例:
public class CircularListEquality {
public static void main(String[] args) {
CircularList<String> c0 = createList("A", "B", "C", "D", "E");
CircularList<String> c1 = createList("A", "B", "C", "D");
CircularList<String> c2 = createList( "B", "C", "D", "E");
CircularList<String> c3 = createList( "B", "C", "D", "E", "A");
CircularList<String> c4 = createList("A", "B", "C", "A", "B", "C");
CircularList<String> c5 = createList("A", "B", "C");
CircularList<String> c6 = createList("A");
CircularList<String> c7 = createList("A", "A", "B", "C");
test(c0, c1, false);
test(c0, c2, false);
test(c1, c2, false);
test(c0, c3, true);
test(c3, c0, true);
test(c4, c5, false);
test(c5, c4, false);
test(c6, c7, false);
}
private static <T> void test(
CircularList<T> c0, CircularList<T> c1, boolean expected) {
boolean actual = c0.equals(c1);
if (actual == expected) {
System.out.print("PASSED");
} else {
System.out.print("FAILED");
}
System.out.println(" for " + toString(c0) + " and " + toString(c1));
}
private static <T> String toString(CircularList<T> c) {
StringBuilder sb = new StringBuilder();
Element<T> current = c.first;
while (true) {
sb.append(String.valueOf(current.info));
current = current.next;
if (current == c.first) {
break;
} else {
sb.append(", ");
}
}
return sb.toString();
}
private static CircularList<String> createList(String... elements) {
CircularList<String> c = new CircularList<String>();
for (String e : elements) {
c.add(createElement(e));
}
return c;
}
private static <T> Element<T> createElement(T t) {
Element<T> e = new Element<T>();
e.info = t;
return e;
}
}
class Element<T> {
Element<T> next;
Element<T> previous;
T info;
}
class CircularList<T> {
Element<T> first = null;
public void add(Element<T> e) {
if (first == null) {
first = e;
e.next = e;
e.previous = e;
} else { // add to the end;
first.previous.next = e;
e.previous = first.previous;
first.previous = e;
e.next = first;
}
}
public boolean equals(Object object) {
if (this == object)
{
return true;
}
if (object == null)
{
return false;
}
if (!(object instanceof CircularList<?>))
{
return false;
}
CircularList<?> that = (CircularList<?>) object;
Element<?> first0 = first;
Element<?> current0 = first0;
Element<?> first1 = that.first;
Element<?> current1 = first1;
while (true) {
if (equalSequence(current0, current0, current1, current1)) {
return true;
}
current1 = current1.next;
if (current1 == first1) {
return false;
}
}
}
private static boolean equalSequence(
Element<?> first0, Element<?> current0,
Element<?> first1, Element<?> current1) {
while (true) {
if (!equalElements(current0, current1)) {
return false;
}
current0 = current0.next;
current1 = current1.next;
if (current0 == first0 && current1 == first1) {
return true;
}
if (current0 == first0) {
return false;
}
if (current1 == first1) {
return false;
}
}
}
private static boolean equalElements(Element<?> t0, Element<?> t1) {
if (t0 == null) {
return t1 == null;
}
return equal(t0.info, t1.info);
}
private static <T> boolean equal(T t0, T t1) {
if (t0 == null) {
return t1 == null;
}
return t0.equals(t1);
}
}
(编辑:增加了另一个测试用例)
答案 1 :(得分:2)
通过稍微调整CircularList
课程来获得解决方案:让我们添加length
字段。
public class CircularList<T> {
int length = 0; // <- this field contains the number of elements that the list has.
Element<T> first = null;
public void add(Element<T> e){
if (first == null){
first = e;
e.next = e;
e.previous = e;
}
else {
first.previous.next = e;
e.previous = first.previous;
first.previous = e;
e.next = first;
}
this.length++; // <- increment each time you call add().
}
}
现在,实施equals
变得微不足道了:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
@SuppressWarnings("unchecked")
final CircularList<T> other = (CircularList<T>) obj;
if(other.length != this.length) {
return false;
}
Element<T> current = this.first;
Element<T> otherCurrent = other.first;
int offset = 0;
boolean found = false;
do {
found = checkSequence(current, otherCurrent);
if(!found) {
offset++;
otherCurrent = otherCurrent.next;
}
} while(!found && offset < length) ;
return found;
}
private boolean checkSequence(Element<T> current, Element<T> otherCurrent) {
int i = 0;
while(i < length && current.info == otherCurrent.info) {
current = current.next;
otherCurrent = otherCurrent.next;
i++;
}
return i == length;
}
我在checkSequence
方法中所做的只是迭代每个元素(两个列表中都有length
个)并检查它们是否完全相同通过配对。
然后,如果我因i
到达length
而离开我的循环,则意味着我已经浏览了所有元素并且它们都是相同的。如果此时i
小于length
,则表示列表的i
个元素不相同。
因此,我只返回i == length
。
除此之外,我还想处理我们正在考虑以下列表的案例:
...必须是equal
。
因此,我只需拨打checkSequence
,最多length
次,将第二个列表与第一个列表进行比较,并列出所有可能的偏移量。
答案 2 :(得分:0)
!
运算符只是将true反转为false,反之亦然。
所以,关于那件事的你的代码将意味着与实际的
相反if !o instanceof CircularList<T>
将返回false,如果 o
对象是实例 CircularList<T>
。否则,如果o
不是CirculatList<T>
的实例,则返回true。您只是想反转o instanceof CircularList<T>
的实际结果。
答案 3 :(得分:0)
这等于实现怎么样?我们可以避免调整你的课程。
public boolean equals(CircularList<T> other)
{
**Standard checks will go here (ref equals, class type etc)**
boolean result = false;
result = first.equals(other.first);
Element<T> next = first.next;
Element<T> nextOfOther = other.first.next;
while (null != next && null != nextOfOther)
{
// break cyclic loop
if (next.equals(first))
break;
result = next.equals(nextOfOther);
if (!result)
// We know they aren't equal so break
break;
next = next.next;
nextOfOther = nextOfOther.next;
}
return result;
}
答案 4 :(得分:0)
指令:this == o;
只有当它们具有相同的地址时(当它是同一个对象时)才返回true,我认为当两个列表包含相同的元素时,你需要的东西会返回true,试试这个:
public boolean equals(CircularList<T> other){
Element<T> e1 = first;
Element<T> e2 = other.first;
while(e1.next != first && e2.next != other.first){
if(e1.info == e2.info){
e1 = e1.next;
e2 = e2.next;
}
else return false;
}
if (e1.next == first && e2.next == other.first)
return true;
else return false;
}
我认为这会起作用!!
答案 5 :(得分:0)
这个怎么样,在这里我将首先找到并检查长度,然后检查元素。
public boolean equals(CircularList<T> other)
{
boolean result = false;
result = first.equals(other.first);
if (!result)
return result;
Element<T> next = first.next;
Element<T> nextOfOther = other.first.next;
int firstCount = 1;
while (null != next)
{
if (next.equals(first))
break;
firstCount++;
next = next.next;
}
int secondCount = 1;
while (null != nextOfOther)
{
if (nextOfOther.equals(other.first))
break;
secondCount++;
nextOfOther = nextOfOther.next;
}
if (firstCount != secondCount)
{
result = false;
}
next = first.next;
nextOfOther = other.first.next;
while (firstCount > 1)
{
result = next.equals(nextOfOther);
if (!result)
// We know they aren't equal so break
break;
next = next.next;
nextOfOther = nextOfOther.next;
firstCount--;
}
return result;
}