2
\$\begingroup\$

Question is here:

Input

The first line contains an integer \$N\$, which is the quantity of numbers written down by Vasya (\$1 \le N \le 1000\$). The second line contains these numbers separated by spaces. All the numbers are positive integers not greater than 10.

Output

Output the numbers Petya would write down separated by space.

For instance, the sequence "1 1 2 3 3 3 10 10" will be told by Vasya as "two ones, one two, three threes, two tens". Petya also wants to be concise, so he writes down the numbers pronounced by Vasya instead of the whole words. For the example above, Petya would write: "2 1 1 2 3 3 2 10".

public class TestClass {

    static String firstLine = "8";
    static String secondLine = "1 1 2 3 3 3 10 10";


    public static void main(String[] args) {
        int countOfIntegersToBeProcessed = Integer.parseInt(firstLine);
        String[] integersAsStringArray = secondLine.split(" ");
        int localCounterForASpecificInteger = 1;
        for (int integersToBeProcessedCounter = 0; integersToBeProcessedCounter < countOfIntegersToBeProcessed; integersToBeProcessedCounter++) {
            String integerBeingProcessed = integersAsStringArray[integersToBeProcessedCounter];
            if (integersToBeProcessedCounter == countOfIntegersToBeProcessed - 1) {
                System.out.print(localCounterForASpecificInteger + " " + integerBeingProcessed);
                return;
            }
            if (integerBeingProcessed.equals(integersAsStringArray[integersToBeProcessedCounter + 1])) {
                localCounterForASpecificInteger++;
            } else {
                System.out.print(localCounterForASpecificInteger + " " + integerBeingProcessed + " ");
                localCounterForASpecificInteger = 1;
            }
        }
    }

}

And the output will be:

2 1 1 2 3 3 2 10

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Ow, my eyes. Your variable names all look so long and similar. I can't even see all of the code at once without line wrapping. I'd rather read for (int i = 0; i < n; i++) than

for (int integersToBeProcessedCounter = 0; integersToBeProcessedCounter < countOfIntegersToBeProcessed; integersToBeProcessedCounter++) {

In cases like this, short variable names are fine, because it is an established convention that i is an array index, and n is the array size.

Furthermore, the verbose naming isn't really that accurate anyway. integerBeingProcessed isn't really an integer, but a string.

A further improvement in naming would come from breaking out the array analysis into a separate function, so that main() is just responsible for parsing the input. Then, integersAsStringArray and countOfIntegersToBeProcessed can become seq and seq.length, respectively.

Just applying some renaming and other minor transformations…

public class TestClass {

    static String firstLine = "8";
    static String secondLine = "1 1 2 3 3 3 10 10";

    public static void summarize(String[] seq) {
        int groupSize = 1;
        for (int i = 0; i < seq.length; i++) {
            if (i == seq.length - 1) {
                System.out.println(groupSize + " " + seq[i]);
            } else if (seq[i].equals(seq[i + 1])) {
                groupSize++;
            } else {
                System.out.print(groupSize + " " + seq[i] + " ");
                groupSize = 1;
            }
        }
    }

    public static void main(String[] args) {
        int arrayLen = Integer.parseInt(firstLine);
        String[] array = secondLine.split(" ");
        if (arrayLen != array.length) {   // Optional validation
            throw new IllegalArgumentException("Expected " + arrayLen + " numbers, got " + array.length);
        }
        summarize(array);
    }
}

I also propose the following algorithm, which does not need as much of a special case for handling the last element.

    public static void summarize(String[] seq) {
        int groupStart, groupEnd;
        for (groupStart = 0; groupStart < seq.length; groupStart = groupEnd) {
            String leader = seq[groupStart];
            for (groupEnd = groupStart + 1; groupEnd < seq.length && seq[groupEnd].equals(leader); groupEnd++);
            System.out.print((groupEnd - groupStart) + " " + leader +
                             (groupEnd < seq.length - 1 ? " " : "\n"));
        }
    }
\$\endgroup\$
1
  • \$\begingroup\$ Thanks. I sensed something was wrong with the variable names. :) \$\endgroup\$ Jun 3, 2015 at 9:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.