I am attempting to make a program that takes an array and reverts it backwards however the program must do this to the array in groups of three. So if the user enters the numbers 1, 2, 3, 4, 5, 6 into the array the program will then output: 3, 2, 1, 6, 5, 4.
When I run the current program I get: 3 2 1 4 5 6. If anyone could help me figure out why that would be great as I am a little confused.
Here is my code:
int * numbersProcessFour(int *x, int size)
{
int i = 0, three = 3, six = 6, nine = 9;
if (size < 4)
{
for (i; i < three; i++)
{
reverse_array(x, three);
printf("%d ", x[i]);
}
}else if (size > 3 && size < 7)
{
for (i; i < three; i++)
{
reverse_array(x, three);
printf("%d ", x[i]);
}
for (i; i < 6; i++)
{
reverse_array(x, three);
printf("%d ", x[i]);
}
}
else if (size > 6 && size < 10)
{
for (i; i < three; i++)
{
reverse_array(x, three);
printf("%d ", x[i]);
}
for (i; i < 6; i++)
{
reverse_array(x, three);
printf("%d ", x[i]);
}
for (i; i < 9; i++)
{
reverse_array(x, three);
printf("%d ", x[i]);
}
}
}
void reverse_array(int *x, int length)
{
int i, temp;
for (i = 0; i<length / 2; i++)
{
temp = x[i];
x[i] = x[length - i - 1];
x[length - i - 1] = temp;
}
}
Continuing from your comment to fluter's answer, you may be over thinking it a bit. In order to swap the 1st and 3rd element in each 3-element partition of an array, you simply need to step though the array 3-elements at a time. You need to decide how you will handle any final partial partition, but since your goal is to swap the 1st and 3rd, there is no 3rd in anything less than a full partition, so the logical choice is to ignore any final partial partition.
A variant of what you and fluter have done incorporating a swap would be:
/* reverse 1st and 3rd element in each group of 3 */
void rev3 (int *a, size_t sz)
{
if (sz < 3) return;
size_t i;
for (i = 0; i < sz; i += 3) {
if (sz - i < 3) break;
swap (&a[i], &a[i+2]);
}
}
You can put it together with:
#include <stdio.h>
void rev3 (int *a, size_t sz);
void swap (int *a, int *b);
int main (void) {
int a[] = {1,2,3,4,5,6,7,8,9};
size_t i;
rev3 (a, sizeof a/sizeof *a);
for (i = 0; i < sizeof a/sizeof *a; i++) printf (" %2d", a[i]);
putchar ('\n');
return 0;
}
void swap (int *a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}
Example Use
When compiled and run it will give you the swap (reversal) of the 1st and 3rd elements throughout the array that you specify in your problem.
$ ./bin/revarr3
3 2 1 6 5 4 9 8 7
There is no difference whether you use a separate swap or whether you include that operation in your reversal function. There is also no need to incur the additional overheard of calling a recursive function when a procedural approach will work. Look over all the answers and compare/contrast the differing ways to accomplish your goal.
You have branches for each multiple of 3, that is inefficient. One way to solve it is you can take the array as a split by 3 smaller arrays, and reverse on them. Also, reversing an array of 3 elements is the same as swap the 1st and the 3rd element.
int i;
int temp;
for (i = 0; i < count; i += 3) {
if (i+2 >= count)
break;
temp = arr[i];
arr[i] = arr[i+2];
arr[i+2] = temp;
}
A generalized version of numberProcessFour might look like this.
int reverse_array_mod(int *input, size_t size, int mod)
{
int i, smod;
/* Error: return modulus if size cannot be divided by mod */
if(size%mod)
return size%mod;
smod = size/mod;
for(i=0; i<smod; i++)
reverse_array(input+i*mod, mod);
/* return 0 on success */
return 0;
}
Test
int main(int argc, char **argv)
{
int a[] = {0, 1, 2, 3, 4, 5};
int i, err, mod;
for(mod=1; mod<5; mod++) {
err = reverse_array_mod(a, 6, mod);
if(err) {
fprintf(stderr, "Error %d, modulus %d invalid\n", err, mod);
return err;
}
for(i=0; i<6; i++)
printf("%d\n", a[i]);
printf("\n");
}
return 0;
}
Result:
0
1
2
3
4
5
1
0
3
2
5
4
3
0
1
4
5
2
Error 2, modulus 4 invalid
try this
int *numbersProcessFour(int *x, int size) {
int i;
for(i = 0; i + 3 < size; i += 3){
reverse_array(x + i, 3);
}
if(size - i > 1)
reverse_array(x + i, size - i);
return x;
}
Related
I have coding problem to write concentric square matrix (biggest number is in the middle) For example user needs to write an matrix For example:
5 5 5 5 5
5 6 6 6 5
5 6 7 6 5
5 6 6 6 5
5 5 5 5 5
My program has to output "Yes" because this is, by my program's rules, a concentric square matrix.
5 5 5 5 5
5 6 6 6 5
5 6 7 8 5
5 6 6 6 5
5 5 5 5 5
This is not a concentric square matrix because 8 is in 4th column and 3rd row.
This is my code:
#include <stdio.h>
int main() {
int mat[100][100];
int i,j;
int n;
scanf("%d",&n);
printf("Unesite matricu; ");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&mat[i][j]);
}
}
}
I don't know how to do the rest of it so if someone can help me, I would be happy :))
Comment::
I forgot to say that only odd numbers can be the dimension of the matrix (1,3,11,27). The only final output of the program has to be "YES (if the matrix is a concentric square matrix) or "NO" (if it's not). I know how to make a concentric square matrix when the user inputs a number (for example, 4) and the matrix has 2*n-1 dimensions. And through the loops, the program automatically makes the matrix (if you know what I mean). But for my matrix, the user has to input all the elements of the matrix and the program has to check if the matrix is concentric or not.
Would you please try the following:
#include <stdio.h>
int main() {
int mat[100][100];
int ii[] = {0, 1, 0, -1}; // incremental numbers of i
int jj[] = {1, 0, -1, 0}; // incremental numbers of j
int i, j;
int n;
int u, v, w; // variables to walk on edges
int val; // value of the element
int prev; // previous value in one outer edge
int length; // length of the edge
// read matrix size and values
printf("Enter the number:\n");
scanf("%d", &n);
printf("Enter the matrix:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
scanf("%d", &mat[i][j]);
}
}
// loop on the edges
for (u = 0; u < n / 2; u++) { // from outmost edge to inner
i = u; j = u; // index of the north west corner
val = mat[u][u]; // initial value to compare
for (v = 0; v < 4; v++) { // four sides
length = n - u * 2 - 1; // length of the edge
for (w = 0; w < length; w++) {
i += ii[v]; // one step ahead on the edge
j += jj[v]; // same as above
if (mat[i][j] != val || (u > 0 && mat[i][j] <= prev)) {
// if u == 0, skip the comparison with prev
printf("No at [%d][%d] (val=%d)\n", i, j, mat[i][j]);
return 1;
}
}
}
prev = mat[i][j];
}
// finally examine the center value (if n is odd number)
if (n % 2) {
if (mat[u][u] <= prev) {
printf("No at [%d][%d] (val=%d)\n", u, u, mat[u][u]);
return 1;
}
}
printf("Yes\n");
return 0;
}
The basic concept is to generate a series of indexes of the edge
such as:
[0, 1], [0, 2], [0, 3], [0, 4],
[1, 4], [2, 4], [3, 4], [4, 4],
[4, 3], [4, 2], [4, 1], [4, 0],
[3, 0], [2, 0], [1, 0], [0, 0]
by using the variables i, j and the arrays ii[], jj[].
The example above is the indexes for the outermost edge and go into
the inner edge in the next iteration. Then the values of the index
is compared with the other value in the same edge and the previous
value in the outer edge.
[Edit]
Here is an alternative which does not use an array other than mat[100][100]:
#include <stdio.h>
int main() {
int mat[100][100];
int i, j;
int ii, jj; // incremental values for i and j
int n;
int u, v, w; // variables to walk on edges
int val; // value of the element
int prev; // previous value in one outer edge
int length; // length of the edge
// read matrix size and values
printf("Enter the number:\n");
scanf("%d", &n);
printf("Enter the matrix:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
scanf("%d", &mat[i][j]);
}
}
// loop on the edges
for (u = 0; u < n / 2; u++) { // from outmost edge to inner
i = u; j = u; // index of the north west corner
val = mat[u][u]; // initial value to compare
for (v = 0; v < 4; v++) { // four sides
ii = (v & 1) * ((v & 1) - (v & 2));
// assigned to {0, 1, 0, -1} in order
jj = ((v + 1) & 1) * (((v + 1) & 1) - ((v + 1) & 2));
// assigned to {1, 0, -1, 0} in order
length = n - u * 2 - 1; // length of the edge
for (w = 0; w < length; w++) {
i += ii; // one step ahead on the edge
j += jj; // same as above
if (mat[i][j] != val || (u > 0 && mat[i][j] <= prev)) {
// if u == 0, skip the comparison with prev
printf("No at [%d][%d] (val=%d)\n", i, j, mat[i][j]);
return 1;
}
}
}
prev = mat[i][j];
}
// finally examine the center value (if n is odd number)
if (n % 2) {
if (mat[u][u] <= prev) {
printf("No at [%d][%d] (val=%d)\n", u, u, mat[u][u]);
return 1;
}
}
printf("Yes\n");
return 0;
}
I created an answer using more functions than just main(). It is more verbose than what is required for your homework — it prints out the matrix it reads and diagnoses the first problem it comes across. It works with both positive and negative numbers, and with matrices with odd or even numbers of elements.
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
enum { MAT_SIZE = 100 };
static int err_error(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
exit(EXIT_FAILURE);
}
static int err_shell(int r, int c, int a_val, int e_val)
{
printf("Element M[%d][%d] = %d vs expected value %d\n", r, c, a_val, e_val);
return 0;
}
static int check_shell(int shell, int n, int matrix[MAT_SIZE][MAT_SIZE])
{
int lb = shell;
int ub = n - shell - 1;
int val = matrix[lb][lb];
/* Check the horizontals */
for (int c = lb; c <= ub; c++)
{
if (matrix[lb][c] != val)
return err_shell(lb, c, matrix[lb][c], val);
if (matrix[ub][c] != val)
return err_shell(ub, c, matrix[ub][c], val);
}
/* Check the verticals */
for (int r = lb; r <= ub; r++)
{
if (matrix[r][lb] != val)
return err_shell(r, lb, matrix[r][lb], val);
if (matrix[r][ub] != val)
return err_shell(r, ub, matrix[r][ub], val);
}
return 1;
}
static int check_matrix(int n, int matrix[MAT_SIZE][MAT_SIZE])
{
for (int i = 0; i <= n / 2; i++)
{
if (check_shell(i, n, matrix) == 0)
return 0;
}
for (int i = 0; i < (n - 1) / 2; i++)
{
if (matrix[i][i] >= matrix[i+1][i+1])
{
printf("Shell %d has value %d but inner shell %d has value %d\n",
i, matrix[i][i], i+1, matrix[i+1][i+1]);
return 0;
}
}
return 1;
}
static int read_size(void)
{
int n;
if (scanf("%d", &n) != 1)
err_error("failed to read an integer\n");
if (n <= 0 || n > MAT_SIZE)
err_error("matrix size %d is not in the range 1..%d\n", n, MAT_SIZE);
return n;
}
static void read_matrix(int n, int matrix[n][n])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (scanf("%d", &matrix[i][j]) != 1)
err_error("failed to read M[%d][%d]\n", i, j);
}
}
}
static int max_field_width(int n, int matrix[MAT_SIZE][MAT_SIZE])
{
int min_val = matrix[0][0];
int max_val = matrix[0][0];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (matrix[i][j] < min_val)
min_val = matrix[i][j];
if (matrix[i][j] > max_val)
max_val = matrix[i][j];
}
}
int fld_width = snprintf(0, 0, "%d", max_val);
if (min_val < 0)
{
int min_width = snprintf(0, 0, "%d", min_val);
if (min_width > fld_width)
fld_width = min_width;
}
return fld_width;
}
static void print_matrix(const char *tag, int n, int matrix[MAT_SIZE][MAT_SIZE])
{
printf("%s (%d):\n", tag, n);
int w = max_field_width(n, matrix) + 1;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
printf("%*d", w, matrix[i][j]);
}
putchar('\n');
}
}
int main(void)
{
int matrix[MAT_SIZE][MAT_SIZE];
int n = read_size();
read_matrix(n, matrix);
print_matrix("Input", n, matrix);
if (check_matrix(n, matrix))
printf("YES: Matrix is a valid concentric matrix\n");
else
printf("NO: Matrix is not a valid concentric matrix\n");
return 0;
}
One detail is that this code can be made to use a VLA (variable-length array) by simply replacing MAT_SIZE by n in each function definition and modifying main() to read:
static int check_shell(int shell, int n, int matrix[n][n]) { … }
static int check_matrix(int n, int matrix[n][n]) { … }
static void read_matrix(int n, int matrix[n][n]) { … }
static int max_field_width(int n, int matrix[n][n]) { … }
static void print_matrix(const char *tag, int n, int matrix[n][n]) { … }
int main(void)
{
int n = read_size();
int matrix[n][n];
read_matrix(n, matrix);
print_matrix("Input", n, matrix);
if (check_matrix(n, matrix))
printf("YES: Matrix is a valid concentric matrix\n");
else
printf("NO: Matrix is not a valid concentric matrix\n");
return 0;
}
This reads the matrix size before allocating the matrix, instead of allocating a fixed size matrix first.
The read_size() function enables this change — that input must be done separately from the main matrix scanning code.
How to separate the even position number of an array from the odd position number in C.
Example
int arr[]= {2,3,4,5,6,7,8,9,1};
int odd[]= {2,4,6,8,1};
int even[] = {3,5,7,9};
Use % to get the remainder. If the remainder is nonzero, then the index is odd, otherwise even. But index starts from 0 and not 1, thus the first element's index is 0 and is even. if you want to sort according to that (seems to be you do), add 1 to index.
#include <stdio.h>
int main() {
int arr[] = {2, 3, 4, 5, 6, 7, 8, 9, 1}; // our array
const size_t max_size = sizeof(arr) / sizeof(arr[0]);
int odd[max_size];
size_t odd_cnt = 0;
int even[max_size];
size_t even_cnt = 0;
for (size_t i = 0; i != max_size; ++i) {
if ((i + 1) % 2) { // if (i + 1) % 2 is nonzero, i + 1 is odd
odd[odd_cnt++] = arr[i];
} else {
even[even_cnt++] = arr[i];
}
}
for (size_t i = 0; i != odd_cnt; ++i) {
printf("%d ", odd[i]);
}
printf("\n");
for (size_t i = 0; i != even_cnt; ++i) {
printf("%d ", even[i]);
}
printf("\n");
return 0;
}
I have learnt C language at school but I'm not good at it... And when I was trying to implement this algorithm using C language:
ReverseArray(int A[], int i, int j) {
Input: Array A, nonnegative integer indices i and j
Output: The reversal of the elements in A starting at index i and ending at j
if i < j then
swap A[i] and A[j]
ReverseArray(A, i+1, j-1)
}
I managed to code this:
int *reverseArray(int A[], int i, int j) {
int *R = NULL;
if(i < j) {
int temp = A[j];
A[j] = A[i];
A[i] = temp;
R = reverseArray(A, i+1, j-1);
return R;
} else {
return R;
}
}
But when I tried to print the original and reversed array in the main:
int main(void) {
int A[] = {1, 3, 5, 6, 8, 3, 4, 2};
int *r = reverseArray(A, 0, 7);
//This prints out the reversed array, when I intended to print the original
for (size_t i = 0; i < 8; i++) {
printf("%d ", A[i]);
}
printf("\n");
/* This was intended to print the reversed array but doesn't work
for (size_t i = 0; i < 8; i++) {
printf("%d ", r[i]);
}
*/
return 0;
}
Could anyone please explain why the commented out for loop doesn't work? And why the first for loop prints out the reversed array...
Is there any other way to get the result of reverseArray() without using *r?
I tried to malloc *r just in case that was the problem, but it still didn't work.
Thank you.
Just don't return anything. You make a reversion in place, so the resulting array is the same as the array to be reversed, and the caller knows it already.
You need to print the contents of A before you call reverseArray, not after. The reason is that you are reversing the bytes in place so the array A itself is changed by calling reverseArray.
A try from your code base and the problem description
If allowed to rewrite the Array in place, then it will work
#include<stdio.h>
void reverseArray(int A[], int i, int j) {
//int *R = NULL;
if(i < j) {
int temp = A[j];
A[j] = A[i];
A[i] = temp;
reverseArray(A, i+1, j-1);
}
}
int main(void) {
int A[] = {1, 3, 5, 6, 8, 3, 4, 2};
//This prints out original array
for (size_t i = 0; i < 8; i++) {
printf("%d ", A[i]);
}
printf("\n");
reverseArray(A, 0, 7);
// print the reversed array
for (size_t i = 0; i < 8; i++) {
printf("%d ", A[i]);
}
return 0;
}
It will Output:
1 3 5 6 8 3 4 2
2 4 3 8 6 5 3 1
R is always assigned to NULL, and A is not a pointer, then you are editing the real data of the array.
if you want to reverse and create a new array, you must do something like that :
int *reverseArray(int array[], int arraySize) {
int *reversedArray = malloc(sizeof(int) * arraySize);
for ( int i = 0 ; i < arraySize ; ++i ) {
reversedArray[i] = array[arraySize - i - 1];
}
return reversedArray;
}
You can also do it in recursive way :
int *reverseArray(int inputArray[], int arrayLength ) {
int *_reverseArray (int inputArray[], int arrayLength, int *outputArray, int actual) {
if (outputArray == NULL) {
outputArray = malloc(sizeof(int) * arrayLength);
}
if (actual < arrayLength) {
outputArray[actual] = inputArray[arrayLength - actual - 1];
return _reverseArray(inputArray, arrayLength, outputArray, ++actual);
}
return outputArray;
}
return _reverseArray(inputArray, arrayLength, NULL, 0);
}
If you want to edit the original array :
void reverseArray(int array[], int arraySize)
{
for ( int i = 0 ; i < arraySize / 2 ; ++i ) {
array[i] ^= array[arraySize - i - 1];
array[arraySize - i - 1] ^= array[i];
array[i] ^= array[arraySize - i - 1];
}
}
I am trying to read list of numbers from txt file and then sort them with Bucket sort.
so here is my code:
void bucketSort(int array[],int *n)
{
int i, j;
int count[*n];
for (i = 0; i < *n; i++)
count[i] = 0;
for (i = 0; i < *n; i++)
(count[array[i]])++;
for (i = 0, j = 0; i < *n; i++)
for(; count[i] > 0; (count[i])--)
array[j++] = i;
}
int main(int brArg,char *arg[])
{
FILE *ulaz;
ulaz = fopen(arg[1], "r");
int array[100];
int i=0,j,k,n;
while(fscanf(ulaz, "%d", &array[i])!=EOF)i++;
fclose(ulaz);
n=i;
for (j = 0; j<i; j++)
{
printf("Broj: %d\n", array[j]);
}
BucketSort(array,&n);
for (k = 0; k<i; k++)
printf("%d \n", array[i]);
return 0;
}
There are no errors in code,but when i call my function instead of sorted array i get array length random numbers(example: 2 3 5 4,after sorting i get 124520 124520 124520 124520 or some other random number) since i am a beginner,could someone help me with my code and what i did wrong? (sorry for bad english)
As Cool Guy correctly pointed out you have issues with memory access but on top of it the code does not sort anything. First you should read how Bucket Sort actually works.
In general:
You divide the input data among buckets by some criteria that guarantees that the buckets will not mess up the input order
Sort each bucket either using some other sorting method or recursively with bucket sort
Concatenate the sorted data (this is why the first point has the restriction of not messing up the input order)
Here is an example of your original code, I tried to adjust it as little as possible you it is easier for you to understand. This code divides a predefined input array among 3 buckets by range:
[-infinity][-1] -> first bucket
[0;10] -> second bucket
[11;infinity] -> third bucket
then performs Quicksort on each bucket and concatenates the result. I hope this helps to understand how this algorithm works.
#include <stdio.h>
#include <stdlib.h>
struct bucket
{
int count;
int* values;
};
int compareIntegers(const void* first, const void* second)
{
int a = *((int*)first), b = *((int*)second);
if (a == b)
{
return 0;
}
else if (a < b)
{
return -1;
}
else
{
return 1;
}
}
void bucketSort(int array[],int n)
{
struct bucket buckets[3];
int i, j, k;
for (i = 0; i < 3; i++)
{
buckets[i].count = 0;
buckets[i].values = (int*)malloc(sizeof(int) * n);
}
// Divide the unsorted elements among 3 buckets
// < 0 : first
// 0 - 10 : second
// > 10 : third
for (i = 0; i < n; i++)
{
if (array[i] < 0)
{
buckets[0].values[buckets[0].count++] = array[i];
}
else if (array[i] > 10)
{
buckets[2].values[buckets[2].count++] = array[i];
}
else
{
buckets[1].values[buckets[1].count++] = array[i];
}
}
for (k = 0, i = 0; i < 3; i++)
{
// Use Quicksort to sort each bucket individually
qsort(buckets[i].values, buckets[i].count, sizeof(int), &compareIntegers);
for (j = 0; j < buckets[i].count; j++)
{
array[k + j] = buckets[i].values[j];
}
k += buckets[i].count;
free(buckets[i].values);
}
}
int main(int brArg,char *arg[]) {
int array[100] = { -5, -9, 1000, 1, -10, 0, 2, 3, 5, 4, 1234, 7 };
int i = 12,j,k,n;
n=i;
for (j = 0; j<i; j++)
{
printf("Broj: %d\n", array[j]);
}
bucketSort(array, n);
for (k = 0; k<i; k++)
printf("%d \n", array[k]);
return 0;
}
Your code exhibits Undefined Behavior as you try to write into memory location which are not owned by your program.
for (i = 0; i < *n; i++)
(count[array[i]])++;
The above loop is causing the problem. You say that i is 4 which means that *n is also 4 and array contains 2 3 5 4. In the above code,count is an array of *n elements(in this case 4 elements) and the valid indices for the array are count[0],count[1],count[2] and count[3]. Doing
count[array[i]]
when i is zero is okay as it is same as count[2]. This is the same when i is 1 as it would be count[3] . After that ,when i is 4 and 5,count[4] and count[5] are wrong as you try to write to a invalid memory location.
Also,your code dosen't sort the values.
I have those functions which are making intersection/union but just of two arrays.
I need too improve them to work with n-arrays: arr = {{1,2,3},{1,5,6},...,{1,9}}.
The arrays are sorted , and their elements are unique among them.
Example (intersection):
Input: {{1,2,3,4},{2,5,4},{4,7,8}}
Output: {4}
arr1[],arr2 - arrays
m,n - length of the arrays
Intersection function:
int printIntersection(int arr1[], int arr2[], int m, int n)
{
int i = 0, j = 0;
while(i < m && j < n)
{
if(arr1[i] < arr2[j])
i++;
else if(arr2[j] < arr1[i])
j++;
else /* if arr1[i] == arr2[j] */
{
printf(" %d ", arr2[j++]);
i++;
}
}
}
and union function:
int printUnion(int arr1[], int arr2[], int m, int n)
{
int i = 0, j = 0;
while(i < m && j < n)
{
if(arr1[i] < arr2[j])
printf(" %d ", arr1[i++]);
else if(arr2[j] < arr1[i])
printf(" %d ", arr2[j++]);
else
{
printf(" %d ", arr2[j++]);
i++;
}
}
while(i < m)
printf(" %d ", arr1[i++]);
while(j < n)
printf(" %d ", arr2[j++]);
}
union(a, b, c) = union(union(a, b), c), and the same goes for intersection(). I.e. you can decompose the union or intersection of n sets into n unions or intersections of 2 sets (as NuclearGhost points out in a comment on the question). What you need to do is change your current functions so that they build up a resulting set, instead of immediately printing the result. You can then make a separate function that prints a set.
For efficiency, you want to take the union or intersection of sets that are roughly of equal size. So a divide-and-conquer approach should work alright, assuming that all input sets are likely to be of roughly equal size.
void intersection(int arr1[], int arr2[], int m, int n, int *out)
{
int i = 0, j = 0;
while(i < m && j < n)
{
if(arr1[i] < arr2[j])
i++;
else if(arr2[j] < arr1[i])
j++;
else /* if arr1[i] == arr2[j] */
{
*out++ = arr2[j++];
i++;
}
}
}
void multi_intersection(int n, int **arrays, int *lengths, int *out) {
if (n == 2) {
intersection(arrays[0], arrays[1], lengths[0], lengths[1], out);
} else if (n == 1) {
memcpy(out, arrays[0], lengths[0] * sizeof (int));
} else {
/* Allocate buffers large enough */
int *buf[2];
int len[2] = { INT_MAX, INT_MAX };
int i;
for (i = 0; i < n; ++i) {
int which = i < n / 2;
if (lengths[i] < len[which]) len[which] = lengths[i];
}
buf[0] = malloc(len[0] * sizeof (int));
buf[1] = malloc(len[1] * sizeof (int));
/* Recurse to process child subproblems */
multi_intersection(n / 2, arrays, lengths, buf[0]);
multi_intersection(n - n / 2, arrays + n / 2, lengths + n / 2, buf[1]);
/* Combine child solutions */
intersection(buf[0], buf[1], len, out);
free(buf[0]);
free(buf[1]);
}
Similar code works for multi_union(), except that the buffer lengths need to be calculated differently: the result of a union could be as large as the sum of the sizes of the inputs, rather than the minimum size of the inputs. It could probably be rewritten to do less buffer allocation. Also the recursion could be rewritten to use iteration, the same way mergesort can be written to use iteration, but the current recursive approach uses only O(log n) additional stack space anyway.
presume the max value in arrays is less than K. N is the number of arrays
int Result[K] = {0};
intersection function
//input array1
int index = 0;
for(; index < arrary1len;index++)
{
Result[array1]++;
}
.....
for(index = 0; index < K; index++)
{
if(Result[index] == N)
printf("%d",index);
}