This function should reverse an array of vectors on the heap, but it doesn't work. It seems like the tmp_array also gets changed.
Output is:
13.700000 21.300000
13.700000 21.300000
Should be:
8.900000 31.700000
13.700000 21.300000
createVector creates a struct Vector with two double values x and y.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _Vector_
{
double x_;
double y_;
} Vector;
Vector *createVector(double x, double y)
{
Vector *vector = malloc((size_t)(sizeof(Vector)));
if (vector == NULL)
{
printf("Memory Error!\n");
return vector;
}
vector->x_ = x;
vector->y_ = y;
return vector;
}
void reverseVectorArray(Vector **vector_array, int length)
{
Vector **tmp_array = malloc(sizeof(Vector*)*length);
if(tmp_array == NULL)
{
printf("Memory Error!\n");
return;
}
memcpy(tmp_array, vector_array, sizeof(Vector*)*length);
int position = length - 1;
for(int i = 0; i<length; i++)
{
*(vector_array[position]) = *(tmp_array[i]);
position--;
}
free(tmp_array);
}
int main()
{
int length = 2;
Vector **vector_array = malloc(sizeof(Vector*) * 2);
vector_array[0] = createVector(13.7, 21.3);
vector_array[1] = createVector(8.9, 31.7);
reverseVectorArray(vector_array, length);
for(int i = 0; i<length; i++)
{
printf("%f ", vector_array[i]->x_);
printf("%f ", vector_array[i]->y_);
printf("\n");
}
return 0;
}
It seems you mean the following.
#include <stdio.h>
#include <stdlib.h>
typedef struct Vector
{
double x;
double y;
} Vector;
Vector * createVector( double x, double y )
{
Vector *vector = malloc( sizeof( Vector ) );
if ( vector )
{
vector->x = x;
vector->y = y;
}
return vector;
}
void reverseVectorArray( Vector **vector_array, size_t n )
{
for ( size_t i = 0; i < n / 2; i++ )
{
Vector tmp = *vector_array[i];
*vector_array[i] = *vector_array[n - i - 1];
*vector_array[n - i - 1] = tmp;
}
}
int main( void )
{
size_t n = 2;
Vector **vector_array = malloc( n * sizeof( Vector * ) );
vector_array[0] = createVector( 13.7, 21.3 );
vector_array[1] = createVector( 8.9, 31.7 );
reverseVectorArray( vector_array, n );
for ( size_t i = 0; i < n; i++ )
{
printf( "%f ", vector_array[i]->x );
printf( "%f ", vector_array[i]->y );
putchar( '\n' );
}
return 0;
}
Take into account that you should append the program with a code that will free all allocated memory.
As for your code then for starters according to the C Standard the function main without parameters shall be declared like
int main( void )
If you are using the function memcpy then you need to include header <string.h>.
Instead of this declaration
Vector *vector = malloc((size_t)(sizeof(Vector*)));
^^^^^^^
you have to write
Vector *vector = malloc( sizeof( Vector ) );
^^^^^^
There is no need to allocate an auxiliary array to reverse the original array. Such an approach is inefficient.
The problem with your function reverseVectorArray is that it rewrites the values of the second half of the array with the values of the first half of the array. So it makes two halves of the array equal each other.
Related
I practice in c language, here is the exercise:
Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
You can return the answer in any order.
Example :
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Output: Because nums[0] + nums[1] == 9, we return [0, 1].
Here my attempt:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
static int r[2];
for(int i=0;i<numsSize;i++){
for(int j=0;j<numsSize;j++){
if(i!=j&&(nums[i]+nums[j])==target){
r[0]=i;
r[1]=j;
}
}
}
return r;
}
But Irecieve a wrong answer:
enter image description here
The function definition does not satisfies the requirement specified in the comment
Note: The returned array must be malloced, assume caller calls free()
Moreover the parameter
int* returnSize
is not used within your function definition.
It seems the function should be defined the following way as it is shown in the demonstration program below. I assume that any element in the source array can be present in the result array only one time.
#include <stdio.h>
#include <stdlib.h>
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int *twoSum( int *nums, int numsSize, int target, int *returnSize )
{
int *result = NULL;
*returnSize = 0;
for (int i = 0; i < numsSize; i++)
{
for (int j = i + 1; j < numsSize; j++)
{
if (nums[i] + nums[j] == target)
{
int unique = result == NULL;
if (!unique)
{
unique = 1;
for (int k = 1; unique && k < *returnSize; k += 2)
{
unique = nums[k] != nums[j];
}
}
if (unique)
{
int *tmp = realloc( result, ( *returnSize + 2 ) * sizeof( int ) );
if (tmp != NULL)
{
result = tmp;
result[*returnSize] = i;
result[*returnSize + 1] = j;
*returnSize += 2;
}
}
}
}
}
return result;
}
int main( void )
{
int a[] = { 2, 7, 11, 15 };
int target = 9;
int resultSize;
int *result = twoSum( a, sizeof( a ) / sizeof( *a ), target, &resultSize );
if (result)
{
for (int i = 0; i < resultSize; i += 2 )
{
printf( "%d, %d ", result[i], result[i + 1] );
}
putchar( '\n' );
}
free( result );
}
The program output is
0, 1
Though as for me then I would declare the function like
int *twoSum( const int *nums, size_t numsSize, int target, size_t *returnSize );
The brute force approach is very simple to this problem.
int* twoSum(int* arr, int n, int t, int* returnSize){
int *res=malloc(2*sizeof(int));
*returnSize=2;
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if((arr[i]+arr[j])==t)
{
res[0]=i;
res[1]=j;
goto exit;
}
}
}
exit:
return res;
}
I understand I'm splitting the array over the double pointer, but how can I deallocate if I lost the data track?
#include <stdio.h>
#include <stdlib.h>
#define width 20
#define height 20
void allocate_matrix(int ***matrix)
{
double **local_matrix, *data;
local_matrix = (double **)malloc(sizeof(double *) * height);
data = (double *)malloc(sizeof(double) * width * height);
for (int i = 0; i < height; i++)
{
local_matrix[i] = &(data[i * width]);
}
*matrix = local_matrix;
}
void deallocate_matrix(int **matrix) {
}
int main(void) {
int **matrix;
allocate_matrix(&matrix);
deallocate_matrix(matrix);
return 0;
}
You didn't lose track of the second pointer. If you look at your loop body:
local_matrix[i] = &(data[i * width]);
When i is 0, local_matrix[0] is assigned &data[0] which is the same as data. So that's what you need to free:
void deallocate_matrix(int **matrix) {
free(matrix[0]);
free(matrix);
}
First of all, you are allocating space for double then use it as int, which doesn't make sense (and will not compile).
But the main problem here is that you shouldn't be allocating this as fragmented segments but as a contiguous 2D array. Please study Correctly allocating multi-dimensional arrays. This will give a major performance boost and may (arguably) make the code a bit easier to read as well.
If we follow the advise in that post, then your code could be rewritten as:
#include <stdio.h>
#include <stdlib.h>
void allocate_matrix(size_t height, size_t width, int (**matrix)[height][width])
{
int (*local_matrix) [height][width];
local_matrix = malloc(sizeof *local_matrix);
if(local_matrix == NULL)
{
// handle errors
}
*matrix = local_matrix;
}
int main (void)
{
const size_t height = 20;
const size_t width = 20;
int (*matrix)[height][width];
allocate_matrix(height, width, &matrix);
int(*pmatrix)[width] = *matrix; // pointer to first 1D array for easier syntax
for(size_t h=0; h<height; h++)
{
for(size_t w=0; w<width; w++)
{
pmatrix[h][w] = h+w; // assign some sort of data
printf("%d ", pmatrix[h][w]);
}
printf("\n");
}
free(matrix);
return 0;
}
As you can see this also eliminated the need for a complex deallocation routine, since we can just pass the pointer directly to free() and deallocate everything at one single place.
the following proposed code:
needs the header file: stdlib.h for the prototypes for exit() and malloc() and EXIT_FAILURE
performs the desired functionality
you might want to modify the calculation of the initialization values of the matrix
and now, the proposed code:
double **allocate_matrix(void)
{
local_matrix** = malloc( sizeof(double *) * height );
if( ! local_matrix )
{
perror( "malloc for matrix height failed:");
exit( EXIT_FAILURE );
}
for( size_t y = 0; y<height; y++ )
{
local_matrix[y] = malloc( sizeof(double) * width );
if( !local_matrix[y] )
{
//cleanup and exit
}
for ( size_t i = 0; i < width; i++)
{
local_matrix[y][i] = i;
}
}
return local_matrix;
}
int main( void )
{
double **matrix;
matrix = allocate_matrix();
for( size_t y= 0; y< height; y++ )
{
free( matrix[ y ] ):
}
free( matrix );
}
How can an array of array of int be declared outside the main, then build inside the main once we know the length of the array of array we want to build, if one dimension is already known.
For example, if the array should be array[numberofargs][2], where the dimension 2 is already known but not numberofargs before execution of main.
One way is just to declare for example a pointer in a file scope like
int ( *array )[2] = NULL;
and then in one of functions allocate a memory for the array.
For example
#include <stdlib.h>
int (*array)[2] = NULL;
int main(void)
{
int numberofargs = 5;
array = malloc( sizeof( int[numberofargs][2] ) );
//...
free( array );
return 0;
}
Or the following way
#include <stdlib.h>
int **array = NULL;
int main(void)
{
int numberofargs = 5;
array = malloc( numberofargs * sizeof( *array ) );
for ( int i = 0; i < numberofargs; i++ )
{
array[i] = malloc( sizeof( *array[i] ) );
}
//...
for ( int i = 0; i < numberofargs; i++ )
{
free( array[i] );
}
free( array );
return 0;
}
Unfortunately, I do not know how to create an array where only the second dimension is known. What you can do is the following:
#include <stdlib.h>
#include <stdio.h>
#define SECOND_DIM 2
int *array;
// returns array[x][y]
int foo(int *array, int x, int y) {
return *(array+x*SECOND_DIM+y);
}
int main(int args, char *argv[]) {
if(!argv[0]) return 0;
array = malloc(args*SECOND_DIM*sizeof(int));
for(int i=0;i<args; i++) {
for(int j=0;j<SECOND_DIM; j++)
*(array+(i*SECOND_DIM)+j) = (i+1)*100+j;
}
printf("array[0][0]: %d\n", foo(array,0,0)); // array[0][0]
printf("array[0][1]: %d\n", foo(array,0,1)); // array[0][1]
free(array);
}
int (*array)[2] = malloc(sizeof(int[numberofargs][2]));
And then when you're finished with it:
free(array);
I have to use the recursive selection sort in order to order different arrays of integers.
These arrays are respectively formed by 100, 1000, 10000, 100000, 200000, 500000 items and can be formed by ordered numbers, partially ordered numbers, inverted ordered numbers and random numbers.
After that I have to calculate the time the algorithm took to order the array.
I have to use recursion, It's a homework.
I created a function that generates the array:
typedef enum {ORINATO, INVERS, PARZ_ORDINATO, RANDOM} Ordine;
int *generaArray(int dimensione, Ordine ordine) {
int i, j, n;
int *array = (int*)malloc(dimensione * sizeof(int));
if (!array){
return NULL;
}
switch (ordine){
case ORINATO:
for (i = 0; i < dimensione; i++){
array[i] = i;
} break;
case INVERS:
n =0;
for ( i = dimensione-1; i >= 0 ; i--) {
array[i] = n;
n++;
}break;
case PARZ_ORDINATO:
for (i = 0; i < dimensione/2 ; i++) {
array[i] = i;
}
for (j = i+1; j <dimensione; j++){
n = rand();
array[j] = n;
};break;
case RANDOM:
for ( i = 0; i <= dimensione ; i++) {
array[i] = rand();
}break;
default:
break;
}
return array;
}
And it works like wonders.
Then I have created the recursive selection sort like follows:
void recursiveSelectionSort(int *array, int dim, int start){
int min=0;
if (start >= dim-1){
return;
}
min = findMin(array, start, start+1, dim);
swap(&array[min], &array[start]);
recursiveSelectionSort(array, dim, start+1);
}
int findMin(int *array, int min, int start, int dim){
if(start == dim ){
return min;
}
if (array[start]< array[min]){
min = start;
}
return findMin(array, min, start+1, dim);
}
void swap (int* x, int *y){
int temp = *x;
x = *y;
y = *temp;
}
Now, this as well should work but something clearly isn't. Let's make an example with the implementation, this is what i put in my main:
int main() {
int *array;
clock_t start, end;
double t;
array = generaArray(1000, ORINATO);
start = clock();
recursiveSelectionSort(array, 1000, 0);
end = clock();
t = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("\nIl tempo impiegato per 1000 elementi รจ: %lf secondi", t);
return 0;
}
This works (but it's slower thank it should be). However if you try and change the dimension from 1000 to 200000 or 500000 it shows error 11.
What is it causing it? I tried everything but it doesn't seem to work.
For starters recursive functions called for large arrays can invoke a stack overflow.
So use non-recursive functions that implement the method selection sort for large arrays.
As for your implementation then for example the function swap has typos.
void swap (int* x, int *y){
int temp = *x;
x = *y;
y = *temp;
}
I think you mean
void swap (int* x, int *y){
int temp = *x;
*x = *y;
*y = temp;
}
All other functions have too many parameters.
For example the function findMin can be declared the following way
size_t findMin( const int *a, size_t n );
and can be also defined as a recursive function (if you decided to write recursive functions then this function can be also recursive)
Here is a demonstrative program that shows how the functions can be defined
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void swap( int *x, int *y )
{
int temp = *x;
*x = *y;
*y = temp;
}
size_t findMin( const int a[], size_t n )
{
if ( n < 2 )
{
return 0;
}
else
{
size_t i = findMin( a + 1, n - 1 ) + 1;
return a[i] < a[0] ? i : 0;
}
}
void recursiveSelectionSort( int a[], size_t n )
{
if ( !( n < 2 ) )
{
size_t i = findMin( a + 1, n - 1 ) + 1;
if ( a[i] < a[0] ) swap( &a[0], &a[i] );
recursiveSelectionSort( a + 1, n - 1 );
}
}
int main(void)
{
enum { N = 15 };
int a[N];
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < N; i++ )
{
a[i] = rand() % N;
}
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
recursiveSelectionSort( a, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output might look like
11 9 3 5 6 8 2 4 5 3 7 9 2 0 14
0 2 2 3 3 4 5 5 6 7 8 9 9 11 14
I encountered the following question in an interview.
Complete this function to return a reversed array without modifying the function signature or the original array. Note that static data types should not be used here at all.
Assume the arrayLength is a power of 2. i.e 2^n. -> I think this is the trick here.
int* reverse(int *array, int arrayLength){
}
Please help.
Note that I could not really think of a solution to the problem. The interviewer hinted at using 2^n for the puspose, but i could not really think of the solution.
How about this:
int* reverse(int *array, int arrayLength){
if (arrayLength==1) {
int* out=(int*)malloc(sizeof(int));
out[0] = array[0];
return out;
}
int* left = reverse(array+arrayLength/2, arrayLength-arrayLength/2);
int* right = reverse(array,arrayLength/2);
int* out = (int*)realloc(left, sizeof(int)*arrayLength);
memcpy(out+arrayLength/2, right, sizeof(int)*(arrayLength/2));
free(right);
return out;
}
Agree with OP the the hint is "2^n". As with many recursive functions: divide and conquer.
This routine first deals with errant paramters and the simple lengths. Next, divide the length in half and reverse each half. Form the result by concatenating the reversed left and right sub-arrays. First, right, then left.
Usual clean-up follows
#include <string.h>
#include <stdlib.h>
int* reverse(int *array, int arrayLength) {
// Check parameters
if (array == NULL || arrayLength < 0) {
; // TBD HandleBadParameters();
}
// Allocate space for result, not much to do if length <= 1
int *y = malloc(arrayLength * sizeof *y);
if (y == NULL) {
; // TBD HandleOOM();
}
if (arrayLength <= 1) {
memcpy(y, array, arrayLength * sizeof *y);
return y;
}
// Find reverse of the two halves
int halflength = arrayLength / 2;
int *left = reverse(array, halflength);
int *right = reverse(&array[halflength], halflength);
// Append them to the result - in reverse order
memcpy(y, right, halflength * sizeof *y);
memcpy(&y[halflength], left, halflength * sizeof *y);
// Clean-up and return
free(right);
free(left);
return y;
}
int* reverse(int *array, int arrayLength){
if(arrayLength == 0) return array;
int* ret = (int*)malloc(arrayLength*sizeof(int));
for(int i=0;i<arrayLength;i++) ret[i] = array[arrayLength-1-i];
return reverse(ret, 0); // technically recursive
}
Here it is (and works):
int *reverse(int *array, int arrayLength)
{
if (arrayLength > 1) {
int i, n = arrayLength >> 1;
int *m = calloc(n, sizeof(int));
memcpy(m, array, n*sizeof(int));
memcpy(array, array + n, n*sizeof(int));
memcpy(array + n, m, n*sizeof(int));
free(m);
reverse(array, n);
reverse(array+n, n);
} /* for */
return array;
} /* reverse */
it can be done without temporary storage, but you have to iterate a little.
int *reverse(int *a, int al)
{
if (al > 1) {
int i, a1 = al >> 1;
for (i = 0; i < a1; i++) {
int temp = a[i];
a[i] = a[i + a1];
a[i + a1] = temp;
} /* for */
reverse(a, a1);
reverse(a+a1, a1);
} /* for */
return a;
} /* reverse */
but, it would be nicer just to exchange from the boundaries to the middle and do it completely iterative.
int *reverse(int *array, int arrayLength)
{
int a, b;
for (a = 0, b = arrayLength-1; a < b; a++, b--) {
int temp = array[a];
array[a] = array[b];
array[b] = temp;
} /* for */
return array;
} /* reverse */
And just for the ones who asked for a non selfmodifying array, this all-inefficient form:
int *reverse(int *array, int arrayLength)
{
int *a1, *a2;
int *res;
if (arrayLength > 1) {
int l = arrayLength >> 1;
a1 = reverse(array, l);
a2 = reverse(array + l, l);
res = calloc(arrayLength, sizeof(int));
memcpy(res, a2, l*sizeof(int));
memcpy(res+l, a1, l*sizeof(int));
free(a1);
free(a2);
} else {
/* we return always memory alloc'd with malloc() so we have to do this. */
res = malloc(sizeof(int));
*res = array[0];
} /* if */
return res;
} /* reverse */
Well, here's one sneaky way, and it doesn't care what length the array is. Note: I'm assuming you can't introduce a new function, it has to be done all within the existing function
if the length is postive, it allocates memory and makes a copy, then calls reverse again with a negative length and the copy, then if the function is called with a negative length, it reverses the first and last inplace, then recursively calls by moving to the next in the array and shrinks the length till there is nothing left to reverse and then the recursive function unwinds
int* reverse(int *array, int arrayLength){
int* result;
if(arrayLength > 0)
{
result =(int*) malloc((sizeof(int)*arrayLength));
memcpy(result, array, sizeof(int)*arrayLength);
reverse(result, -arrayLength);
return result;
}
else if(arrayLength < -1)
{
int end = (-arrayLength)-1;
int temp = array[end];
array[end] = array[0];
array[0] = temp;
return reverse(array+1, arrayLength+2);
}
return array;
}
Considering that arrayLength is always a power of 2. we will apply the function to the two parts of the array then concat them in the reverse way.
Finaly if the array has only one element, we simply return other array with the same element.
int* reverse(int *array, int arrayLength){
int * newArray = NULL;
if(arrayLength == 1){
newArray = (int *)malloc(sizeof(int));
*newArray = array[0];
} else if(arrayLength == 2){
newArray = (int *)malloc(2 * sizeof(int));
newArray[0] = array[1];
newArray[1] = array[0];
} else {
// apply to first half
int * first = reverse(array, arrayLength / 2);
// apply to second half
int * second = reverse(array + arrayLength / 2, arrayLength / 2);
// allocate space
newArray = (int *) malloc(arrayLength * sizeof(int));
// copy parts in reverse way
memcpy(newArray, second, arrayLength / 2 * sizeof(int));
memcpy(newArray + arrayLength / 2, first, arrayLength / 2 * sizeof(int));
// free allocated space for parts
free(first);
free(second);
}
return newArray;
}
I'll give it a shot.
Knowing that the array is of length 2^n means that it can be safely halved. We call the function recursively on each half until length is 2. At this point we swap the two integers. Think { 2,1,4,3,6,5,8,7 }. When we come back from that, each half is then merged opposite of where it came from ( { 4,3,2,1,8,7,6,5} ). Rinse and repeat.
#include <stdio.h>
#include <stdlib.h>
int * reverse( int* arr, int length )
{
if ( length == 1 )
{
int *result = malloc( sizeof( arr[0] ) );
result[0] = arr[0];
return result;
}
int * result = 0;
if ( length == 2 )
{
result = malloc( sizeof( arr[0] ) * 2 );
result[0] = arr[1];
result[1] = arr[0];
}
else
{
int half_length = length / 2;
// named correctly
int * right = reverse( arr, half_length );
int * left = reverse( arr + half_length, half_length );
result = malloc( sizeof( arr[0] ) * length );
for ( int i = 0; i < half_length; ++i )
{
result[i] = left[i];
result[ i + half_length ] = right[i];
}
free( right );
free( left );
}
return result;
}
int main( void )
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int length = 8;
int *reversed = reverse( arr, length );
for ( int i = 0; i < length; ++i )
{
printf( "%d %d\n", arr[i], reversed[i] );
}
free( reversed );
return 0;
}
for all integer arrays with more than 2 elements.
The basic idea is to swap elements from both ends untill the number of elements remaining is 1.
int* reverse_array(int* array, int arrayLength)
{
if(arrayLength <2)
{
return NULL;
}
else
{
int *array1 = NULL;
int *array2 = NULL;
array1 = malloc(arrayLength*sizeof(int));
memcpy(array1,array,arrayLength*sizeof(int));
/*swap the start and end*/
swap(array1,(array1+arrayLength-1));
/* swap the next pair */
array2 = reverse_array(array1+1,arrayLength-2);
memcpy(array1+1,array2,(arrayLength-2)*sizeof(int));
if(array2!= NULL)
{
free(array2);
}
return array1;
}
}