This code is a improved version of implementation which asked for a review: Product of all but one number in a sequence.
#include <stdio.h>
#include <stdlib.h>
//without division, with O(n) time, but extra space complexity as suggested
//return new array on the heap
int *derive_products(const int *nums, int count)
{
int *retval = malloc(count * sizeof *retval);
if (!retval && count)
return 0;
int mult=1; //product of prefix or suffix elements
//swipe up
for(int i=0; i<count; i++) {
retval[i] = mult;
mult *= nums[i];
}
//swipe down
for(int j=count-1, mult=1; j>=0; j--) {
retval[j] *= mult;
mult *= nums[j];
}
return retval;
}
int main()
{
/*Given an array of integers, return a new array such that each element at index i of the
new array is the product of all the numbers in the original array except the one at i.
For example, if our input was [1, 2, 3, 4, 5], the expected output would be
[120, 60, 40, 30, 24] */
int nums[] = {1, 2, 2, 4, 6};
int size = sizeof(nums)/sizeof(nums[0]);
int *products = derive_products(nums, size); //get a new array
for (int i = 0; i < size; i++)
printf("%d ", products[i] );
free(products); //release heap memory
}
-
\$\begingroup\$ Rather than "/return new array on the heap ", get right to the point as C does not define "heap". Instead. "// Returns allocated array"/ \$\endgroup\$chux– chux2020年11月14日 03:48:00 +00:00Commented Nov 14, 2020 at 3:48
-
\$\begingroup\$ Why does code describe the output of a commented test case and then code uses a test with another set of data? I'd expect the true test case to have a commented expectation - or a run-time check. \$\endgroup\$chux– chux2020年11月14日 03:51:15 +00:00Commented Nov 14, 2020 at 3:51
-
\$\begingroup\$ @chux-ReinstateMonica I declared random int array since I only focus on product generator function. But I got the point thanks. \$\endgroup\$Erdenebat Ulziisaikhan– Erdenebat Ulziisaikhan2020年11月14日 05:58:21 +00:00Commented Nov 14, 2020 at 5:58
1 Answer 1
Proper scoping
int mult=1; //product of prefix or suffix elements
mult
above is only used in the first loop. The one used in the second loop is defined there, and limited to that loop. This one should be the same.
Proper naming
j
in the second loop is an unexpected name. As it is an outer loop, you should usei
(again).
int size = sizeof(nums)/sizeof(nums[0]);
- While
size
isn't really wrong, I would expect a different unit of measurement (namely bytes, as forsizeof
, instead of elements) considering the name. I suggest going forcount
.
Check for failure
int *products = derive_products(nums, size); //get a new array
- The above can fail, in which case it returns null. Don't just assume success.
Comments
//without division, with O(n) time, but extra space complexity as suggested
//return new array on the heap
Comments should be to the point, omit the obvious, and describe the motivation.
The above could be:
// without division in O(n) time // free(result)
Yes, writing down the task as a comment is a good idea. But if you have test-data, just write a test.
Your comment after a line of code are pretty superfluous. Are you forced to sprinkle more comments?
See Guessing a number, but comments concerning
Whitespace
- Your use of whitespace is inconsistent. Do you surround binary operators with single whitespace?
Sometimes you do, sometimes you don't. Imho, doing so looks better, so standardise on that. There are plenty automatic code formatters, so you don't even have to do the hard work yourself.
-
\$\begingroup\$ Good point about scoping. It took a while to see that
mult
declaration inint j=count-1, mult=1;
.for
body certainty looks like it is using the prior code'smult
. \$\endgroup\$chux– chux2020年11月14日 03:44:26 +00:00Commented Nov 14, 2020 at 3:44