gpt4 book ai didi

java - "Comparison method violates its general contract!",一切似乎都正常

转载 作者:行者123 更新时间:2023-11-30 03:25:03 25 4
gpt4 key购买 nike

我知道 Java 中的比较规则(以及一般情况),如 here 中所述。 .
我有一个字符串数组列表。
每个字符串代表一手德州扑克,忽略花色。
每个字符串的长度正好是 13 个字符。
每个字符串仅由总和为 7 的数字组成。

例如,“0100300200100”代表一手扑克牌,由一张 3 的牌、三张 6 的牌、两张 9 的牌和一张 Q 组成。
(在这种情况下,手牌代表葫芦 - 六满九)。

我想根据扑克牌的强度对这个列表进行排序。
我有以下java代码,它实现了Comparator的compare方法。

final Comparator<String> COMBINATION_ORDER = new Comparator<String>() {
@Override
public int compare(String c1, String c2) {
if (c1.indexOf('4') != -1 || c2.indexOf('4') != -1) { // Four of a kind
if (c1.indexOf('4') == c2.indexOf('4')) {
for (int i = 12; i >= 0; i--) {
if (c1.charAt(i) != '0' && c1.charAt(i) != '4') {
if (c2.charAt(i) != '0' && c2.charAt(i) != '4') {
return 0;
}
return 1;
}
if (c2.charAt(i) != '0' && c2.charAt(i) != '4') {
return -1;
}
}
}
return c1.indexOf('4') - c2.indexOf('4');
}
int tripleCount1 = StringFunctions.countOccurrencesOf(c1, "3");
int tripleCount2 = StringFunctions.countOccurrencesOf(c2, "3");
if (tripleCount1 > 1 || (tripleCount1 == 1 && c1.indexOf('2') != -1) || tripleCount2 > 1 || (tripleCount2 == 1 && c2.indexOf('2') != -1)) { // Full house
int higherTriple = c1.lastIndexOf('3');
if (higherTriple == c2.lastIndexOf('3')) {
for (int i = 12; i >= 0; i--) {
if (i == higherTriple) {
continue;
}
if (c1.charAt(i) == '2' || c1.charAt(i) == '3') {
if (c2.charAt(i) == '2' || c2.charAt(i) == '3') {
return 0;
}
return 1;
}
if (c2.charAt(i) == '2' || c2.charAt(i) == '3') {
return -1;
}
}
}
return higherTriple - c2.lastIndexOf('3');
}
return 0;
}
};

在此期间,我仅指“四人一类”和“欢乐满屋”。这意味着其他所有牌都将被视为彼此平等(但低于四张牌或葫芦牌)。

但是当我排序时:

combinations.sort(COMBINATION_ORDER);

(其中组合是我的ArrayList)。

我遇到异常。

Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(TimSort.java:773)
at java.util.TimSort.mergeAt(TimSort.java:510)
at java.util.TimSort.mergeCollapse(TimSort.java:437)
at java.util.TimSort.sort(TimSort.java:241)
at java.util.Arrays.sort(Arrays.java:1512)
at java.util.ArrayList.sort(ArrayList.java:1454)
at Poker.main(Poker.java:120)

请帮我理解代码有什么问题。
非常感谢。

编辑:

正如 @ajb 所说,我没有考虑没有 Full House 的三人制游戏。

解决方案:

final Comparator<String> COMBINATION_ORDER = new Comparator<String>() {
@Override
public int compare(String c1, String c2) {
if (c1.indexOf('4') != -1 || c2.indexOf('4') != -1) { // Four of a kind
if (c1.indexOf('4') == c2.indexOf('4')) {
for (int i = 12; i >= 0; i--) {
if (c1.charAt(i) != '0' && c1.charAt(i) != '4') {
if (c2.charAt(i) != '0' && c2.charAt(i) != '4') {
return 0;
}
return 1;
}
if (c2.charAt(i) != '0' && c2.charAt(i) != '4') {
return -1;
}
}
}
return c1.indexOf('4') - c2.indexOf('4');
}
int tripleCount1 = StringFunctions.countOccurrencesOf(c1, "3");
int tripleCount2 = StringFunctions.countOccurrencesOf(c2, "3");
if (tripleCount1 > 1 || (tripleCount1 == 1 && c1.indexOf('2') != -1)) { // c1 Full house
if (tripleCount2 > 1 || (tripleCount2 == 1 && c2.indexOf('2') != -1)) { // c2 Full house too
int higherTriple = c1.lastIndexOf('3');
if (higherTriple == c2.lastIndexOf('3')) {
for (int i = 12; i >= 0; i--) {
if (i == higherTriple) {
continue;
}
if (c1.charAt(i) == '2' || c1.charAt(i) == '3') {
if (c2.charAt(i) == '2' || c2.charAt(i) == '3') {
return 0;
}
return 1; // only c1 Full house
}
if (c2.charAt(i) == '2' || c2.charAt(i) == '3') { // only c2 Full house
return -1;
}
}
}
return higherTriple - c2.lastIndexOf('3');
}
return 1;
}
if (tripleCount2 > 1 || (tripleCount2 == 1 && c2.indexOf('2') != -1)) {
return -1;
}
return 0;
}
};

最佳答案

比较器必须遵守的条件之一是它必须是可传递的。也就是说,如果 A > B 且 B > C,则 A > C。如果比较器不遵循此规则,则排序可能会遇到排序不符合预期的情况,然后会抛出异常.

您的算法中至少存在一个逻辑错误。 (可能还有其他错误,但我绝对可以发现这个错误,并且它肯定会导致异常。)问题是当一只手有葫芦,而另一只手有 3 个同种牌但不是葫芦时。您的代码并不总是让整个房子变得更大。如果 3 张牌是比葫芦中的三张牌更高的三张牌,则 3 张牌将比较更大。所以说一只手是KKK8743,另一只手是QQQ6632,另一只手是JJJ8743。您的代码错误地使 KKK8743 > QQQ6632。它还显示 QQQ6632 > JJJ8743。但它也说 KKK8743 = JJJ8743,因此传递性被违反。

关于java - "Comparison method violates its general contract!",一切似乎都正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30449488/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com