Skip to main content
Added note about trying it out.
Source Link
user1118321
  • 11.9k
  • 1
  • 20
  • 46

In fact, I went to the site and tried the above suggestions and passed the tests in the time allotted. For the sorting, I used the standard library qsort() function. I wrote my own binary search, and it seemed to do the trick.

In fact, I went to the site and tried the above suggestions and passed the tests in the time allotted. For the sorting, I used the standard library qsort() function. I wrote my own binary search, and it seemed to do the trick.

Source Link
user1118321
  • 11.9k
  • 1
  • 20
  • 46

One of the things that's terrible about these types of competitions is that the problems are very contrived. They're written like a math problem, which makes it tempting to write your solutions the same way. I'd do the following things to improve your code.

#Formatting The formatting of your code is very messy. Maybe it's just due to getting used to entering code in the Stack Exchange text field, but even if the tabs were correct, you're not using a lot of white space between statements. I recommend looking at other people's code to see how they use whitespace and adopting a style that you like. The book Code Complete has some useful rules of thumb to use for how to style C code. It's a good place to start from.

#Naming This is the number one thing that most developers could improve (myself included!). Just because the problem description names things like N, Q, and B[i] doesn't mean your code has to use those names. You should strive to use readable names like numEntries, numQueries, and queries.

Your function names aren't great either. check() doesn't tell me what it's doing. What is it checking? It turns out nothing. It's tabulating the number of times z occurs in arr and putting the result into c. It might be better to name it something like tabulateEntries() or something along those lines. Likewise, count() is counting something, right? What is it counting? The number of occurrences of z. So maybe it should be named countOccurences()?

#Be Careful With The Stack You're allocating everything on the stack. This can get you in trouble with longer programs. For example, your declaration of B is using either 400 or 800KB of stack space. The default stack size in many implementations is 1MB, so this would use almost 80% of the stack just in your main() function. It might be wiser to allocate that space on the heap or better yet, only allocate as much as you actually need (which will be q elements instead of 100,000). Same thing with arr.

#Avoid Magic Numbers You have several magic numbers in your code. These are numbers that are hard-coded to specific values. Someone reading your code would have no idea where they come from. You should use named constants or enumerations where appropriate. For example,

const int kMaxQueries = 1000;
const int kUnsetEntry = -1;
const int kInvalidEntry = 9999;

#Use structs Where Appropriate You're using a 2 dimensional array to represent the values and their counts. You should instead use a struct that holds those 2 values and have a 1-dimensional array of those structs. Something like this:

typedef struct ValueCounts {
    int value;
    int count;
} ValueCounts;

Then you can write self-documenting code like this:

int check(int z, ValueCounts counts, int q, int arr[])
{
    int i = 0;
    while (counts[i].value != kUnsetEntry)
    {
        if (z == counts [ i ].value)
        {
            return counts [ i ].count;
        }
        else
        {
            counts [ i ].value = z;
            counts [ i ].count = count(z, arr, q);
            return counts [ i ].count;
        }
        i++;
    }
}

#Errors Notice that your check() function can return an undefined value. If c[i][0] == -1, then the while loop ends, and the function will return whatever's on the stack, which is likely uninitialized memory. Is this why you made c[0][0] have an initial value of 9999? While that works around the problem, it's a bad way to do it.

#Performance Looking at your code, it seems to be doing things the long way. arr is an unsorted array. Tabulating how many occurrences there are of a single value in arr potentially involves looping over the entirety of c processed so far. This can happen for every value in arr. It would probably be faster to sort arr before counting the occurrences of each value. If it were already sorted, you'd be able to just run through arr in order, and as soon as the value changed, you'd fill in the next value in c with the total number of occurrences of the value before the change. That would leave c in order and would allow you to do a binary search of c for getting the values needed to print out the result. That should be considerably faster than the linear search you're currently doing.