Kev*_*inO 6 java arrays java-8 java-stream
基于BlackJack问题,我想知道如何表明所有获胜的手牌.实际上,原始问题只是简单地询问了两个不大于21的数字.所以这样的方法就像
public int blackjack(int a, int b);
Run Code Online (Sandbox Code Playgroud)
但是,如果有人希望返回所有获胜的牌(假设输入数组中的位置是桌子上的座位),那么签名如下:
/**
* returns an array indicate the index in the specified hands that
* correspond to the winning locations. Will return an empty array if
* there are no winners. The length of the returned array is how many
* winning hands there were
* @param hands The total for each hand, where the index is the seat
* @return the index/"seat" where a winning hand was found; may return
* an empty array
*/
public int[] blackjack(int[] hands) { ... }
Run Code Online (Sandbox Code Playgroud)
因此基于输入数据,例如(仅在"座位"0,1,2处使用3个"玩家"):
{17,15,23}
{23,25,22}
{18,16,18}
{16,21,20}
我希望输出的结果如下:
手:[17,15,23]在[0]
获胜者
手中:[23,25,22 ]没有获胜者手:[18,16,18]在[0,2]
手中获胜:[16,21 ] ,20]在[1]获奖
在过去,我会迭代hands[]数组,找到<= 21的最大值,然后再次迭代找到等于最大值的每个索引.所以像这样:
public static int[] blackjackByIteration(int[] hands)
{
int max = 0;
int numAtMax = 0;
for (int i = 0; i < hands.length; ++i) {
if (hands[i] <= 21 && hands[i] > max) {
max = hands[i];
numAtMax = 1;
}
else if (hands[i] == max) {
++numAtMax;
}
}
int[] winningSeats = new int[numAtMax];
int loc = 0;
for (int i = 0; i < hands.length; ++i) {
if (hands[i] == max) {
winningSeats[loc++] = i;
}
}
return winningSeats;
}
Run Code Online (Sandbox Code Playgroud)
但是,我想知道是否有更有效的方法通过流实现它.我认识到使用Lambdas不是解决所有问题的方法.我相信,如果我已经正确阅读,那么就不可能直接找到int[]数组的索引,因此该方法必须依赖于使用a List<Integer>,如上面引用的问题所示.
我使用Streams做了一个初步的解决方案,但是想知道是否有更有效的方法.我完全承认我对流的理解是有限的.
public static int[] blackjackByStreams(int[] hands)
{
// set to an empty array; no winners in this hand
int[] winningSeats = new int[0];
// get the maximum that is <= 21
OptionalInt oi = Arrays.stream(hands).filter(tot -> tot <= 21).max();
// if there are any hands that are <= 21
if (oi.isPresent()) {
// have to make a list (?)
List<Integer> list = Arrays.stream(hands)
.boxed()
.collect(Collectors.toList());
// find the location(s) in the list
winningSeats = IntStream.range(0, list.size())
.filter(i -> list.get(i) == oi.getAsInt())
.toArray();
}
return winningSeats;
}
Run Code Online (Sandbox Code Playgroud)
这两种方法返回相同的数据,因此这不是功能本身的问题.相反,有没有办法让事情变得blackjackByStreams更好?特别是,有没有办法消除创造List<Integer> list?
编辑:我在这里读过这个问题,其中一个答案建议创建一个自定义收集器.不确定这是否是唯一的替代方法.
感谢您提供任何见解.
当您找到最大元素时,您就错过了简单的解决方案。只需直接在数组的索引上创建一个 Stream,而不是使用中间列表:
public static int[] blackjackByIteration(int[] hands) {
OptionalInt oi = Arrays.stream(hands).filter(i -> i <= 21).max();
if (oi.isPresent()) {
int value = oi.getAsInt();
return IntStream.range(0, hands.length).filter(i -> hands[i] == value).toArray();
}
return new int[0];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
507 次 |
| 最近记录: |