gpt4 book ai didi

java - 如果子集共享共同值(value),则将子集组合成更大的集

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:33:02 24 4
gpt4 key购买 nike

我正在尝试创建一种方法,该方法将返回具有邻居的最大卡片集。例如,如果我有 list<RANK> rankList = [FIVE, QUEEN, KING, ACE, TEN]它会返回 [KING, ACE, QUEEN] .我还没有完全实现它,但我通过将一组拆分为多个较小的组来获得该部分。

private boolean isStraight(List<Card> cards) {
Set<RANK> rankList = cards.stream()
.map(Card::getRank)
.distinct()
.collect(Collectors.toSet());


List<Set<RANK>> subSets = new ArrayList<>();

for(RANK rank : rankList) {
int currRankValue = rank.getValue();
RANK prevRank = RANK.getRank(currRankValue - 1);
RANK nextRank = RANK.getRank(currRankValue + 1);

if(!subSets.stream().anyMatch(set -> set.contains(rank))) {
Set<RANK> newSet = new HashSet<>();
newSet.add(rank);
subSets.add(newSet);
}

subSets.stream()
.filter(set -> (set.contains(prevRank) || set.contains(nextRank)))
.forEach( set -> set.add(rank));
}

System.out.print(subSets);
return false;
}

Card.java:

 public static enum RANK {
NONE(0),
TWO(2), THREE(3), FOUR(4), FIVE(5),
SIX(6), SEVEN(7), EIGHT(8), NINE(9),
TEN(10), JACK(11), QUEEN(12), KING(13), ACE(14);

private final int value;

private RANK(int value) {
this.value = value;
}

public int getValue() {
return value;
}

public static RANK getRank(int value) {
for(RANK r : RANK.values() ) {
if (r.getValue() == value)
return r;
}
return NONE;
}
}

在我检查是否有 5 张或更多张牌可以形成顺子之前,我已经组合了至少具有一个共同值的子集。我该怎么做?我想不出任何不涉及很多循环的东西。

已编辑

添加了整个Card.java:

ppackage deck;

public class Card implements Comparable {

public static enum SUIT {
SPADES,
HEARTS,
CLUBS,
DIAMONDS
}

public static enum RANK {
NONE(0),
TWO(2), THREE(3), FOUR(4), FIVE(5),
SIX(6), SEVEN(7), EIGHT(8), NINE(9),
TEN(10), JACK(11), QUEEN(12), KING(13), ACE(14);

private final int value;

private RANK(int value) {
this.value = value;
}

public int getValue() {
return value;
}

public static RANK getRank(int value) {
for(RANK r : RANK.values() ) {
if (r.getValue() == value)
return r;
}
return NONE;
}
}

private final RANK rank;
private final SUIT suit;

public Card(RANK rank, SUIT suit) {
this.rank = rank;
this.suit = suit;
}

public RANK getRank() {
return rank;
}

public SUIT getSuit() {
return suit;
}

@Override
public String toString() {
return "Card{" +
"rank=" + rank +
", suit=" + suit +
'}';
}

@Override
public int compareTo(Object that) {
return this.rank.getValue() - ((Card) that).rank.getValue();
}
}

已编辑

添加了带循环的解决方案:在方法返回之前添加它。

for(int index = 0; index < subSets.size(); index++) {
for(int index2 = 1; index2 < subSets.size(); index2++) {
if(!Collections.disjoint(subSets.get(index), subSets.get(index2)) && index != index2) {
subSets.get(index).addAll(subSets.remove(index2));
index2--;
}
}
}

最佳答案

我关注的是与“有邻居的最大牌组”相关的问题方面。如果对卡片排名值列表进行排序,这将转化为对列表运行进行分段然后从这些分段中选择最长运行的问题。

精明的读者会注意到与 this question 的相似之处.我将使用类似于 my answer 的技术对那个问题。

首先,让我们从包含 OP 示例中的输入列表开始。不过,以下技术应该适用于任何输入。

    List<Rank> rankList = [FIVE, QUEEN, KING, ACE, TEN];

让我们排序并使这个列表具有独特的元素:

    List<Rank> sorted = rankList.stream()
.distinct()
.sorted()
.collect(toList());

[FIVE, TEN, QUEEN, KING, ACE]

现在让我们计算应该将列表拆分为连续排名值的单独运行的位置。这发生在列表中彼此相邻的值不是连续排名值的位置。我们通过索引列表(从 1 开始)并通过检查列表中的相邻值来过滤索引来做到这一点:

    List<Integer> splits = IntStream.range(1, sorted.size())
.filter(i -> sorted.get(i).ordinal() != sorted.get(i-1).ordinal() + 1)
.boxed()
.collect(toCollection(ArrayList::new));

[1, 2]

这些是运行之间的位置。这几乎足以创建子列表的信息,但它省略了第一个子列表的开头和最后一个子列表的结尾的索引。要添加这些,我们只需在前面添加 0 并在末尾添加 size:

    splits.add(0, 0);
splits.add(list.size());

[0, 1, 2, 5]

现在我们可以使用每对索引来生成包含每次运行的子列表:

    List<List<Rank>> runs = IntStream.range(1, splits.size())
.mapToObj(i -> list.subList(splits.get(i-1), splits.get(i)))
.collect(toList());

[[FIVE], [TEN], [QUEEN, KING, ACE]]

我们可以找到最长的运行,然后打印出与其长度匹配的运行:

    int longest = runs.stream()
.mapToInt(list -> list.size())
.max()
.getAsInt();
runs.stream()
.filter(list -> list.size() == longest)
.forEach(System.out::println);

[QUEEN, KING, ACE]

综合起来,我们有:

static void split(List<Rank> rankList) {
List<Rank> sorted = rankList.stream()
.distinct()
.sorted()
.collect(toList());

List<Integer> splits = IntStream.range(1, sorted.size())
.filter(i -> sorted.get(i).ordinal() != sorted.get(i-1).ordinal() + 1)
.boxed()
.collect(toCollection(ArrayList::new));

splits.add(0, 0);
splits.add(sorted.size());

List<List<Rank>> runs = IntStream.range(1, splits.size())
.mapToObj(i -> sorted.subList(splits.get(i-1), splits.get(i)))
.collect(toList());

int longest = runs.stream()
.mapToInt(list -> list.size())
.max()
.getAsInt();

runs.stream()
.filter(list -> list.size() == longest)
.forEach(System.out::println);
}

关于java - 如果子集共享共同值(value),则将子集组合成更大的集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29826531/

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