删除列表中的第一个索引,直到它为空

Deleting first index in list until it's empty

提问人:patdybalski 提问时间:10/14/2023 最后编辑:patdybalski 更新时间:10/14/2023 访问量:71

问:

firstPlayer 和 secondPlayer 交替从列表的第一个索引中获取分数。

firstPlayer 获取索引 0,然后删除该值。如果该值为偶数,则其余列表将反转。

然后,secondPlayer 做同样的事情。但是不知何故,这部分出现了错误。

每当每个玩家获得一个值时,它都是串联的。

最后,计算第一和第二玩家的差额。

这是我得到的:enter image description here

import java.util.*;

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        
        list.add(4);
        list.add(2);
        list.add(1);
        list.add(4);
        list.add(3);
        
        int firstScore = 0;
        int secondScore = 0;
        
        int i = 0;
        
        int firstPlayer = 0;
        int secondPlayer = 0;
        
        while (!list.isEmpty()) {
            System.out.println(list);
            firstScore = list.get(i);
            list.remove(i);

            System.out.println(firstScore);
            
            if (firstScore % 2 == 0) {
                Collections.reverse(list);
            }
            
            firstPlayer = firstScore + firstPlayer;
            
            System.out.println(list);
            secondScore = list.get(i);    //this line gets an error but if there's no while loop, it works fine  
            list.remove(i);

            System.out.println(secondScore);
            
            if (secondScore % 2 == 0) {
                Collections.reverse(list);
            }
            
            secondPlayer = secondScore + secondPlayer;
        }
        
        System.out.println(firstPlayer - secondPlayer);
    }
}

爪哇岛 列表

评论

0赞 Tim Roberts 10/14/2023
你有问题吗?

答:

1赞 Sky64Redstone 10/14/2023 #1

所以,问题是,你的列表只有 5 个数字长,你只在第一个玩家回合之前进行空检查。

在 while 循环的最后一次运行中,第一个玩家得到最后一个号码,没有检查,第二个玩家要求他的号码,但现在列表是空的......

要解决这个问题,你必须在第二个玩家得到他的号码之前放一个空支票:

System.out.println(list);
if (list.isEmpty()) {
    break; // if the list is now empty break the loop
}
secondScore = list.get(i); // if the list was empty we can now be sure that the code interpret won't reach this here
1赞 Aswin Prasad 10/14/2023 #2

我找到了一个解决方案,

import java.util.*;

public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    
    list.add(4);
    list.add(2);
    list.add(1);
    list.add(4);
    list.add(3);
    /*
    list.add(6);
    
    if there are even no. of list items present then the loop get 
    finished before getting error, because having even values and each loop deletes 2 value is proportional.
    
    */
    
    int firstScore = 0;
    int secondScore = 0;
    
    int i = 0;
    
    int firstPlayer = 0;
    int secondPlayer = 0;
    
    while (!list.isEmpty()) {
        System.out.println(list);
        firstScore = list.get(i);
        list.remove(i);

        System.out.println(firstScore);
        
        if (firstScore % 2 == 0) {
            Collections.reverse(list);
        }
        
        firstPlayer = firstScore + firstPlayer;
        
        if(!list.isEmpty()) {   //your code gets error because, try to access value in an empty list.
            System.out.println(list);
            secondScore = list.get(i);
            list.remove(i);

            System.out.println(secondScore);
            
            if (secondScore % 2 == 0) {
                Collections.reverse(list);
            }
            
            secondPlayer = secondScore + secondPlayer;
        }
    }
    
    System.out.println(firstPlayer - secondPlayer);
}

从上面的代码中,需要检查为第二个玩家添加的 if 条件,因为如果列表包含奇数个值,那么第一个玩家删除的最后一个元素,然后第二个玩家无法访问任何值。

谢谢。。

1赞 Rob Spoor 10/14/2023 #3

在 Java 21 及更高版本中,您可以使用继承自 以下方法轻松完成此操作:SequencedCollection

List<Integer> list = new ArrayList<>();

list.add(4);
list.add(2);
list.add(1);
list.add(4);
list.add(3);

int firstScore = 0;
int secondScore = 0;

int firstPlayer = 0;
int secondPlayer = 0;

while (!list.isEmpty()) {
    System.out.println(list);
    firstScore = list.removeFirst();

    System.out.println(firstScore);

    if (firstScore % 2 == 0) {
        list = list.reversed();
    }

    firstPlayer = firstScore + firstPlayer;

    if (!list.isEmpty()) {
        System.out.println(list);
        secondScore = list.removeFirst();

        System.out.println(secondScore);

        if (secondScore % 2 == 0) {
            list = list.reversed();
        }

        secondPlayer = secondScore + secondPlayer;
    }
}

System.out.println(firstPlayer - secondPlayer);

请注意,我必须在循环中包含第二个空检查,正如其他几个人所观察到的那样。

1赞 Abra 10/14/2023 #4

通常最好在循环中只处理集合的一个元素。在代码的 [] 循环中,您正在处理两个元素——这是问题的原因,如其他答案中所述。while

在下面的代码中,[] 循环处理单个元素并使用“标志”(即布尔变量)来确定轮到谁了。while

请注意,下面的代码至少需要 Java 21,因为它使用序列集合,这些集合最初是在 JDK 21 中添加的。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Players2 {

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(List.of(4, 2, 1, 4, 3));
        int score1 = 0;
        int score2 = 0;
        System.out.println("list: " + list);
        System.out.println("score1 = " + score1);
        System.out.println("score2 = " + score2);
        boolean player1 = true;
        while (!list.isEmpty()) {
            int score = list.removeFirst();
            if (player1) {
                player1 = false;
                score1 += score;
            }
            else {
                player1 = true;
                score2 += score;
            }
            if (score % 2 == 0) {
                Collections.reverse(list);
            }
            System.out.println("list: " + list);
            System.out.println("score1 = " + score1);
            System.out.println("score2 = " + score2);
        }
    }
}

这是我运行上述代码时的输出:

list: [4, 2, 1, 4, 3]
score1 = 0
score2 = 0
list: [3, 4, 1, 2]
score1 = 4
score2 = 0
list: [4, 1, 2]
score1 = 4
score2 = 3
list: [2, 1]
score1 = 8
score2 = 3
list: [1]
score1 = 8
score2 = 5
list: []
score1 = 9
score2 = 5