@ti1

Java: Почему цикл while с вложенным в него циклом for и условием if работает некорректно?

Решаю задачку на очередь из произвольного числа покупателей у *n* касс в супермаркете, где очередь задается массивом целых чисел, каждое из которых означает время обслуживания соответствующего покупателя в кассе.

Возникла проблема в самом сложном случае, когда число касс больше одной (n > 1) и при этом число покупателей в очереди больше, чем число касс (customers.length > n).

import java.util.Arrays;
public class Solution {

    public static int solveSuperMarketQueue(int[] customers, int n) {
        int sum = 0;
        int[] nCustomers;
        int[] restOfCustomers;
        if (customers.length == 0) {
            return 0;
        } else if (customers.length == 1) {
            return customers[0];
        } else {
            if (n == 0) {
                return 0;
            } else if (n == 1) {
                sum = sumOfArray(customers);
            } else if (customers.length <= n) {
                int customerMax = customers[0];
                for (int i = 0; i < n; i++) {
                    if (customers[i] > customerMax) {
                        customerMax = customers[i];
                    }
                }
                return customerMax;
            } else {
                nCustomers = Arrays.copyOfRange(customers, 0, n);
                restOfCustomers = Arrays.copyOfRange(customers, n, customers.length);
                int serviceTime = 0;

                while (sumOfArray(nCustomers) > 0) {
                    for (int i = 0; i < nCustomers.length; i++) {
                        nCustomers[i]--;

                        if (nCustomers[i] == 0) {
                            nCustomers[i] = restOfCustomers[0];
                            restOfCustomers = Arrays.copyOfRange(restOfCustomers, 1, restOfCustomers.length);
                        }
                        serviceTime++;
                    }
                    return serviceTime;

                }

            }
        }
        return sum;
    }

    public static int sumOfArray(int ary[]) {
        int s = 0;
        for (int i = 0; i < ary.length; i++) {
            s += ary[i];
        }
        return s;
    }
}


А именно этот фрагмент:

} else {
  nCustomers = Arrays.copyOfRange(customers, 0, n);
  restOfCustomers = Arrays.copyOfRange(customers, n, customers.length);
  int serviceTime = 0;

  while (sumOfArray(nCustomers) > 0) {
    for (int i = 0; i < nCustomers.length; i++) {
      nCustomers[i]--;

    if (nCustomers[i] == 0) {
      nCustomers[i] = restOfCustomers[0];
      restOfCustomers = Arrays.copyOfRange(restOfCustomers, 1, restOfCustomers.length);
    }
    serviceTime++;
  }
  return serviceTime;

  }


Здесь я разбил массив покупателей из условия customers на два подмассива - nCustomers (это те первые n покупателей, что подошли к n кассам) и restOfCustomers (это оставшаяся очередь).

Мои рассуждения такие: пока у касс кто-то есть, мы запускаем счетчик времени на обслуживание serviceTime, уменьшая за каждую итерацию каждый элемент массива nCustomers на единицу.

После каждой итерации проверяем, не обнулился ли какой-нибудь элемент в этом массиве, и если обнулился, то ему присваиваем первый элемент из подмассива оставшейся очереди restOfCustomers, а сам этот подмассив укорачиваем на этот передаваемый в nCustomers элемент.

Подскажите - ошибся ли я в логике решения или логика правильная, а реализация в коде неправильная?
  • Вопрос задан
  • 202 просмотра
Пригласить эксперта
Ответы на вопрос 1
@forspamonly2
вы неправильно делаете неправильные вещи. то есть, и реализация слабая, и логика.

по реализации, например, зачем вообще копировать содержимое массива с очередью, когда можно просто хранить текущую позицию? это у вас только квадратичную вычислительную сложность добавило зазря.

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

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

при этом даже не потребуется обрабатывать отдельно случаи одной кассы или большего количества касс, чем людей, или пустой очереди нулевой длины - оно вполне корректно отработает.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы