T
T
ti12018-07-31 19:15:59
Java
ti1, 2018-07-31 19:15:59

Java: Why doesn't a while loop with a nested for loop and an if condition work correctly?

I am solving a problem for a queue of an arbitrary number of customers at *n* checkouts in a supermarket, where the queue is given by an array of integers, each of which means the service time of the corresponding customer at the checkout.
There was a problem in the most difficult case, when the number of cash desks is more than one (n > 1) and the number of customers in the queue is greater than the number of cash desks (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;
    }
}

Namely this snippet:
} 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;

  }

Here I split the array of customers from the customers condition into two sub-arrays - nCustomers (these are the first n customers who came to n cash registers) and restOfCustomers (this is the remaining queue).
My reasoning is as follows: while there is someone at the checkout, we start the serviceTime service time counter, decrementing each element of the nCustomers array by one for each iteration.
After each iteration, we check if any element in this array is zeroed, and if it is zeroed, then we assign the first element from the subarray of the remaining restOfCustomers queue to it, and we shorten this subarray by this element passed to nCustomers.
Tell me - did I make a mistake in the logic of the solution or is the logic correct, but the implementation in the code is wrong?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
F
forspamonly2, 2018-08-03
@forspamonly2

you are doing the wrong things. that is, both the implementation is weak, and the logic.
by implementation, for example, why copy the contents of an array with a queue at all, when you can just store the current position? it only added quadratic computational complexity in vain.
and logically, you don’t need to make a step-by-step queue simulator, but distribute people among the cash desks and choose the busiest one.
you can distribute it in one pass in turn: you have a list of cash desks with the current time of release of each cash desk (initially zero), for each person you select the fastest cash desk (which has the minimum time value in the list) and add to it the time of its service. then just choose the largest total time from all cash desks.
it does not even need to handle separately the cases of one cash desk or more cash desks than people, or an empty zero-length queue - it will work quite correctly.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question