Pair-wise difference using recursion
I was asked to translate this pseudo code into a C program:
rep := 0
while A not empty:
B :=
for x in A, y in A:
if x != y: append absolute_value(x - y) to B
A := B
rep := rep + 1
and I end up with this:
int iterateIt(int a_count, int* a) {
unsigned long long i, j, k;
unsigned long long count = a_count;
for( i = 1 ; i < a_count ; i++ )
count *= count-1;
int *b = (int *) malloc(count * sizeof(int));
count = 0;
k = 0;
for( i = 0 ; i < a_count ; i++ ){
for( j = i ; j < a_count ; j++ ){
if(a[i] != a[j]){
b[k] = abs(a[i] - a[j]);
k++;
}
}
}
if( k > 0){
return 1 + iterateIt(k, b);
}
free(b);
return 1;
}
I used recursion to return the number of iteration of the algorithm. Practically I take the difference between any two different objects of A and put the absolute value in B, on which I recur.
For simple input I get the correct result but I don't understand why for input like:
16
1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768
or 4
1 352 9483 50000
(the first number is the number of element of A)
I get a segmentation fault error.
Thank you for your help
c arrays recursion segmentation-fault
add a comment |
I was asked to translate this pseudo code into a C program:
rep := 0
while A not empty:
B :=
for x in A, y in A:
if x != y: append absolute_value(x - y) to B
A := B
rep := rep + 1
and I end up with this:
int iterateIt(int a_count, int* a) {
unsigned long long i, j, k;
unsigned long long count = a_count;
for( i = 1 ; i < a_count ; i++ )
count *= count-1;
int *b = (int *) malloc(count * sizeof(int));
count = 0;
k = 0;
for( i = 0 ; i < a_count ; i++ ){
for( j = i ; j < a_count ; j++ ){
if(a[i] != a[j]){
b[k] = abs(a[i] - a[j]);
k++;
}
}
}
if( k > 0){
return 1 + iterateIt(k, b);
}
free(b);
return 1;
}
I used recursion to return the number of iteration of the algorithm. Practically I take the difference between any two different objects of A and put the absolute value in B, on which I recur.
For simple input I get the correct result but I don't understand why for input like:
16
1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768
or 4
1 352 9483 50000
(the first number is the number of element of A)
I get a segmentation fault error.
Thank you for your help
c arrays recursion segmentation-fault
1
Why do you putcount *= count-1;
in a loop? What does it compute?
– n.m.
Nov 21 '18 at 17:02
You do not test the return value ofmalloc()
. My guess would be that you are computing a huge or even negative (because overflow) value incount
,malloc()
is therefore failing, and you are then attempting to write through the resulting null pointer.
– John Bollinger
Nov 21 '18 at 17:04
Do you use an IDE? Does it have a debugger? Do you know how to use it? It is your best friend and will easilly let you resolve problems like this without having to ask us
– Mawg
Nov 21 '18 at 21:02
add a comment |
I was asked to translate this pseudo code into a C program:
rep := 0
while A not empty:
B :=
for x in A, y in A:
if x != y: append absolute_value(x - y) to B
A := B
rep := rep + 1
and I end up with this:
int iterateIt(int a_count, int* a) {
unsigned long long i, j, k;
unsigned long long count = a_count;
for( i = 1 ; i < a_count ; i++ )
count *= count-1;
int *b = (int *) malloc(count * sizeof(int));
count = 0;
k = 0;
for( i = 0 ; i < a_count ; i++ ){
for( j = i ; j < a_count ; j++ ){
if(a[i] != a[j]){
b[k] = abs(a[i] - a[j]);
k++;
}
}
}
if( k > 0){
return 1 + iterateIt(k, b);
}
free(b);
return 1;
}
I used recursion to return the number of iteration of the algorithm. Practically I take the difference between any two different objects of A and put the absolute value in B, on which I recur.
For simple input I get the correct result but I don't understand why for input like:
16
1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768
or 4
1 352 9483 50000
(the first number is the number of element of A)
I get a segmentation fault error.
Thank you for your help
c arrays recursion segmentation-fault
I was asked to translate this pseudo code into a C program:
rep := 0
while A not empty:
B :=
for x in A, y in A:
if x != y: append absolute_value(x - y) to B
A := B
rep := rep + 1
and I end up with this:
int iterateIt(int a_count, int* a) {
unsigned long long i, j, k;
unsigned long long count = a_count;
for( i = 1 ; i < a_count ; i++ )
count *= count-1;
int *b = (int *) malloc(count * sizeof(int));
count = 0;
k = 0;
for( i = 0 ; i < a_count ; i++ ){
for( j = i ; j < a_count ; j++ ){
if(a[i] != a[j]){
b[k] = abs(a[i] - a[j]);
k++;
}
}
}
if( k > 0){
return 1 + iterateIt(k, b);
}
free(b);
return 1;
}
I used recursion to return the number of iteration of the algorithm. Practically I take the difference between any two different objects of A and put the absolute value in B, on which I recur.
For simple input I get the correct result but I don't understand why for input like:
16
1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768
or 4
1 352 9483 50000
(the first number is the number of element of A)
I get a segmentation fault error.
Thank you for your help
c arrays recursion segmentation-fault
c arrays recursion segmentation-fault
asked Nov 21 '18 at 16:52
Andrea FoderaroAndrea Foderaro
36
36
1
Why do you putcount *= count-1;
in a loop? What does it compute?
– n.m.
Nov 21 '18 at 17:02
You do not test the return value ofmalloc()
. My guess would be that you are computing a huge or even negative (because overflow) value incount
,malloc()
is therefore failing, and you are then attempting to write through the resulting null pointer.
– John Bollinger
Nov 21 '18 at 17:04
Do you use an IDE? Does it have a debugger? Do you know how to use it? It is your best friend and will easilly let you resolve problems like this without having to ask us
– Mawg
Nov 21 '18 at 21:02
add a comment |
1
Why do you putcount *= count-1;
in a loop? What does it compute?
– n.m.
Nov 21 '18 at 17:02
You do not test the return value ofmalloc()
. My guess would be that you are computing a huge or even negative (because overflow) value incount
,malloc()
is therefore failing, and you are then attempting to write through the resulting null pointer.
– John Bollinger
Nov 21 '18 at 17:04
Do you use an IDE? Does it have a debugger? Do you know how to use it? It is your best friend and will easilly let you resolve problems like this without having to ask us
– Mawg
Nov 21 '18 at 21:02
1
1
Why do you put
count *= count-1;
in a loop? What does it compute?– n.m.
Nov 21 '18 at 17:02
Why do you put
count *= count-1;
in a loop? What does it compute?– n.m.
Nov 21 '18 at 17:02
You do not test the return value of
malloc()
. My guess would be that you are computing a huge or even negative (because overflow) value in count
, malloc()
is therefore failing, and you are then attempting to write through the resulting null pointer.– John Bollinger
Nov 21 '18 at 17:04
You do not test the return value of
malloc()
. My guess would be that you are computing a huge or even negative (because overflow) value in count
, malloc()
is therefore failing, and you are then attempting to write through the resulting null pointer.– John Bollinger
Nov 21 '18 at 17:04
Do you use an IDE? Does it have a debugger? Do you know how to use it? It is your best friend and will easilly let you resolve problems like this without having to ask us
– Mawg
Nov 21 '18 at 21:02
Do you use an IDE? Does it have a debugger? Do you know how to use it? It is your best friend and will easilly let you resolve problems like this without having to ask us
– Mawg
Nov 21 '18 at 21:02
add a comment |
2 Answers
2
active
oldest
votes
I think your count
is wrong. Your second iteration is already humongous.
#include <stdio.h>
#include <stdlib.h>
size_t total_allocated = 0;
int iterateIt(int a_count, int* a) {
unsigned long long i, j, k;
unsigned long long count = a_count;
for( i = 1 ; i < a_count ; i++ )
count *= count-1;
size_t size = count * sizeof(int);
printf("Allocating %llu ints: %llu bytesn", count, (unsigned long long)size);
total_allocated += size;
printf("Total allocated: %llu bytesn", (unsigned long long)total_allocated);
int *b = (int *) malloc(count * sizeof(int));
count = 0;
k = 0;
for( i = 0 ; i < a_count ; i++ ){
for( j = i ; j < a_count ; j++ ){
if(a[i] != a[j]){
b[k] = abs(a[i] - a[j]);
k++;
}
}
}
if( k > 0){
return 1 + iterateIt(k, b);
}
free(b);
return 1;
}
int main (void)
{
iterateIt(4, (int[4]){1,352,9483,50000});
return 0;
}
Result:
Allocating 17292 ints: 69168 bytes
Total allocated: 69168 bytes
Allocating 12550317587327992670 ints: 13307782201892867448 bytes
Total allocated: 13307782201892936616 bytes
add a comment |
First consider this line:
return 1 + iterateIt(k, b);
The b
array never gets freed on this return
but if k
is zero, it does. Let's rewrite this code to clean it up a bit:
#include <stdio.h>
#include <stdlib.h>
unsigned iterateIt(size_t a_count, int *a) {
unsigned rep = 1;
int *b = calloc(a_count * a_count, sizeof(int));
size_t k = 0;
for (size_t i = 0; i < a_count; i++) {
for (size_t j = i + 1; j < a_count; j++) {
if (a[i] != a[j]) {
b[k++] = abs(a[i] - a[j]);
}
}
}
if (k > 0) {
rep += iterateIt(k, b);
}
free(b);
return rep;
}
int main() {
int x = {1, 324, 54};
printf("%un", iterateIt(sizeof(x) / sizeof(int), x));
return 0;
}
Watching the value of a_count
, the program tries to allocate too much memory and fails.
UPDATE
Since the two halves of the matrix end up identical, I fixed the above code to do what the OP did, just process 1/2 the matrix, i.e. j
starts at i + 1
since the two halves end up identical. I also ignore the diagonal as it's always zeros. Then the code completes for the three numbers in my example code but blows up again when I increase the array to four values.
I believe the recursive nature of the OP's solution is elegant and a non-issue but just to confirm, here's an iterative solution that fails to perform and not due to lack of stack memory:
unsigned iterateIt(size_t a_count, int *a) {
unsigned rep = 1;
bool first_time = true;
while (true) {
int *b = calloc((a_count * a_count) / 2, sizeof(int));
if (b == NULL) {
perror("calloc failed!");
exit(1);
}
size_t b_count = 0;
for (size_t i = 0; i < a_count; i++) {
for (size_t j = i + 1; j < a_count; j++) {
if (a[i] != a[j]) {
b[b_count ++] = abs(a[i] - a[j]);
}
}
}
if (b_count == 0) {
free(b);
break;
}
if (first_time) {
first_time = false;
} else {
free(a);
}
a = b;
a_count = b_count;
rep++;
}
return rep;
}
The convergence is definitely there: at each round the maximal value decreases. I don't see a reason for a recursive approach though.
– user58697
Nov 21 '18 at 19:07
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53416987%2fpair-wise-difference-using-recursion%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I think your count
is wrong. Your second iteration is already humongous.
#include <stdio.h>
#include <stdlib.h>
size_t total_allocated = 0;
int iterateIt(int a_count, int* a) {
unsigned long long i, j, k;
unsigned long long count = a_count;
for( i = 1 ; i < a_count ; i++ )
count *= count-1;
size_t size = count * sizeof(int);
printf("Allocating %llu ints: %llu bytesn", count, (unsigned long long)size);
total_allocated += size;
printf("Total allocated: %llu bytesn", (unsigned long long)total_allocated);
int *b = (int *) malloc(count * sizeof(int));
count = 0;
k = 0;
for( i = 0 ; i < a_count ; i++ ){
for( j = i ; j < a_count ; j++ ){
if(a[i] != a[j]){
b[k] = abs(a[i] - a[j]);
k++;
}
}
}
if( k > 0){
return 1 + iterateIt(k, b);
}
free(b);
return 1;
}
int main (void)
{
iterateIt(4, (int[4]){1,352,9483,50000});
return 0;
}
Result:
Allocating 17292 ints: 69168 bytes
Total allocated: 69168 bytes
Allocating 12550317587327992670 ints: 13307782201892867448 bytes
Total allocated: 13307782201892936616 bytes
add a comment |
I think your count
is wrong. Your second iteration is already humongous.
#include <stdio.h>
#include <stdlib.h>
size_t total_allocated = 0;
int iterateIt(int a_count, int* a) {
unsigned long long i, j, k;
unsigned long long count = a_count;
for( i = 1 ; i < a_count ; i++ )
count *= count-1;
size_t size = count * sizeof(int);
printf("Allocating %llu ints: %llu bytesn", count, (unsigned long long)size);
total_allocated += size;
printf("Total allocated: %llu bytesn", (unsigned long long)total_allocated);
int *b = (int *) malloc(count * sizeof(int));
count = 0;
k = 0;
for( i = 0 ; i < a_count ; i++ ){
for( j = i ; j < a_count ; j++ ){
if(a[i] != a[j]){
b[k] = abs(a[i] - a[j]);
k++;
}
}
}
if( k > 0){
return 1 + iterateIt(k, b);
}
free(b);
return 1;
}
int main (void)
{
iterateIt(4, (int[4]){1,352,9483,50000});
return 0;
}
Result:
Allocating 17292 ints: 69168 bytes
Total allocated: 69168 bytes
Allocating 12550317587327992670 ints: 13307782201892867448 bytes
Total allocated: 13307782201892936616 bytes
add a comment |
I think your count
is wrong. Your second iteration is already humongous.
#include <stdio.h>
#include <stdlib.h>
size_t total_allocated = 0;
int iterateIt(int a_count, int* a) {
unsigned long long i, j, k;
unsigned long long count = a_count;
for( i = 1 ; i < a_count ; i++ )
count *= count-1;
size_t size = count * sizeof(int);
printf("Allocating %llu ints: %llu bytesn", count, (unsigned long long)size);
total_allocated += size;
printf("Total allocated: %llu bytesn", (unsigned long long)total_allocated);
int *b = (int *) malloc(count * sizeof(int));
count = 0;
k = 0;
for( i = 0 ; i < a_count ; i++ ){
for( j = i ; j < a_count ; j++ ){
if(a[i] != a[j]){
b[k] = abs(a[i] - a[j]);
k++;
}
}
}
if( k > 0){
return 1 + iterateIt(k, b);
}
free(b);
return 1;
}
int main (void)
{
iterateIt(4, (int[4]){1,352,9483,50000});
return 0;
}
Result:
Allocating 17292 ints: 69168 bytes
Total allocated: 69168 bytes
Allocating 12550317587327992670 ints: 13307782201892867448 bytes
Total allocated: 13307782201892936616 bytes
I think your count
is wrong. Your second iteration is already humongous.
#include <stdio.h>
#include <stdlib.h>
size_t total_allocated = 0;
int iterateIt(int a_count, int* a) {
unsigned long long i, j, k;
unsigned long long count = a_count;
for( i = 1 ; i < a_count ; i++ )
count *= count-1;
size_t size = count * sizeof(int);
printf("Allocating %llu ints: %llu bytesn", count, (unsigned long long)size);
total_allocated += size;
printf("Total allocated: %llu bytesn", (unsigned long long)total_allocated);
int *b = (int *) malloc(count * sizeof(int));
count = 0;
k = 0;
for( i = 0 ; i < a_count ; i++ ){
for( j = i ; j < a_count ; j++ ){
if(a[i] != a[j]){
b[k] = abs(a[i] - a[j]);
k++;
}
}
}
if( k > 0){
return 1 + iterateIt(k, b);
}
free(b);
return 1;
}
int main (void)
{
iterateIt(4, (int[4]){1,352,9483,50000});
return 0;
}
Result:
Allocating 17292 ints: 69168 bytes
Total allocated: 69168 bytes
Allocating 12550317587327992670 ints: 13307782201892867448 bytes
Total allocated: 13307782201892936616 bytes
answered Nov 21 '18 at 17:12
contrapantscontrapants
590214
590214
add a comment |
add a comment |
First consider this line:
return 1 + iterateIt(k, b);
The b
array never gets freed on this return
but if k
is zero, it does. Let's rewrite this code to clean it up a bit:
#include <stdio.h>
#include <stdlib.h>
unsigned iterateIt(size_t a_count, int *a) {
unsigned rep = 1;
int *b = calloc(a_count * a_count, sizeof(int));
size_t k = 0;
for (size_t i = 0; i < a_count; i++) {
for (size_t j = i + 1; j < a_count; j++) {
if (a[i] != a[j]) {
b[k++] = abs(a[i] - a[j]);
}
}
}
if (k > 0) {
rep += iterateIt(k, b);
}
free(b);
return rep;
}
int main() {
int x = {1, 324, 54};
printf("%un", iterateIt(sizeof(x) / sizeof(int), x));
return 0;
}
Watching the value of a_count
, the program tries to allocate too much memory and fails.
UPDATE
Since the two halves of the matrix end up identical, I fixed the above code to do what the OP did, just process 1/2 the matrix, i.e. j
starts at i + 1
since the two halves end up identical. I also ignore the diagonal as it's always zeros. Then the code completes for the three numbers in my example code but blows up again when I increase the array to four values.
I believe the recursive nature of the OP's solution is elegant and a non-issue but just to confirm, here's an iterative solution that fails to perform and not due to lack of stack memory:
unsigned iterateIt(size_t a_count, int *a) {
unsigned rep = 1;
bool first_time = true;
while (true) {
int *b = calloc((a_count * a_count) / 2, sizeof(int));
if (b == NULL) {
perror("calloc failed!");
exit(1);
}
size_t b_count = 0;
for (size_t i = 0; i < a_count; i++) {
for (size_t j = i + 1; j < a_count; j++) {
if (a[i] != a[j]) {
b[b_count ++] = abs(a[i] - a[j]);
}
}
}
if (b_count == 0) {
free(b);
break;
}
if (first_time) {
first_time = false;
} else {
free(a);
}
a = b;
a_count = b_count;
rep++;
}
return rep;
}
The convergence is definitely there: at each round the maximal value decreases. I don't see a reason for a recursive approach though.
– user58697
Nov 21 '18 at 19:07
add a comment |
First consider this line:
return 1 + iterateIt(k, b);
The b
array never gets freed on this return
but if k
is zero, it does. Let's rewrite this code to clean it up a bit:
#include <stdio.h>
#include <stdlib.h>
unsigned iterateIt(size_t a_count, int *a) {
unsigned rep = 1;
int *b = calloc(a_count * a_count, sizeof(int));
size_t k = 0;
for (size_t i = 0; i < a_count; i++) {
for (size_t j = i + 1; j < a_count; j++) {
if (a[i] != a[j]) {
b[k++] = abs(a[i] - a[j]);
}
}
}
if (k > 0) {
rep += iterateIt(k, b);
}
free(b);
return rep;
}
int main() {
int x = {1, 324, 54};
printf("%un", iterateIt(sizeof(x) / sizeof(int), x));
return 0;
}
Watching the value of a_count
, the program tries to allocate too much memory and fails.
UPDATE
Since the two halves of the matrix end up identical, I fixed the above code to do what the OP did, just process 1/2 the matrix, i.e. j
starts at i + 1
since the two halves end up identical. I also ignore the diagonal as it's always zeros. Then the code completes for the three numbers in my example code but blows up again when I increase the array to four values.
I believe the recursive nature of the OP's solution is elegant and a non-issue but just to confirm, here's an iterative solution that fails to perform and not due to lack of stack memory:
unsigned iterateIt(size_t a_count, int *a) {
unsigned rep = 1;
bool first_time = true;
while (true) {
int *b = calloc((a_count * a_count) / 2, sizeof(int));
if (b == NULL) {
perror("calloc failed!");
exit(1);
}
size_t b_count = 0;
for (size_t i = 0; i < a_count; i++) {
for (size_t j = i + 1; j < a_count; j++) {
if (a[i] != a[j]) {
b[b_count ++] = abs(a[i] - a[j]);
}
}
}
if (b_count == 0) {
free(b);
break;
}
if (first_time) {
first_time = false;
} else {
free(a);
}
a = b;
a_count = b_count;
rep++;
}
return rep;
}
The convergence is definitely there: at each round the maximal value decreases. I don't see a reason for a recursive approach though.
– user58697
Nov 21 '18 at 19:07
add a comment |
First consider this line:
return 1 + iterateIt(k, b);
The b
array never gets freed on this return
but if k
is zero, it does. Let's rewrite this code to clean it up a bit:
#include <stdio.h>
#include <stdlib.h>
unsigned iterateIt(size_t a_count, int *a) {
unsigned rep = 1;
int *b = calloc(a_count * a_count, sizeof(int));
size_t k = 0;
for (size_t i = 0; i < a_count; i++) {
for (size_t j = i + 1; j < a_count; j++) {
if (a[i] != a[j]) {
b[k++] = abs(a[i] - a[j]);
}
}
}
if (k > 0) {
rep += iterateIt(k, b);
}
free(b);
return rep;
}
int main() {
int x = {1, 324, 54};
printf("%un", iterateIt(sizeof(x) / sizeof(int), x));
return 0;
}
Watching the value of a_count
, the program tries to allocate too much memory and fails.
UPDATE
Since the two halves of the matrix end up identical, I fixed the above code to do what the OP did, just process 1/2 the matrix, i.e. j
starts at i + 1
since the two halves end up identical. I also ignore the diagonal as it's always zeros. Then the code completes for the three numbers in my example code but blows up again when I increase the array to four values.
I believe the recursive nature of the OP's solution is elegant and a non-issue but just to confirm, here's an iterative solution that fails to perform and not due to lack of stack memory:
unsigned iterateIt(size_t a_count, int *a) {
unsigned rep = 1;
bool first_time = true;
while (true) {
int *b = calloc((a_count * a_count) / 2, sizeof(int));
if (b == NULL) {
perror("calloc failed!");
exit(1);
}
size_t b_count = 0;
for (size_t i = 0; i < a_count; i++) {
for (size_t j = i + 1; j < a_count; j++) {
if (a[i] != a[j]) {
b[b_count ++] = abs(a[i] - a[j]);
}
}
}
if (b_count == 0) {
free(b);
break;
}
if (first_time) {
first_time = false;
} else {
free(a);
}
a = b;
a_count = b_count;
rep++;
}
return rep;
}
First consider this line:
return 1 + iterateIt(k, b);
The b
array never gets freed on this return
but if k
is zero, it does. Let's rewrite this code to clean it up a bit:
#include <stdio.h>
#include <stdlib.h>
unsigned iterateIt(size_t a_count, int *a) {
unsigned rep = 1;
int *b = calloc(a_count * a_count, sizeof(int));
size_t k = 0;
for (size_t i = 0; i < a_count; i++) {
for (size_t j = i + 1; j < a_count; j++) {
if (a[i] != a[j]) {
b[k++] = abs(a[i] - a[j]);
}
}
}
if (k > 0) {
rep += iterateIt(k, b);
}
free(b);
return rep;
}
int main() {
int x = {1, 324, 54};
printf("%un", iterateIt(sizeof(x) / sizeof(int), x));
return 0;
}
Watching the value of a_count
, the program tries to allocate too much memory and fails.
UPDATE
Since the two halves of the matrix end up identical, I fixed the above code to do what the OP did, just process 1/2 the matrix, i.e. j
starts at i + 1
since the two halves end up identical. I also ignore the diagonal as it's always zeros. Then the code completes for the three numbers in my example code but blows up again when I increase the array to four values.
I believe the recursive nature of the OP's solution is elegant and a non-issue but just to confirm, here's an iterative solution that fails to perform and not due to lack of stack memory:
unsigned iterateIt(size_t a_count, int *a) {
unsigned rep = 1;
bool first_time = true;
while (true) {
int *b = calloc((a_count * a_count) / 2, sizeof(int));
if (b == NULL) {
perror("calloc failed!");
exit(1);
}
size_t b_count = 0;
for (size_t i = 0; i < a_count; i++) {
for (size_t j = i + 1; j < a_count; j++) {
if (a[i] != a[j]) {
b[b_count ++] = abs(a[i] - a[j]);
}
}
}
if (b_count == 0) {
free(b);
break;
}
if (first_time) {
first_time = false;
} else {
free(a);
}
a = b;
a_count = b_count;
rep++;
}
return rep;
}
edited Nov 21 '18 at 20:55
answered Nov 21 '18 at 17:34
cdlanecdlane
17.5k21143
17.5k21143
The convergence is definitely there: at each round the maximal value decreases. I don't see a reason for a recursive approach though.
– user58697
Nov 21 '18 at 19:07
add a comment |
The convergence is definitely there: at each round the maximal value decreases. I don't see a reason for a recursive approach though.
– user58697
Nov 21 '18 at 19:07
The convergence is definitely there: at each round the maximal value decreases. I don't see a reason for a recursive approach though.
– user58697
Nov 21 '18 at 19:07
The convergence is definitely there: at each round the maximal value decreases. I don't see a reason for a recursive approach though.
– user58697
Nov 21 '18 at 19:07
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53416987%2fpair-wise-difference-using-recursion%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Why do you put
count *= count-1;
in a loop? What does it compute?– n.m.
Nov 21 '18 at 17:02
You do not test the return value of
malloc()
. My guess would be that you are computing a huge or even negative (because overflow) value incount
,malloc()
is therefore failing, and you are then attempting to write through the resulting null pointer.– John Bollinger
Nov 21 '18 at 17:04
Do you use an IDE? Does it have a debugger? Do you know how to use it? It is your best friend and will easilly let you resolve problems like this without having to ask us
– Mawg
Nov 21 '18 at 21:02