Select certain elements in array to create new array - c

How could I select a certain number of elements from an array by giving a start and ending index number to create a new array?
For example, if my original array was {1,2,3,4,5,6}, and I say x=0 and y=2 for their index values, I would have a new array that is {1,2,3}.
Thank you.

If your compiler supports variable length arrays then you can do this the following way
#include <stdio.h>
#include <string.h>
int main(void)
{
int a[] = { 1, 2, 3, 4, 5, 6 };
size_t n1 = 0, n2 = 2;
int b[n2 - n1 + 1];
memcpy( b, a + n1, ( n2 - n1 + 1 ) * sizeof( int ) );
size_t n = sizeof( b ) / sizeof( *b );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", b[i] );
}
putchar( '\n' );
return 0;
}
The program output is
1 2 3
Otherwise the new array should be allocated dynamically as for example
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
int a[] = { 1, 2, 3, 4, 5, 6 };
size_t n1 = 0, n2 = 2;
size_t n = n2 - n1 + 1;
int *b = malloc( n * sizeof( *b ) );
memcpy( b, a + n1, n * sizeof( int ) );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", b[i] );
}
putchar( '\n' );
free( b );
return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void print_arr(int* arr, int len) {
for (int i = 0; i < len; i ++) {
printf("%d", arr[i]);
if (i != len - 1) {
printf(" ");
} else {
printf("\n");
}
}
}
int main() {
int arr1[] = {1, 2, 3, 4, 5, 6};
int start, end;
printf("input the beginning and the end: ");
scanf("%d %d", &start, &end);
int len = end - start + 1;
// we use malloc to dynamically allocate an array of the correct size
int* arr2 = (int*)malloc(len * sizeof(int));
// we use memcpy to copy the values
memcpy(arr2, arr1 + start, len * sizeof(int));
print_arr(arr1, 6);
print_arr(arr2, len);
// we have to free the memory
free(arr2);
return 0;
}

Related

Using `malloc` for dynamical array concatenation in C leads to strange exit code

Problem statement
I want to write a function
int *concat_tab(int n1, int *t1, int n2, int *t2)
in pure C which does the following: Given two arrays of integers (as pointers), the function should return a new array which is the concatenation of the two input arrays.
The input names mean the following:
n1: length of the first array;
*t1: pointer to the first element of the first array;
n2: length of the second array;
*t2: pointer to the first element of the second array.
My code
#include<stdio.h>
#include<stdlib.h>
int *concat_tab(int n1, int *t1, int n2, int *t2){
/*
* Takes two 1D arrays and their lengths as input and outputs their concatenation.
* Input:
* - n1: Length of first array
* - t1: First array
* - n2: Length of second array
* - t2: Second array
* Output:
* - Array of length n1+n2 containing the elements of t1 followed by the elements of t2
*/
int *output = (int*) malloc(n1+n2);
for(int k = 0; k < n1+n2; k++){
if(k < n1) {
*(output + k) = *(t1 + k);
}
else{
*(output + k) = *(t2+k-n1);
}
}
return output;
}
int main(){
int array1[4] = {1, 2, 3, 4};
int array2[5] = {10, 11, 12, 13, 14};
int *output = concat_tab(4, array1, 5, array2);
for(int k = 0; k < 9; k++){
printf("Output[%d] = %d\n", k, *(output+k));
}
return 0;
}
My problem
As output I get, as desired,
Output[0] = 1
Output[1] = 2
Output[2] = 3
Output[3] = 4
Output[4] = 10
Output[5] = 11
Output[6] = 12
Output[7] = 13
Output[8] = 14
However, my program exits with the exit code -1073740940 instead of 0. Why does that happen?
The undesired exit code happens because the input passed to malloc in C denotes the number of bytes (which is not, in general, equal to the length of the array) that will be allocated in memory (for instance, each int in the array requires 4 bytes and not just 1).
Therefore, what happens is that C allocates too little memory for the output array. This can be fixed by replacing the line
int *output = (int*) malloc(n1+n2);
with
int *output = (int*) malloc(sizeof(int)*(n1+n2));
and now the program will exit as desired.
This memory allocation
int *output = (int*) malloc(n1+n2);
is equivalent to
int *output = (int*) malloc( ( n1+n2 ) * sizeof( char ));
But you need to allocate memory for objects of the type int. That is you need to write
int *output = (int*) malloc( ( n1+n2 ) * sizeof( int ) );
Also the function declaration is bad. Firstly the passed arrays are not being changed within the function. So the corresponding parameters should have the qualifier const.
Secondly the parameters that specify the number of elements in the arrays should have the type size_t.
Thirdly the order of parameters should be changed.
So the function declaration should look like
int * concat_tab( const int *t1, size_t n1, const int *t2, size_t n2 );
Pay attention to that you should to check whether the memory was allocated successfully. And you need to free it when the allocated array is not required any more.
Here is shown how your program can look.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int * concat_tab( const int *t1, size_t n1, const int *t2, size_t n2 )
{
int *output = NULL;
if (n1 || n2)
{
output = malloc( ( n1 + n2 ) * sizeof( int ) );
if (output != NULL)
{
memcpy( output, t1, n1 * sizeof( int ) );
memcpy( output + n1, t2, n2 * sizeof( int ) );
}
}
return output;
}
int main( void )
{
int array1[] = { 1, 2, 3, 4 };
size_t n1 = sizeof( array1 ) / sizeof( *array1 );
int array2[] = { 10, 11, 12, 13, 14 };
size_t n2 = sizeof( array2 ) / sizeof( *array2 );
int *output = concat_tab( array1, n1, array2, n2 );
if ( output != NULL )
{
for (size_t i = 0; i < n1 + n2; i++)
{
printf( "Output[%zu] = %d\n", i, *( output + i ) );
}
}
free( output );
}

Set typedef that can be 2 different types

I am trying to make a function that can receive a variable which can be a char or an int and for that I have to give the variable a type but I don't know what to put because I want it to be able to receive both.
My code is like this and i don't know what to put in the spot where is written 'IDK':
#include <stdio.h>
#include <string.h>
int is_string = 0;
#define less(A,B) (!is_string ? ((A)<(B)) : (strcmp(A,B)<0))
void merge(IDK a[], int l, int m, int r)
{
IDK aux[10000][20];
int i, j, k;
for (i = m+1; i > l; i--) aux[i-1] = a[i-1];
for (j = m; j < r; j++) aux[r+m-j] = a[j+1];
for (k = l; k <= r; k++){
if (less(aux[j], aux[i])) a[k] = aux[j--];
else a[k] = aux[i++];
}
}
void mergesort(IDK a[], int l, int r) {
int m = (r+l)/2;
if (r <= l)
return;
mergesort(a, l, m);
mergesort(a, m+1, r);
merge(a, l, m, r);
}
int main(){
mergesort(a,left,right);
}
I want the 'IDK' to be char when the variable is_stringis 1, and int when else...
The goal is to use the function to sort words alphabetically or numbers (lowest to highest), the function just has to sort one type of object at a time, but I want it to be able to sort both types of objects so I don't have to repeat code.
I want to have a program that chooses (at runtime) what type it needs to sort.
Thanks
The general approach of writing such functions in C is to declare a function that accepts a pointer of the type void * together with the number of elements in the passed array, the size of an object of the array element type and a comparison function similarly how the standard C function qsort is declared.
Here is a demonstrative program that shows such an approach.
The function merge can be written without allocating dynamically memory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void merge( void *a, size_t m, size_t n, size_t size, int cmp( const void *, const void * ) )
{
void *p = malloc( n * size );
size_t i = 0, j = m;
char *pos = p;
while ( i < m && j < n )
{
if ( cmp( ( char * )a + j * size, ( char *)a + i * size ) < 0 )
{
memcpy( pos, ( char * )a + j * size, size );
++j;
}
else
{
memcpy( pos, ( char * )a + i * size, size );
++i;
}
pos += size;
}
if ( i < m )
{
memcpy( pos, ( char * )a + i * size, ( m - i ) * size );
}
if ( j < n )
{
memcpy( pos, ( char * )a + j * size, ( n - j ) * size );
}
memcpy( a, p, n * size );
free( p );
}
void mergesort( void *a, size_t n, size_t size, int cmp( const void *, const void * ) )
{
if ( n / 2 )
{
mergesort( a, n / 2, size, cmp );
mergesort( ( char * )a + n / 2 * size, n - n / 2, size, cmp );
merge( a, n / 2, n, size, cmp );
}
}
int cmp_int( const void *p1, const void *p2 )
{
int a = *( int * )p1;
int b = *( int * )p2;
return ( b < a ) - ( a < b );
}
int cmp_string( const void *p1, const void *p2 )
{
return strcmp( *( const char * const * )p1, *( const char * const * )p2 );
}
int main(void)
{
int a[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
const size_t N1 = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N1; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
mergesort( a, N1, sizeof( *a ), cmp_int );
for ( size_t i = 0; i < N1; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
char * s[] = { "J", "I", "H", "G", "F", "E", "D", "C", "B", "A" };
const size_t N2 = sizeof( s ) / sizeof( *s );
for ( size_t i = 0; i < N2; i++ )
{
printf( "%s ", s[i] );
}
putchar( '\n' );
mergesort( s, N2, sizeof( *s ), cmp_string );
for ( size_t i = 0; i < N2; i++ )
{
printf( "%s ", s[i] );
}
putchar( '\n' );
return 0;
}
The program output is
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
J I H G F E D C B A
A B C D E F G H I J
You're looking for a union, but that won't work with your calls to scanf and printf. They expect a certain type of argument depending on the format modifier, in this case expecting an int or int* for modifier "%d".
union IDK
{
int int_val;
char *string_val;
};
void merge(union IDK a[], int l, int m, int r);
What you read from the console is always a string. scanf can convert it to a number, if that's what you ask for with "%d". But it appears that what you really are looking for is a way to sort strings that may consist of digits. The easiest way to do that is to try to convert it using strtol.
There's another pitfall you should be aware of. strcmp compares the ASCII values of characters. This won't sort alphabetically, if that's what you're looking for.
Note that a generalized sorting function is usually implemented by passing it a void*, the number of elements, the size of those elements, and a function pointer to a comparison function. See qsort for an example.

C kind of sorting

Ok so a function which arranges the elements in an array in such a way that all elements
smaller than a given value are placed into positions to the left of the elements that are larger
than the given value.
For instance if the array contents are {4,6,2,9,1,7,3,10} and x is given as 5, then
{4,3,2,1,9,7,6,10} is a possible solution, since all elements smaller than 5 are to the left
of the elements larger than 5.
Also, using brackets [ ] is ​ forbidden ​ except for defining the array in the main function.
Also, implement a function which prints the contents of an array. Both functions must be
implemented recursively.
you are allowed to access each element of the array only for once.
ok so this "challenge" and I dont know if it is possible with the given restrictions. I have tried to make it with a while loop and then convert it to recursive somehow but you are not allowed to change the parameters as well. Does anyone know a solution.
I have written something but its garbage.
#include <stdio.h>
#define length 8
void selection(int array[],int size, int x){
int i=0;
int temp;
if(( array[i]>x ) && (array[i] > array[i+1])){
temp=array[i+1];
array[i+1]=array[i];
array[i]=temp;
i++;
selection(array+1,size-1,x)
}
else if(( array[i] > x) && ( array[i+1] > array[i])){
i++;
}
//This is not correct
}
void printArray(int arr[], int start, int len)
{
if(start >= len)
return;
printf("%d ", arr[start]);
printArray(arr, start + 1, len);
}
int main(){
int array[length]={6,4,2,9,1,7,3,10};
int x=5;
selection(array,length,x);
printArray(array,0,length);
return 0;
}
I havent implemented the a recursive solution because things I tried kept giving segmentation faults because I was reaching outside the array.
Can anyone do this recursivly without for or while. I guess you need to split the array and look at it half by half
Here you are.
#include <stdio.h>
void partition( int a[], size_t n, int pivot )
{
if ( !( n < 2 ) )
{
if ( *a < pivot )
{
partition( a + 1, n - 1, pivot );
}
else
{
if ( *( a + n - 1 ) < pivot )
{
int tmp = *a;
*a = *( a + n - 1 );
*( a + n - 1 ) = tmp;
partition( a + 1, n - 2, pivot );
}
else
{
partition( a, n - 1, pivot );
}
}
}
}
int main(void)
{
int a[] = { 4, 6, 2, 9, 1, 7, 3, 10 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
int pivot = 5;
partition( a, N, pivot );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output is
4 6 2 9 1 7 3 10
4 3 2 1 9 7 6 10
Or also with a recursive definition of the function printArray.
#include <stdio.h>
void partition( int a[], size_t n, int pivot )
{
if ( !( n < 2 ) )
{
if ( *a < pivot )
{
partition( a + 1, n - 1, pivot );
}
else
{
if ( *( a + n - 1 ) < pivot )
{
int tmp = *a;
*a = *( a + n - 1 );
*( a + n - 1 ) = tmp;
partition( a + 1, n - 2, pivot );
}
else
{
partition( a, n - 1, pivot );
}
}
}
}
void printArray( const int a[], size_t n )
{
if ( n )
{
printf( "%d ", *a );
printArray( a + 1, n - 1 );
}
else
{
putchar( '\n' );
}
}
int main(void)
{
int a[] = { 4, 6, 2, 9, 1, 7, 3, 10 };
const size_t N = sizeof( a ) / sizeof( *a );
printArray( a, N );
int pivot = 5;
partition( a, N, pivot );
printArray( a, N );
return 0;
}
The recursive function printArray also can be defined the following way
void printArray( const int a[], size_t n )
{
n == 0 ? ( void )putchar( '\n' )
: ( printf( "%d ", *a ), printArray( a + 1, n - 1 ) );
}

Most long series of element in array

I've prepared a code that should found the longer series of elements in growing order .for example ,in arrays exists following elements : 1 2 3 4 5 2 7 6 7 9,output will 5 (the series from 1 to 5) ,function will return integer tempcount that include numbers of element and print it.but get an error ,the function
isn't working:
#include "stdafx.h"
#include <stdio.h>
int find_maximum(int[], int);
int main() {
int c, array[100], size, location, maximum,found;
scanf_s("%d", &size);
for (c = 0; c < size; c++)
scanf_s("%d", &array[c]);
location = find_maximum(array, size);
maximum = found;
printf("Maximum elements = %d ", maximum);
return 0;
}
int find_maximum(int a[], int n) {
int c, index = 0,count =1,tempCount=1;
for (c = 1; c < n; c++)
if (a[c] > a[index])
count +=1;
else
{
if (count > tempCount)
{
tempCount=count;
}
}
return tempCount;
}
The variables maximum and found are not initialized and are used nowhere except this statement that does not make sense
maximum = found;
You are storing the length of the maximum subsequence in the variable location
location = find_maximum(array, size);
It is the variable value which you need to output.
The function find_maximum also does not make sense. For example you are comparing elements of the array with the same element at position 0.
int c, index = 0,count =1,tempCount=1;
^^^^^^^^^
for (c = 1; c < n; c++)
if (a[c] > a[index])
count +=1;
//…
The function can be declared and implemented as it is shown in the demonstrative program below.
#include <stdio.h>
size_t max_ascending_seq( const int a[], size_t n )
{
size_t max_n = 0;
for ( size_t i = 0; i < n; )
{
size_t current_n = 1;
while ( ++i < n && a[i-1] < a[i] ) ++current_n;
if ( max_n < current_n ) max_n = current_n;
}
return max_n;
}
int main(void)
{
int a[] = { 1, 2, 3, 4, 5, 2, 7, 6, 7, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t max_n = max_ascending_seq( a, N );
printf( "%zu\n", max_n );
return 0;
}
The program output is
5
A more generic function can be written the following way.
#include <stdio.h>
size_t max_ascending_seq( const int a[], size_t n, int predicate( int, int ) )
{
size_t max_n = 0;
for ( size_t i = 0; i < n; )
{
size_t current_n = 1;
while ( ++i < n && predicate( a[i-1], a[i] ) ) ++current_n;
if ( max_n < current_n ) max_n = current_n;
}
return max_n;
}
int less_than( int x, int y )
{
return x < y;
}
int greater_than( int x, int y )
{
return y < x;
}
int main(void)
{
int a[] = { 1, 2, 3, 4, 5, 2, 7, 6, 7, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t max_n = max_ascending_seq( a, N, less_than );
printf( "%zu\n", max_n );
max_n = max_ascending_seq( a, N, greater_than );
printf( "%zu\n", max_n );
return 0;
}
The program output is
5
2

Combine or merge 2 array with loop or function

I'm new to the C world. I'm using Visual 2010. I need to create an array from 2 other arrays, or a function to merge them; I come from PHP so I'm sorry if this is stupid. I tested some loop without success..
a real example could be helpful:
int arrayA[5] = {3,2,1,4,5}
int arrayB[5] = {6,3,1,2,9}
And the printed expected output of the third arrayC should be :
arrayC {
[3][6]
[2][3]
[2][1]
[4][2]
[5][9]
}
A straightforward approach can look the following way
#include <stdio.h>
#define N 5
int main( void )
{
int a[N] = { 3, 2, 2, 4, 5 };
int b[N] = { 6, 3, 1, 2, 9 };
int c[N][2];
for ( size_t i = 0; i < N; i++ )
{
c[i][0] = a[i]; c[i][1] = b[i];
}
for ( size_t i = 0; i < N; i++ ) printf( "%d, %d\n", c[i][0], c[i][1] );
return 0;
}
The program output is
3, 6
2, 3
2, 1
4, 2
5, 9
If you want to write a function that will merge arrays of any size then it can look like
#include <stdio.h>
#include <stdlib.h>
#define N 5
int ** merge( int *a, int *b, size_t n )
{
int **c = malloc( n * sizeof( int * ) );
if ( c != NULL )
{
size_t i = 0;
for ( ; i < n && ( c[i] = malloc( 2 * sizeof( int ) ) ); i++ )
{
c[i][0] = a[i]; c[i][1] = b[i];
}
if ( i != n )
{
while ( i-- ) free( c[i] );
free( c );
c = NULL;
}
}
return c;
}
int main( void )
{
int a[N] = { 3, 2, 2, 4, 5 };
int b[N] = { 6, 3, 1, 2, 9 };
int **c;
c = merge( a, b, N );
if ( c != NULL )
{
for ( size_t i = 0; i < N; i++ ) printf( "%d, %d\n", c[i][0], c[i][1] );
for ( size_t i = 0; i < N; i++ ) free( c[i] );
free( c );
}
return 0;
}
The program output will be the same as shown above.
Really It's unclear to all. I had understood like this.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int arrayA[5] = {3,2,2,4,5};
int arrayB[5] = {6,3,1,2,9};
int arrayC[5][5];
int i,j;
for(i=0; i<5; i++)
{
int a = arrayA[i]*10 + arrayB[i];
arrayC[i][0] = a;
}
for(i=0; i<5; i++)
{
printf("%d ", arrayC[i][0]);
printf("\n");
}
return 0;
}
After your comment:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int arrayA[5] = {3,2,2,4,5};
int arrayB[5] = {6,3,1,2,9};
int arrayC[5];
int i,j;
for(i=0; i<5; i++)
{
arrayC[arrayA[i]] = arrayB[i];
}
for(i=0; i<5; i++)
{
printf("[%d %d]",arrayA[i], arrayC[arrayA[i]]);
printf("\n");
}
return 0;
}
Please edit your question and specify it (you can read https://stackoverflow.com/help/how-to-ask ).
If you know size of the array, you can create 2D array in that way:
int array[2][5] = { {2, 3, 4, 5}, {6, 3, 1, 2, 9} };
Also take a look to malloc function. This is how to create dynamic 2D array
# create array of two pointers
int **tab = (int**) malloc(sizeof(int*) * 2);
# create pointer to array
tab[0] = (int*) malloc(sizeof(int) * 5);
tab[1] = (int*) malloc(sizeof(int) * 5);
tab[0][0] = 3;
tab[0][1] = 2;
// ...
tab[1][0] = 6;
tab[1][1] = 3;
tab[1][2] = 1;
// ...
// remember to call free
free(tab[0]);
free(tab[1]);
free(tab);
Of course you should use for loop. I show you only how to create array. Please also take a look at this thread Using malloc for allocation of multi-dimensional arrays with different row lengths
you can do this in c++ if i get what you mean
#include <iostream>
using namespace std;
int main()
{
int arrayA[5] = {3,2,2,4,5};
int arrayB[5] = {6,3,1,2,9};
int arrayC[10];
int a=0;
int b=0;
bool use_a= true;
bool use_b = false;
for ( int i =0 ; i <10 ; i++ )
{
if(use_a){
arrayC[i]=arrayA[a];
use_a=false;
use_b= true;
a++;
}else if(use_b){
arrayC[i]= arrayB[b];
use_b=false;
use_a= true;
b++;
}
}
for(int i =0 ; i <10 ; i++)
cout<<arrayC[i];
return 0;
}

Resources