Фильтрация строк 2d-массива по определенному значению

#java #arrays #loops #multidimensional-array #iteration

#java #массивы #циклы #многомерный-массив #итерация

Вопрос:

Я новичок в Java. Для моей задачи мне была предоставлена такая таблица. В таблице представлены 6 бегунов, которые участвовали в 7 гонках. Значение в каждой ячейке — это место, которое они получили в конкретной гонке:

Таблица

Задача моей программы — вывести количество бегунов, занявших 1-е место хотя бы в одной из гонок. Мне удалось написать код, который подсчитывает количество первых мест, достигнутых всеми бегунами, однако я изо всех сил пытаюсь найти решение, как добавить тех бегунов, которые финишировали 1-м несколько раз, к подсчету только один раз. Как мне перейти к следующей строке, когда соответствующее значение найдено и добавлено к счетчику? Вот мой код до сих пор:

 public class MyClass {
    public static void main(String[] args) {
        int A[][] = {{21, 14, 1, 21, 19, 5, 2},
                {4, 27, 1, 7, 25, 19, 19},
                {12, 20, 25, 11, 30, 14, 15},
                {5, 8, 5, 7, 1, 2, 13},
                {20, 2, 14, 4, 25, 1, 1},
                {14, 20, 20, 15, 11, 18, 16}};

        int i, j;
        int counter = 0;

        System.out.println("result:");
        for (i = 0; i < 6; i  ) {
            for (j = 0; j < 7; j  ) {
                if (A[i][j] == 1) {
                    counter  ;
                }
            }
        }
        System.out.print(counter);
    }
}
 

Ответ №1:

Чтобы отслеживать бегуна, который уже финишировал первым в гонке, вы можете иметь логический массив, подобный следующему

 boolean[] firstPlaceRunner = new boolean[A[0].length];
 

в i-й позиции приведенного выше логического массива хранится следующая информация:

  1. True — если i-й бегун занял 1-е место в любой из гонок.
  2. False — Если i-й бегун не смог занять 1-е место ни в одном из забегов.

Итак, теперь в вашем коде вы можете увеличивать счетчик только тогда, когда текущий участник еще не занял 1-е место. Итак, ваш код выглядит следующим образом:

 public static void main(String[] args) {
    int[][] A = {{21, 14, 1, 21, 19, 5, 2},
            {4, 27, 1, 7, 25, 19, 19},
            {12, 20, 25, 11, 30, 14, 15},
            {5, 8, 5, 7, 1, 2, 13},
            {20, 2, 14, 4, 25, 1, 1},
            {14, 20, 20, 15, 11, 18, 16}};
    int counter = 0;
    // A[0].length gives the number of runner in any race
    boolean[] firstPlaceRunner = new boolean[A[0].length];
    for (int i = 0; i < 6; i  ) {
        for (int j = 0; j < 7; j  ) {
            if (A[i][j] == 1) {
                if (!firstPlaceRunner[j]) {
                    counter  ;
                    // because now jth runner has secured first
                    // place, and in future we don't want to
                    firstPlaceRunner[j] = true;
                    // double count it
                }
            }
        }
    }
    System.out.println("result:");
    System.out.print(counter);
}
 

Примечание: В качестве улучшения нашего алгоритма вы можете поместить break оператор после следующей строки в коде, поскольку может быть только один победитель, занявший 1-е место:

 firstPlaceRunner[j] = true;
break;
 

Итак, по сути, вы говорите, что если мы нашли бегуна, занявшего первое место в данной гонке, то не проверяйте наличие других бегунов.

Ответ №2:

Вы можете выполнить итерацию по индексам range строк этой матрицы и filter вывести те строки, которые содержат anyMatch 1 :

 int[][] runners = {
        {21, 14, 1, 21, 19, 5, 2},
        {4, 27, 1, 7, 25, 19, 19},
        {12, 20, 25, 11, 30, 14, 15},
        {5, 8, 5, 7, 1, 2, 13},
        {20, 2, 14, 4, 25, 1, 1},
        {14, 20, 20, 15, 11, 18, 16}};

int[] winners = IntStream
        // iterate over indices of
        // the rows of 2d array
        .range(0, runners.length)
        // filer rows where at least
        // one element matches '1'
        .filter(i -> Arrays.stream(runners[i])
                .anyMatch(j -> j == 1))
        // array of indices
        .toArray();

System.out.println(Arrays.toString(winners)); // [0, 1, 3, 4]
 

Ответ №3:

Добавьте разрыв в оператор if:

 public class MyClass {
    public static void main(String[] args) {
        int A[][] = {{21, 14, 1, 21, 19, 5, 2},
                {4, 27, 1, 7, 25, 19, 19},
                {12, 20, 25, 11, 30, 14, 15},
                {5, 8, 5, 7, 1, 2, 13},
                {20, 2, 14, 4, 25, 1, 1},
                {14, 20, 20, 15, 11, 18, 16}};

        int i, j;
        int counter = 0;

        System.out.println("result:");
        for (i = 0; i < 6; i  ) {
            for (j = 0; j < 7; j  ) {
                if (A[i][j] == 1) {
                    counter  ;
                    break;
                }
            }
        }
        System.out.print(counter);
    }
}