To find common elements( matching elements) between the arrays - c

Consider if I am having an input, where number of arrays to have as input is not fixed and the number of elements in each array is also not fixed. So each time my input varies,
Example 1: 1st input
1st array= [2,3,4]
2nd array =[6,7,8,9]
3rd array=[5,3,12]
Example 2: 2nd input
1st array= [6,3,4,8]
2nd array =[6,7,4,9]
3rd array=[1,2,12]
4th array= [20,21,22,23,25]
The solution required is, 1st array is considered as a reference array, the next set of arrays are to be checked with respect to the first array(reference), the requirement is second array should not have a common element with respect to first array and it goes on for next check third array should not have a common element with first array.
from 1st Example
1st array= [2,3,4] -- reference array
1st array= [2,3,4] is compared to 2nd array =[6,7,8,9]
1st array= [2,3,4] is compared to 3rd array=[5,3,12]
solution needed:
+ print 1st array( reference array)
+ if no common elements found between 1st array and 2nd array, from ex. no common elements found, so print out the 2nd array.
+ same for 3rd array, from ex. there is common element(3 is present in both first and third array), so dont print.
I ave tried this by storing the input in 2-dimensional array, but i messed up .
Please guide me for computing this with your algorithm/code.

Notice how i had to create an array to contain the length of the various arrays, and a parameter to tell how long that array is.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void print_array(int *a, int size) {
int i;
for (i = 0; i<size; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
bool is_in(int *a, int size, int elem) {
int i;
for (i=0; i<size; i++) {
if (a[i] == elem) {
return true;
}
}
return false;
}
void f(int **a, int a_siz, int* sizes) {
print_array(a[0],sizes[0]);
for (int i=1; i< a_siz; i++) {
bool common_element = false;
for (int k=0; k< sizes[i]; k++) {
if (is_in(a[0],sizes[0],a[i][k])) {
common_element = true;
break;
}
}
if (! common_element) {
print_array(a[i],sizes[i]);
}
}
}
int main() {
int s = 3;
int sizes[] = {3,4,3};
int **a = malloc(sizeof(int*)*3);
for (int i=0; i<s; i++) {
a[i] = malloc(sizeof(int*)*sizes[i]);
}
a[0][0] = 2;
a[0][1] = 3;
a[0][2] = 4;
a[1][0] = 4;
a[1][1] = 7;
a[1][2] = 8;
a[1][3] = 9;
a[2][0] = 5;
a[2][1] = 44;
a[2][2] = 12;
f(a,s,&sizes);
}

Since the question states that the length of the array is not a constant, the idea of static 2-dimensional array might not work. You can go with creating a 2 dimensional array using DMA (malloc and calloc functions)
You can prefer a straight forward algorithm which compares each element in reference array with other arrays.

Related

Use of a function on a 2d array

I have written code which allows me to modify the elements of a 1D array within my function by passing the element of the array:
I print the original array
I pass each element of the array to the function
Within the function I add the value 50 to each element of the array
I then call the function, and print out to screen the modified element value (i.e the value of each element +50)
I have been able to do this for a 1D array, with example values in the array being (10,20,30) and the valued printed after modification being (60,70,80).
What I am hoping to do is adapt that code to work for 2D arrays, you will see my attempt at doing this below. This code focuses on the use of int, but once I understand how to achieve this I am hoping to adapt for the use of a 2D string as well.
With the code below:
My objective is
Print to screen the original 2D array
Pass each element of the 2D array to the function
Within the function add the value 50 to each element of the array
Then call the function, and print out the modified element values to the screen(expected result displayed on screen 60,61,etc,.)
So far I have been able to print the original 2D array to the screen. It is the function I think I am messing up and would appreciate any advice. Thank you.
#include <stdio.h>
#include <string.h>
#define M 4
#define N 2
int function(int **arr);
int main() {
int i, a;
int arr[N][M] = {10, 11, 12, 13, 14, 15, 16, 17};
// the int array first
for(i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
// Accessing each variable
printf("value of arr[%d] is %d\n", i, arr[i][j]);
}
}
printf("\n ***values after modification***\n");
a = function(&arr[i][0]);
// int array print results
for(int i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr %d\n", arr[i][j]);
}
}
return 0;
}
int function(int **arr) {
int i;
int j;
for(int i = 0; i < 3; i++) {
for(size_t j = 0; j < 5; j++) {
arr[i][j] = arr[i][j] + 50;
}
}
}
My apologies in advance for silly mistakes I am very new to C.
Thank you in advance.
The function int function(int **arr) does not return an int so make it void.
When you call it, a = function(&arr[i][0]);, you do not use a after the assignment. I suggest that you remove a from the program completely since it's not used anywhere.
The call to the function, function(&arr[i][0]);, should simply be function(arr);
The function signature needs to include the extent of all but the outermost dimension:
void function(int arr[][M])
Inside the function, you use 3 and 5 instead of N and M. That accesses the array out of bounds.
In function, the i and j you declare at the start of the function are unused. Remove them.
arr[i][j] = arr[i][j] + 50; is better written as arr[i][j] += 50;
When initializing a multidimensional array, use braces to make it simpler to read the code:
int arr[N][M] = {{10, 11, 12, 13}, {14, 15, 16, 17}};
In main you mix int and size_t for the indexing variables. I suggest you settle for one type.
Remove unused header files (string.h)
Example:
#include <stdio.h>
#define N 2
#define M 4
void function(int arr[][M]) {
for(int i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
arr[i][j] += 50;
}
}
}
int main() {
int arr[N][M] = {{10, 11, 12, 13}, {14, 15, 16, 17}};
for(size_t i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr[%zu][%zu] is %d\n", i, j, arr[i][j]);
}
}
printf("\n ***values after modification***\n");
function(arr);
// int array print results
for(size_t i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr[%zu][%zu] is %d\n", i, j, arr[i][j]);
}
}
}
Since you print the array more than once, you could also add a function to do so to not have to repeat that code in main:
void print(int arr[][M]) {
for(size_t i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr[%zu][%zu] is %d\n", i, j, arr[i][j]);
}
}
}
Two-Dimensional arrays in C (and C++) are actually one-dimensional arrays whose elements are one-dimensional arrays. The indexing operator [] has left-to-right semantics, so for a type arr[N][M] the first index (with N elements) is evaluated first. The resulting expression, e.g. arr[0], the first element in arr, is a one-dimensional array with M elements. Of course that array can be indexed again , e.g. arr[0][1], resulting in the second int in the first sub-array.
One of the quirks in the C language is that if you use an array as a function argument, what the function sees is a pointer to the first element. An array used as an argument "decays" or, as the standard says, is "adjusted" that way. This is no different for two-dimensional arrays, except that the elements of a two-dimensional array are themselves arrays. Therefore, what the receiving function gets is a pointer to int arr[M].
Consider: If you want to pass a simple integer array, say intArr[3], to a function, what the function sees is a pointer to the first element. Such a function declaration might look like void f(int *intPtr) and for this example is simply called with f(intArr). An alternative way to write this is void f(int intPtr[]). It means exactly the same: The parameter is a pointer to an int, not an array. It is pointing to the first — maybe even only — element in a succession of ints.
The logic with 2-dimensional arrays is exactly the same — except that the elements, as discussed, have the type "array of M ints", e.g. int subArr[M]. A pointer argument to such a type can be written in two ways, like with the simple int array: As a pointer like void f(int (*subArrPtr)[M]) or in array notation with the number of top-level elements unknown, like void f(int arr[][M]). Like with the simple int array the two parameter notations are entirely equivalent and interchangeable. Both actually declare a pointer, so (*subArrPtr)[M] is, so to speak, more to the point(er) but perhaps more obscure.
The reason for the funny parentheses in (*subArrPtr)is that we must dereference the pointer first in order to obtain the actual array, and only then index that. Without the parentheses the indexing operator [] would have precedence. You can look up precedences in this table. [] is in group 1 with the highest priority while the dereferencing operator * (not the multiplication!) is in group 2. Without the parentheses we would index first and only then dereference the array element (which must therefore be a pointer), that is, we would declare an array of pointers instead of a pointer to an array.
The two possible, interchangeable signatures for your function therefore are
void function( int (*arrArg)[M] ); // pointer notation
void function( int arrArg[][M] ); // "array" notation (but actually a pointer)
The entire program, also correcting the problems Ted mentioned, and without printing the original values (we know them, after all), is below. I have also adapted the initialization of the two-dimensional array so that the sub-arrays become visible. C is very lenient with initializing structures and arrays; it simply lets you write consecutive values and fills the elements of nested subobjects as the come. But I think showing the structure helps understanding the code and also reveals mistakes, like having the wrong number of elements in the subarrays. I have declared the function one way and defined it the other way to show that the function signatures are equivalent. I also changed the names of the defines and of the function to give them more meaning.
#include<stdio.h>
#define NUM_ELEMS_SUBARRAY 4
#define NUM_ELEMS_ARRAY 2
/// #arrArg Is a pointer to the first in a row of one-dimensional
/// arrays with NUM_ELEMS_SUBARRAY ints each.
void add50ToElems(int arrArg[][NUM_ELEMS_SUBARRAY]);
int main()
{
// Show the nested structure of the 2-dimensional array.
int arr[NUM_ELEMS_ARRAY][NUM_ELEMS_SUBARRAY] =
{
{10, 11, 12, 13},
{14, 15, 16, 17}
};
// Modify the array
add50ToElems(arr);
// print results
for (int i = 0; i < NUM_ELEMS_ARRAY; i++) {
for (int j = 0; j < NUM_ELEMS_SUBARRAY; j++)
{
printf("value of arr[%d][%d]: %d\n", i, j, arr[i][j]);
}
}
return 0;
}
// Equivalent to declaration above
void add50ToElems(int (*arrArg)[NUM_ELEMS_SUBARRAY])
{
for (int i = 0; i < NUM_ELEMS_ARRAY; i++)
{
for (size_t j = 0; j < NUM_ELEMS_SUBARRAY; j++)
{
//arrArg[i][j] = arrArg[i][j] + 50;
arrArg[i][j] += 50; // more idiomatic
}
}
}
Why is it wrong to pass a two-dimensional array to a function expecting a pointer-to-pointer? Let's consider what void f(int *p) means. It receives a pointer to an int which often is the beginning of an array, that is, of a succession of ints lying one after the other in memory. For example
void f(int *p) { for(int i=0; i<3; ++i) { printf("%d ", p[i]); }
may be called with a pointer to the first element of an array:
static int arr[3];
void g() { f(arr); }
Of course this minimal example is unsafe (how does f know there are three ints?) but it serves the purpose.
So what would void f(int **p); mean? Analogously it is a pointer, pointing to the first in a succession of pointers which are lying one after the other in memory. We see already why this will spell disaster if we pass the address of a 2-dimensional array: The objects there are not pointers, but all ints! Consider:
int arr1[2] = { 1,2 };
int arr2[2] = { 2,3 };
int arr3[2] = { 3,4 };
// This array contains addresses which point
// to the first element in each of the above arrays.
int *arrOfPtrToStartOfArrays[3] // The array of pointers
= { arr1, arr2, arr3 }; // arrays decay to pointers
int **ptrToArrOfPtrs = arrOfPtrToStartOfArrays;
void f(int **pp)
{
for(int pi=0; pi<3; pi++) // iterate the pointers in the array
{
int *p = pp[pi]; // pp element is a pointer
// iterate through the ints starting at each address
// pointed to by pp[pi]
for(int i=0; i<2; i++) // two ints in each arr
{
printf("%d ", pp[pi][i]); // show double indexing of array of pointers
// Since pp[pi] is now p, we can also say:
printf("%d\n", p[i]); // index int pointer
}
}
}
int main()
{
f(ptrToArrOfPtrs);
}
f iterates through an array of pointers. It thinks that the value at that address, and at the subsequent addresses, are pointers! That is what the declaration int **pp means.
Now if we pass the address of an array full of ints instead, f will still think that the memory there is full of pointers. An expression like int *p = pp[i]; above will read an integer number (e.g., 1) and think it is an address. p[i] in the printf call will then attempt to access the memory at address 1.
Let's end with a discussion of why the idea that one should pass a 2-dimensional array as a pointer to a pointer is so common. One reason is that while declaring a 2-dimensional array argument as void f(int **arr); is dead wrong, you can access the first (but only the first) element of it with e.g. int i = **arr. The reason this works is that the first dereferencing gives you the first sub-array, to which you can in turn apply the dereferencing operator, yielding its first element. But if you pass the array as an argument to a function it does not decay to a pointer to a pointer, but instead, as discussed, to a pointer to its first element.
The second source of confusion is that accessing elements the array-of-pointers uses the same double-indexing as accessing elements in a true two-dimensional array: pp[pi][i] vs. arr[i][j]. But the code produced by these expressions is entirely different and spells disaster if the wrong type is passed. Your compiler warns about that, by the way.

Inserting 1D array to 2D array

Can we directly insert a 1D array to a 2D array?
For example I have this code:
void insert(int[]data , int**collection)
{
collection[1] = data
}
int main()
{
int data[2]= {1,3}
int collection[2][2];
insert(data,&collection);
}
Will this work?
You cannot insert a 1D array to 2D array the way you are doing. Use memcpy to copy the elements of 1D array to 2D array, like this:
memcpy(collection[1], data, 2 * sizeof(int));
this will copy the 2 integer elements of data array to collection[1].
Besides, a couple of problems in your code. Lets discuss them:
First:
insert(data,&collection);
^
You don't need to pass the address of collection. Note that, an array, when used in an expression, will convert to pointer to its first element (there are few exceptions to this rule). That means, when you pass collection, it will convert to type int (*)[2]. Just do:
insert(data, collection);
Second:
void insert(int[]data , int**collection)
int[]data is wrong. The first parameter of insert() should be int data[2] or int data[], both are equivalent to int * data. You can use either of them.
The second argument to insert() is collection array which is a 2D array of integers. When you pass it to insert(), it will decay to pointer whose type is int (*)[2]. The type of second parameter of insert() is int ** which is not compatible with the argument that you are passing to insert() function. The second parameter of insert() function should be int collection[2][2] or int collection[][2], both are equivalent to int (*collection)[2].
Putting these altogether, you can do:
#include <stdio.h>
#include <string.h>
#define ROW 2
#define COL 2
void insert(int data[ROW], int collection[ROW][COL]) {
//for demonstration purpose, copying elements of data array
//to all elements (1D array) of collection array.
for (int i = 0; i < ROW; ++i) {
memcpy(collection[i], data, COL * sizeof(int));
}
}
int main(void) {
int data[COL] = {1, 3};
int collection[ROW][COL];
insert(data, collection);
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
printf("collection[%d][%d] : %d ", i, j, collection[i][j]);
}
printf("\n");
}
return 0;
}
Output:
# ./a.out
collection[0][0] : 1 collection[0][1] : 3
collection[1][0] : 1 collection[1][1] : 3

Removing an array (row) from a 2d array - C Programming

Lets say I have a 2d array:
int array[3][3];
with
000
111
222
and I want to remove 000.
I wrote a function:
void remove(int (*array)[3], int index, int array_length)
{
int i;
for(i = index; i < array_length - 1; i++)
{
array[i] = array[i + 1];
}
}
which receives pointer to the first element of the 2d array, index which I want to remove and a length of the array.
In the for loop, I move array at the position index to the next element.
But I receive this error message:
error: assignment to expression with array type
array[i] = array[i + 1];
Why?
How can I remove element and get the 2d array without array at the index? Should I maybe make new 2d array and return it instead of passing pointer of 2d array to the function?
You can do what you originally wanted if you use an array of structs instead of a 2D array.
The C language treats structs as value types so you can copy them with simple and safe assignment (no memcpy needed).
Here's an example with a few tweaks.
//try online here: https://rextester.com/DDHBC95444
#include <stdio.h>
//from Chromium code https://stackoverflow.com/a/1598827/7331858
#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
typedef struct row_t {
int columns[3];
} row_t;
void remove_row(row_t * const rows, const size_t row_index, const size_t row_count)
{
for (size_t i = row_index; i < row_count - 1; i++) {
rows[i] = rows[i + 1];
}
}
void print_rows(row_t const * const rows, const size_t row_count)
{
const size_t column_count = COUNT_OF(rows[0].columns);
for (size_t r = 0; r < row_count; r++) {
for (size_t c = 0; c < column_count; c++) {
printf("%02i ", rows[r].columns[c]);
}
printf("\n");
}
}
int main(void)
{
row_t rows[] = { {{0,1,2}}, {{10,11,12}}, {{20,21,22}} };
print_rows(rows, COUNT_OF(rows));
printf("\n'removing' row index 1\n");
remove_row(rows, 1, COUNT_OF(rows));
print_rows(rows, COUNT_OF(rows));
return 0;
}
outputs:
00 01 02
10 11 12
20 21 22
'removing' row index 1
00 01 02
20 21 22
20 21 22
The parameter array is declared as int (*array)[3], so its type is pointer to an array of 3 ints. The type of array[i] is array of int and an array cannot be assigned to. A function to shift the rows of your matrix can be implemented like this:
void remove(int (*array)[3], int index, int array_length)
{
int i, j;
for(i = index; i < array_length - 1; i++) {
for (j = 0; j < 3; ++j)
array[i][j] = array[i + 1][j];
}
}
Note that the function does not really remove the row, just shifts the rows up. So its name is misleading. You must create a new array and copy the old array to the new array except the indicated row to really remove a row and to change the dimensions of the array.
Edit: The name of that function should be changed because the standard library already has a function named remove.
If the array is obtained like that:
int (*array)[3] = malloc(array_length * sizeof *array);
You can shrink the array by calling the realloc:
int (*p)[3] = realloc(array, (array_length - 1) * sizeof *p);
if (p != NULL)
array = p;
int (*array)[3] -> Here, array is a pointer to 3 element integer array.
error: assignment to expression with array type
This is because an array variable is not modifiable/re-assignable like a pointer. Operations that can be performed on an lvalue of array type are: sizeof, unary & and implicit conversion to pointer type.
The error is telling you that C doesn't support array assigning. Your code tries to copy the whole line i + 1 into the line i of the matrix, but C doesn't know how to operate this.
The solution is to iterate through each element of your array, copying one by one.
void remove(int (*array)[3], int index, int array_length)
{
int i, j;
for(i = index; i < array_length - 1; i++)
{
for(j = 0; j < array_length; ++)
{
array[i][j] = array[i + 1][j];
}
}
}
The code above assumes that your matrix is always squared, but you could change its dimension inside j's for loop.

C how to move through 2 dimensional array based on address

I'm trying to figure out how to loop through a 2 dimensional array as a single dimensional array. Since a 2 dimensional array will occupy continuous memory, is there a way to address the two dimensional array as a single dimensional array by changing the index by 4 bytes. I'm assuming an integer array. Could some one provide an example? I tried the following but it doesn't work:
for (int i = 0; i < 2; i++){
for (int j = 0;j < 2; j++){
z[i][j] = count;
count++;
}
}
for (int i = 0; i < 4; i++)
printf("%d\n", z[i]);
2D arrays can be iterated through in a single loop like this:
#include <stdio.h>
int main()
{
int a[2][2], *p;
a[0][0] = 100;
a[0][1] = 200;
a[1][0] = 300;
a[1][1] = 400;
p = &a[0][0];
while(p!=&a[0][4])
printf("%d\n", *p++);
return 0;
}
Remember that an array index is just an offset from the first element of the array, so there is no real difference between a[0][3] and a[1][1] - they both refer to the same memory location.
Access 2D arrays like this
int *array; // note one level of pointer indirection
array = malloc(width * height * sizeof(int)); / allocate buffer somehow
for(y=0;y<height;y++)
for(x=0;x<width;x++)
array[y*width+x] = 0; // address the element by calculation
In three dimensions
int *array; // note one level of pointer indirection
array = malloc(width * height * depth * sizeof(int)); / allocate buffer somehow
for(z=0;z<depth;z++)
for(y=0;y<height;y++)
for(x=0;x<width;x++)
array[z*width*height + y*width+x] = 0; // address the element by calculation
Generally it's easier to use flat buffers than to mess around with C and C++ convoluted rules for multi-dimensional arrays. You can also of course
iterate through the entire array with a single index. If you want to set
up a 2D array, then cast the array to a single pointer, it behaves the
same way.
#define HEIGHT 50
#define WIDTH 90
int array2D[HEIGHT][WIDTH}:
int * array = reinterpret_cast<int *>(array2D):
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int arr[4][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}};
void my_fun(int(*a)[],int m,int n)
{
for(int i=0;i<m*n;i++)
{
printf("%d\n",(*a)[i]);
}
}
int main()
{
my_fun(arr,3,4);
return 0;
}

Creating an array of int arrays in C?

Let us say I have the following method prototype:
void mix_audio(int *vocal_data_array, int *instrumental_data_array, int *mixed_audio_array, FOURTH ARGUMENT)
{
}
How would I:
Initialize an array_of_arrays before the above argument so as to pass it as the fourth argument?
In the method, make it so that the first value of my array_of_arrays is the array called vocal_data, that the second value of my array is instrumental_data_array and the third value is mixed_audio_array.
How would I later then loop through all the values of the first array within the array_of_arrays.
I hope I'm not asking too much here. I just thought it would be simple syntax that someone could spit out pretty quickly :)
Thanks!
EDIT 1
Please note that although I've showed by my example an array_of_arrays of length 3 I'm actually looking to create something that could contain a variable length of arrays.
Simple array of arrays and a function showing how to pass it. I just added fake values to the arrays to show that something was passed to the function and that I could print it back out. The size of the array, 3, is just arbitrary and can be changed to whatever sizing you want. Each array can be of a different size (known as a jagged array). It shows your three criteria:
Initialization, Assigning values to each index of arrayOfArrays, The function demonstrates how to extract the data from the array of arrays
#include <stdio.h>
void mix_audio(int *arr[3]);
int main() {
int *arrayOfArrays[3];
int vocal[3] = {1,2,3};
int instrumental[3] = {4,5,6};
int mixed_audio[3] = {7,8,9};
arrayOfArrays[0] = vocal;
arrayOfArrays[1] = instrumental;
arrayOfArrays[2] = mixed_audio;
mix_audio(arrayOfArrays);
return(0);
}
void mix_audio(int *arr[3]) {
int i;
int *vocal = arr[0];
int *instrumental = arr[1];
int *mixed_audio = arr[2];
for (i=0; i<3; i++) {
printf("vocal = %d\n", vocal[i]);
}
for (i=0; i<3; i++) {
printf("instrumental = %d\n", instrumental[i]);
}
for (i=0; i<3; i++) {
printf("mixed_audio = %d\n", mixed_audio[i]);
}
}
From your question it sounds like you actually want a struct containing your arrays, something like:
struct AudioData {
int* vocal_data_array;
unsigned int vocal_data_length;
int* instrumental_data_array;
unsigned int instrumental_data_length;
int* mixed_audio_array;
unsigned int mixed_audio_length;
};
For the array allocation using the example of an array of integers:
int** x = malloc (sizeof (int*) * rows);
if (! x) {
// Error
}
for (int i = 0; i < rows; ++i) {
x[i] = malloc (sizeof (int) * columns);
if (! x[i]) {
// Error
}
}

Resources