c++ to c

Can anyone please convert this code from C++ to C OR just give me a C solution for this problem:

Positive number N, find all combinations of 2 * n elements so that each element from 1 to n appears exactly twice and the distance between the two occurrences is equal to the value of the element. For example if n = 3 then we get (3, 1, 2, 1, 3, 2), (2, 3, 1, 2, 1, 3).


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

#include <bits/stdc++.h> 
using namespace std; 
  
void allCombinationsRec(vector<int> &arr, int elem, int n) 
{ 
    if (elem > n) 
    { 
        for (int i : arr) 
            cout << i << " "; 
        cout << endl; 
  
        return; 
    } 
  
    for (int i = 0; i < 2*n; i++) 
    { 
       
        if (arr[i] == -1 && (i + elem + 1) < 2*n && 
                arr[i + elem + 1] == -1) 
        { 
           
            arr[i] = elem; 
            arr[i + elem + 1] = elem; 
  
           allCombinationsRec(arr, elem + 1, n); 
  
            arr[i] = -1; 
            arr[i + elem + 1] = -1; 
        } 
    } 
} 
  
void allCombinations(int n) 
{ 
    vector<int> arr(2*n, -1); 
    int elem = 1; 
    allCombinationsRec(arr, elem, n); 
} 
  
int main() 
{ 
    int n = 3; 
    allCombinations(n); 
    return 0; 
}
Well it's very nearly C to start with.
Fix
- the range loop
- the cout
- the vector

The vector on line 36 would be
int *arr = malloc(2*n*sizeof(int));
But you need to initialise all the elements to -1.




Don't know how to use range loop in C. Please post the full working code here.
Last edited on
This is c code for the above. However it doesn't display anything...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void allCombinationsRec(int arr[], int elem, int n) {
	if (elem > n) {
		for (int i = 0; i < n * 2; ++i)
			printf("%i ", arr[i]);

		putchar('\n');
		return;
	}

	for (int i = 0; i < 2 * n; i++) {
		if (arr[i] == -1 && (i + elem + 1) < 2 * n &&
			arr[i + elem + 1] == -1) {

			arr[i] = elem;
			arr[i + elem + 1] = elem;

			allCombinationsRec(arr, elem + 1, n);

			arr[i] = -1;
			arr[i + elem + 1] = -1;
		}
	}
}

void allCombinations(int n) {
	int* arr = (int*)malloc(2 * n * sizeof(int));
        memset(arr, -1, 2 * n * sizeof(int));
	int elem = 1;
	allCombinationsRec(arr, elem, n);
	free(arr);
}

int main() {
	int n = 3;
	allCombinations(n);
}

Last edited on
Thanks. This should be the output:

3 1 2 1 3 2
2 3 1 2 1 3

Consider N at main is 3, and now where is its position on each row. So for any N, it should be like that.
Well now is the time to use the debugger to see where is the error.
I found none. I only changed this: printf("%i ", arr[i]); to printf("%d ", arr[i]);
Change
memset(arr, -1, 2 * n);
to
for ( int i = 0; i < 2 * n; i++ ) arr[i] = -1;
in @seeplus's code and it will be fine.


But why change it to C in the first place?
Last edited on
Yea. Mea Culpa. memset() works in chars and not in type size. L31 should be

 
memset(arr, -1, 2 * n * sizeof(int));


[Fixed above]


3 1 2 1 3 2
2 3 1 2 1 3

Last edited on
Using memset is still broken, it only 'works' because all the bytes of (int)-1 are the same (like 0xffffffff).

It also presumes that the machine is using 2's complement arithmetic.
https://en.wikipedia.org/wiki/Signed_number_representations

memset(arr, 42, 2 * n * sizeof(int));
for example does not set your array to be full of the integer value 42.

Use lastchance's for loop, and it always works regardless of the numeric data type, or the underlying representation of that type.



You can't use memset to initialize the array, you have to use a loop.

You only get away with if because you're setting each byte to FF, and -1 for all values in the array is a pattern FFFF...

If your array was an array of float/double, it would fail.
Fair points. :) :)

memset can zero ints & floating point types as well. Probably the most common use of it.
In practice, yes: std::numeric_limits<T>::is_iec559 is true on almost all implementations.

In theory, no: the standard does not mandate the object / value representations for floating point types. (Bytes filled with zeroes could turn out to be an invalid value representation or could represent a non-zero value).

In practice: just write a simple, transparent, loop (or use std::uninitialised_fill). And then let the optimiser (it knows what is going on) take care of low-level optimisations.
Topic archived. No new replies allowed.