Formatting arrays in corelation to ther arrays C - arrays

I am trying to make a function that is able to recognize if Winning_order arrays integers are within Order1,Order2,Order3. In Order1 the first row of Winning_order is present {1,2,3} as well as in order2. However in Order3 none of the elements correlate to the values of Winning_order so it is not a valid output.
int main(void)
{
int Order1[5] = {1,2,3}
int Order2[5] = {1,2,5,3}
int Order3[5] = {1,2,5}
int Winning_order[5][3] = {{1,2,3}, {4,5,6}, {7,8,9},{1,4,7},{2,5,8},{3,6,9},{1,5,9},{3,5,7}};
return 0;
}
Expected Output:
Order1
Order2

To expand on Jack Lilhammers's comment, you could do something like this:
#include <stdio.h>
int match_arrays(int *arr1, int *arr2, int len) {
for (int i = 0; i < len; i++) {
if (arr1[i] != arr2[i]) {
return 0;
}
}
return 1;
}
int main(void)
{
int Order1[3] = {1,2,3};
int Order2[4] = {1,2,5,3};
int Order3[3] = {1,2,5};
int Winning_order[8][3] = {{1,2,3}, {4,5,6}, {7,8,9},{1,4,7},{2,5,8},{3,6,9},{1,5,9},{3,5,7}};
for (int i = 0; i < 5; i++) {
if (match_arrays(Order1, Winning_order[i], 3)) {
printf("Order1");
}
if (match_arrays(Order2, Winning_order[i], 3)) {
printf("Order2");
}
if (match_arrays(Order3, Winning_order[i], 3)) {
printf("Order3");
}
}
return 0;
}
Be cause those are statically declared arrays, you have to use a series of if statements, or create a new array out of them, and it forces a lot to be hard coded.
EDIT: fixed include, dimensions, removed breaks, fixed function calls

Firstly, as #Jack Lilhammers pointed out, your expected output is incorrect if we can assume we understand what you are trying to accomplish: Your problem is essentially to check if an array is an element of an array-of-arrays.
This can be achieved like this:
#include <stdio.h>
int is_array_element(int rows, int columns, int arr1[rows][columns],
int arr2[columns]) {
for(int i = 0; i < rows; i++) {
for(int j = 0; j < columns; j++) {
if(arr1[i][j] != arr2[j]) {
break;
}
if(j == columns - 1) {
return 1;
}
}
}
return 0;
}
int main(void) {
/* as Order1 and Order3 have been declared as 5-arrays but are only
initialized with 3 integers, the remaining two elements are zero and
can (should) be ignored */
int Order1[5] = {1, 2, 3};
/* not clear how you wish to compare a 4-array with a 3-array and so
the code will clip the last element */
int Order2[5] = {1, 2, 5, 3};
int Order3[5] = {1, 2, 5};
int Winning_order[8][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9},
{1, 4, 7}, {2, 5, 8}, {3, 6, 9},
{1, 5, 9}, {3, 5, 7}
};
if(is_array_element(8, 3, Winning_order, Order1)) {
printf("Order1\n");
}
if(is_array_element(8, 3, Winning_order, Order2)) {
printf("Order2\n");
}
if(is_array_element(8, 3, Winning_order, Order3)) {
printf("Order3\n");
}
return 0;
}
And the output we get is:
Order1

Related

How to solve this C bitwise university problem?

Problem
Given a sequence of N integer values (N > 1). Using at most one conditional operator(or conditional operator), the program must determine whether its is true that sequence is increasing. Loops on a program can only be used to enumerate elements of a sequence.
Example
int arr[] = {10, 9, 8, 7, 6, 5}; // Decreasing sequence
int arr2[] = {1, 2, 3, 4, 5, 6}; // Increasing sequence
My solution
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*
Returns num1 if num1 < num2 otherwise num2
*/
static int CompareNums(int num1, int num2)
{
return (int)(((num1 + num2) - sqrt((num1 - num2) * (num1 - num2))) / 2);
}
static _Bool IsIncreasing(int arr[], size_t N)
{
int min = arr[0];
int res = 0;
for (size_t i = 0; i < N - 1; i++)
{
min = CompareNums(arr[i + 1], min);
/*If min equals to current processed num => it is decreasing sequence*/
res = min ^ arr[i + 1];
}
return res;
}
int main(void)
{
int arr[] = {10, 9, 8, 7, 6, 5};
int arr2[] = {1, 2, 3, 4, 5, 6};
int res = IsIncreasing(arr2, 6);
if (res == 0)
{
printf("Decreasing\n");
}
else
{
printf("Increasing\n");
}
return 0;
}
It has a problem, it's work fine with sequence from example, but doesn't work with sequence like this
//It is a complex sequence, but idk how to make my code detect this sequences.
int arr[] = {10, 11, 6, 12, 13}
Restrictions
//You can't use if inside for loop
for(int i = 0; i < N; i++)
{
//can't do this
if(bool)
{
}
//and this also
int a = a > b ? a : b
}
//And also this
while(a > b)
{
}
You need to calculate is it increasing sequence or not inside function than check for it for display right string
static _Bool IsIncreasing(int arr[], size_t N)
{
}
int main(void)
{
int res = IsIncreasing(arr, N);
if(res)
{
printf("Increasing");
}
else
{
printf("Decreasing");
}
}
So, I'm don't know how to write clean function which will calculate increasing/decreasing sequences, including errors sequences. I wan't any support or ideas or maybe ready solution how to do this.

How to transfer an array from a pointer to the main program on C

This is the program I've been trying to run...
#include <stdio.h>
#define MAX 10
int suma_arreglo(int x1[], int x2[], int y);
int array1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, array2[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int *suma;
main()
{
int cont = 0;
suma = suma_arreglo(array1, array2, MAX);
for(cont = 0; cont < MAX; cont++)
{
printf("\n%d + %d = %d", array1[cont], array2[cont], *suma++);
}
puts("");
system("pause");
}
int suma_arreglo(int x1[], int x2[], int y)
{
int cont, arraysum[y];
for(cont = 0; cont < y; cont++)
{
arraysum[cont] = x1[cont] + x2[cont];
//printf("\n%d + %d = %d", x1[cont], x2[cont], arraysum[cont]);
}
return arraysum;
}
But for some reason, it doesn't work, debugging I notice that the function and the program works fine, but the problem starts when I try to return the address arraysum to a pointer in the main program suma... in theory it should be
suma = arraysum
That way it works on the main program. In any case, I think there is still an issue on the way I try to get back the data of the array to the main program.
What do you guys think?
This works:
#include <stdio.h>
#define MAX 10
int* suma_arreglo(int x1[], int x2[], int y, int* sum_arr_ptr);
int array1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, array2[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int *suma;
int sum_array1[MAX];
main()
{
int cont = 0;
suma = suma_arreglo(array1, array2, MAX, sum_array1);
for(cont = 0; cont < MAX; cont++)
{
printf("\n%d + %d = %d", array1[cont], array2[cont], *suma++);
}
puts("");
system("pause");
}
int* suma_arreglo(int x1[], int x2[], int y, int* sum_arr_ptr)
{
for(int cont = 0; cont < y; cont++)
{
sum_arr_ptr[cont] = x1[cont] + x2[cont];
//printf("\n%d + %d = %d", x1[cont], x2[cont], arraysum[cont]);
}
return sum_arr_ptr;
}
The issues were that firstly, you gave the function a return type of int and then made it return an int*. Secondly, it was returning its own local variable. Variables created locally inside function bodies disappear after the function finishes, so you can't return those.
Here I just introduce a fourth parameter to the function, an int* pointer to an array of ints so that it has a proper result to return at the end, instead of returning something that won't exist after the function returns. Also fixed the return type from int to int*.
PS. You can use the static keyword when creating a variable inside functions to extend its lifetime beyond the function body itself. In that case, the variable is initialized only once and lives until the end of the program.

Multiply matrices in C using 3 arrays

I am trying to write an algorithm that calculates 2 nxn matrices using 3 arrays per matrix.
For example
int m1Row[] = {1,1,2,2};
int m1Column[] = {1,2,1,2};
int m1Value[] = {1,2,3,4};
int m2Row[] = {1,1,2,2};
int m2Column[] = {1,2,1,2};
int m2Value[] = {4,3,2,1};
represents 2 matrices. m1Value[x] is the value of matrix 1 at row m1Row[x] and column m1Column[x].
m1:
1 2
3 4
m2:
4 3
2 1
The code I wrote somehow works for some matrices but not for every one. The problem is probably that I am missing the part where you have to add some values to each other to multiply two matrices. Here's an example from wikipedia.
Example of correctly calculated matrices (m = count of numbers not equal to zero):
int m = 4;
int n = 8;
int m1Row[] = {1, 2, 3, 3};
int m1Column[] = {1, 2, 1, 3};
int m1Value[] = {1, 2, 3, 4};
int m2Row[] = {1, 2, 3, 3};
int m2Column[] = {3, 2, 1, 2};
int m2Value[] = {7, 3, 1, 2};
I already thought about this problem for hours and tried some other for-loops and everything but it just made it worse and no value was correct or it calculated way too many values.
I hope somebody can help me get this code working so that the result matrix is calculated correctly.
My code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
//************************
int m = 4;
int n = 8;
int m1Row[] = {1, 2, 3, 3};
int m1Column[] = {1, 2, 1, 3};
int m1Value[] = {1, 2, 3, 4};
int m2Row[] = {1, 2, 3, 3};
int m2Column[] = {3, 2, 1, 2};
int m2Value[] = {7, 3, 1, 2};
//************************
int resultRow[50]; //result matrix, 50 is just a placeholder
int resultColumn[50];
int resultValue[50];
int reminder = 0;
int resultBuffer = 0;
int saveIndex = 0;
for(int i = 1; i <= n;) {
if(m1Row[reminder] == i) {
for(int j = 0; j < m; j++) {
if(m2Row[j] == m1Column[reminder]) {
resultBuffer = m2Value[j] * m1Value[reminder];
//save result
resultRow[saveIndex] = m1Row[reminder]; //save row number
resultColumn[saveIndex] = m2Column[j]; //save column number
resultValue[saveIndex] = resultBuffer; //save value
saveIndex++;
}
}
reminder++;
} else { i++; }
}
//print results
printf("resultRow[] resultColumn[] resultValue[]\n");
for(int i = 0; i <= reminder; i++) {
printf("\t%d\t\t\t\t%d\t\t\t%d\n", resultRow[i], resultColumn[i], resultValue[i]);
}
return 0;
}

Optimizing code to find common elements in 2 arrays of different sizes

This function f is to find common elements in an array and return result array and i am using 4 four loops to accomplish this task which i feel is no the best use of the loops,
Another problem is, how can i determine the size of the returned array so that my loop is within bounds
here is the code
#include <stdio.h>
#include <stdlib.h>
int *f(int first[], int second[], int size_first, int size_second);
int main(void) {
int arr1[]={1, 8, 3, 2, 6};
int arr2[]= {2, 6, 1};
int size1 = sizeof(arr1)/sizeof(arr1[0]);
int size2 = sizeof(arr2)/sizeof(arr2[0]);
int *intersection = f(arr1, arr2, size1, size2);
for(int i=0;i<3; i++){
printf("%d ", intersection[i]);
}
return 0;
}
// function to find common elements in 2 arrays
int *f(int first[], int second[], int size_first, int size_second){
int k=0, count=0;
//loop through the array to find the number common elements and store in count for dynamic memory allocation in future
for(int i=0;i<size_first;i++){
for(int j=0;j<size_second;j++){
if(first[i]==second[j]){
count ++;
}
}
}
// allocate memory for the common elements by making use of count
int * common_elements = (int*)malloc(count*sizeof(int));
// store the common elements in the new memory location
for(int i=0;i<size_first;i++){
for(int j=0;j<size_second;j++){
if(first[i]==second[j]){
common_elements[k]=first[i];
k++;
}
}
}
return common_elements;
free(common_elements);
}
If you are allowed to waste some memory, note that the intersection cannot have cardinality larger than the number of elements in the smaller set. Therefore, you can allocate more memory than you might need and avoid having to count first and allocate later.
Or, you can realloc as you go.
In general, you need a good data structure for checking set membership more quickly than scanning an entire array although for small sizes which fit in various caches, the linear scan will not perform too shabbily either.
For larger sets, however, you'll want to load the larger of the sets into an AVL tree or Scapegoat tree.
For really large data sets, you'll need to look into Bloom filters and related data structures depending on the use case.
I am including below the most naive improvement in your code which still has the nested loop and wastes memory up to the size of the smaller set to avoid counting common elements first.
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
// TODO: What about duplicates in smaller set?
int *
int_set_intersection(
const int *first,
const int *second,
const size_t size_first,
const size_t size_second,
size_t *n
)
{
size_t K = 0; // number of common elements
const int is_first_smaller = (size_first < size_second);
// Done this way so I can declare variables as consts
const int *set_smaller = is_first_smaller ? first : second;
const int *set_larger = is_first_smaller ? second : first;
const size_t size_smaller = is_first_smaller ? size_first : size_second;
const size_t size_larger = is_first_smaller ? size_second : size_first;
int *common = malloc(size_smaller * sizeof(*common));
if (!common) {
fprintf(stderr, "Failed to allocate memory for %z ints\n", size_smaller);
perror("Cannot allocate memory for common elements");
exit(EXIT_FAILURE);
}
for (size_t i = 0; i < size_smaller; ++i) {
for (size_t j = 0; j < size_larger; ++j) {
if (set_smaller[i] == set_larger[j]) {
common[K] = set_smaller[i];
++K;
break;
}
}
}
*n = K;
return common;
}
void
int_set_print(const int *set, size_t n, FILE *f)
{
FILE *out = f ? f : stdout;
size_t i = 0;
fputs("{ ", out);
for (i = 0; i < n - 1; ++i) {
fprintf(out, "%d, ", set[i]);
}
fprintf(out, "%d }\n", set[i]);
}
int
main(void) {
int arr1[] = {1, 8, 3, 2, 6};
int arr2[] = {2, 5, 1};
size_t n = 0;
const int *intersection = int_set_intersection(
arr1,
arr2,
sizeof(arr1)/sizeof(arr1[0]),
sizeof(arr2)/sizeof(arr2[0]),
&n
);
int_set_print(intersection, n, NULL);
free(intersection); // not really needed, but good hygiene
return 0;
}
For larger arrays, one option is to sort the contents first to make it easier to check for common elements, as shown in the code below. If the original array contents cannot be changed, first copy them into dynamically allocated memory. Dynamically allocated memory is also needed to hold the list of common elements, but that can use the same storage as one of the copies.
OP's original function returns a pointer to dynamically allocated memory containing the array of common elements, but does not indicate the length of the array. I added a parameter to return the length.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *f(int first[], int second[], int size_first, int size_second, int *size_common);
int main(void) {
int arr1[]={1, 8, 3, 2, 6};
int arr2[]= {2, 6, 1};
int size1 = sizeof(arr1)/sizeof(arr1[0]);
int size2 = sizeof(arr2)/sizeof(arr2[0]);
int size_common;
int *intersection = f(arr1, arr2, size1, size2, &size_common);
for(int i=0;i<size_common; i++){
printf("%d ", intersection[i]);
}
free(intersection);
return 0;
}
static int cmp_int(const void *ap, const void *bp) {
int a = *(const int *)ap;
int b = *(const int *)bp;
return (a > b) - (a < b);
}
// function to find common elements in 2 arrays
int *f(int first[], int second[], int size_first, int size_second,
int *size_common) {
int *copy1;
int *copy2;
int idx1;
int idx2;
int count;
// allocate memory local copies of the arrays
copy1 = malloc(size_first * sizeof (int));
copy2 = malloc(size_second * sizeof (int));
if (!copy1 || !copy2) {
// allocation error
free(copy1);
free(copy2);
*size_common = -1; // use -1 to report error
return NULL;
}
// copy the arrays
memcpy(copy1, first, size_first * sizeof (int));
memcpy(copy2, second, size_second * sizeof (int));
// sort the copies in ascending order
qsort(copy1, size_first, sizeof (int), cmp_int);
qsort(copy2, size_second, sizeof (int), cmp_int);
// find common elements
idx1 = 0;
idx2 = 0;
count = 0;
while (idx1 < size_first && idx2 < size_second) {
if (copy1[idx1] < copy2[idx2]) {
idx1++;
} else if (copy1[idx1] > copy2[idx2]) {
idx2++;
} else {
// common element found!
// use copy1[] to store common elements
copy1[count] = copy1[idx1];
count++;
idx1++;
idx2++;
}
}
// common elements are in copy1[].
// finished with copy2, so free it.
free(copy2);
if (count == 0) {
// no common elements
free(copy1); // free the memory
copy1 = NULL; // and make the function return NULL
} else {
// try to reduce memory for common elements
copy2 = realloc(copy1, count * sizeof (int));
if (copy2) {
// reallocation successful
copy1 = copy2;
} // else, never mind, copy1 is still valid
}
// return the common elements
*size_common = count;
return copy1;
}
If your arrays are of comparable elements (you use integers, which are comparable), the best way in my opinion is to sort both arrays and traverse both in parallel, looking at both sides and comparing the elements at both sides. If there's a lowest element, advance its pointer, leaving the other waiting.... if there's a match (they are equal), you can mark it (more on this later) and advance both pointers, until you reach the end in one array (the sortest). You will get the marks on the matching positions, but if you reorder the array, exchanging the found element with the first of the yet, unmatched elements, you will have all matching elements in the first positions of both arrays, letting you to return only the number of matches from the function and the matches themselves in the first positions of both arrays.
The complexity of this algorithm should be O(n*log(n)) (because of the quicksorts) if you use quicksort, plus O(n) (which doesn't affect the final O) for the matching, so O(n*log(n)) should be the big O complexity, as a general case. Below is a sample code, with a run:
comp.c
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#define N(arr) (sizeof(arr)/sizeof((arr)[0]))
void swap(int *ref_a, int *ref_b)
{
if (ref_a == ref_b)
return; /* nothing to do. */
int temp = *ref_a;
*ref_a = *ref_b;
*ref_b = temp;
}
int int_cmp(const void *_a, const void *_b)
{
const int *a = _a, *b = _b;
return *a - *b;
}
void print(int v[], int v_sz, const char *fmt, ...)
{
va_list p;
va_start(p, fmt);
vprintf(fmt, p);
va_end(p);
char *sep = "[";
for (int i = 0; i < v_sz; i++) {
printf("%s%d", sep, v[i]);
sep = ", ";
}
printf("]\n");
}
int find_matches(int a[], int b[], int a_sz, int b_sz)
{
print(a, a_sz, "a(unsorted)");
print(b, b_sz, "b(unsorted)");
qsort(a, a_sz, sizeof a[0], int_cmp);
qsort(b, b_sz, sizeof b[0], int_cmp);
print(a, a_sz, "a(sorted)");
print(b, b_sz, "b(sorted)");
int i = 0;
for (int i_a = 0, i_b = 0; i_a < a_sz && i_b < b_sz;) {
if (a[i_a] < b[i_b]) {
i_a++;
continue;
} else if (a[i_a] > b[i_b]) {
i_b++;
continue;
}
/* a[i_a] == b[i_b] */
swap(&a[i_a], &a[i]);
swap(&b[i_b], &b[i]);
print(a, a_sz, "after #%d, a:", i);
print(b, b_sz, "after #%d, b:", i);
i_a++; i_b++; i++;
}
return i;
}
int main()
{
int arr1[] = {1, 8, 3, 2, 6, 7};
int arr2[] = {2, 6, 1, 7, 4, 1, 9, 6};
int size1 = N(arr1);
int size2 = N(arr2);
int match = find_matches(arr1, arr2, size1, size2);
for (int i = 0; i < match; i++) {
printf("Match #%d: %d\n", i, arr1[i]);
}
}
It will produce:
$ comp
a(unsorted)[1, 8, 3, 2, 6, 7]
b(unsorted)[2, 6, 1, 7, 4, 1, 9, 6]
a(sorted)[1, 2, 3, 6, 7, 8]
b(sorted)[1, 1, 2, 4, 6, 6, 7, 9]
after #0, a:[1, 2, 3, 6, 7, 8]
after #0, b:[1, 1, 2, 4, 6, 6, 7, 9]
after #1, a:[1, 2, 3, 6, 7, 8]
after #1, b:[1, 2, 1, 4, 6, 6, 7, 9]
after #2, a:[1, 2, 6, 3, 7, 8]
after #2, b:[1, 2, 6, 4, 1, 6, 7, 9]
after #3, a:[1, 2, 6, 7, 3, 8]
after #3, b:[1, 2, 6, 7, 1, 6, 4, 9]
Match #0: 1
Match #1: 2
Match #2: 6
Match #3: 7
$ _
A good interface is to switch in both algorithms the matched elements with the first of the non-yet-matched elements in both arrays, so in this way you can return an integer (the one you use to know the start of the non-yet-matched elements) that tells you the number of matched elements, and you will get them from any of the two arrays.
If the elements are not comparable, and they can be just be compared for equity, then you have to compare each element with any other for a match, take them off from the arrays (this can be done swapping them with the first of the not yet matched elemnts, and advance the pointers), and start again with the reduced versions of them. Some way of doing this is, when you find a match, to exchange them with the first, second, third elements of each array, and use a variation of the above algorithm (you reorder as you match) In this case you compare at first time n*m (but not all), when you get a match, (n-1)*(m-1), ... and so until the last comparition in which you fail all comparitions to (m-k)*(n-k). This is, in the average, m*n/2 + (m-1)*(n-1)/2 +...+ (m-k)*(n-k). something in the range of m(m-1)*n(n-1)/k^2, which is O(m^2*n^2):
comp2.c
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#define N(arr) (sizeof(arr)/sizeof((arr)[0]))
void swap(int *ref_a, int *ref_b)
{
if (ref_a == ref_b)
return; /* nothing to do. */
int temp = *ref_a;
*ref_a = *ref_b;
*ref_b = temp;
}
int int_cmp(const void *_a, const void *_b)
{
const int *a = _a, *b = _b;
return *a - *b;
}
void print(int v[], int v_sz, const char *fmt, ...)
{
va_list p;
va_start(p, fmt);
vprintf(fmt, p);
va_end(p);
char *sep = "[";
for (int i = 0; i < v_sz; i++) {
printf("%s%d", sep, v[i]);
sep = ", ";
}
printf("]\n");
}
int find_matches(int a[], int b[], int a_sz, int b_sz)
{
print(a, a_sz, "a(unsorted)");
print(b, b_sz, "b(unsorted)");
int i = 0;
loop:
for (int i_a = 0; i_a + i < a_sz; i_a++) {
for (int i_b = 0; i_b + i < b_sz; i_b++) {
/* we can only compare for equality */
if (a[i + i_a] == b[i + i_b]) {
swap(&a[i + i_a], &a[i]);
swap(&b[i + i_b], &b[i]);
i++;
goto loop;
}
}
}
print(a, a_sz, "a(final)");
print(b, b_sz, "b(final)");
return i;
}
int main()
{
int arr1[] = {1, 8, 3, 2, 6, 7};
int arr2[] = {2, 6, 1, 7, 4, 1, 9, 6};
int size1 = N(arr1);
int size2 = N(arr2);
int match = find_matches(arr1, arr2, size1, size2);
for (int i = 0; i < match; i++) {
printf("Match #%d: %d\n", i, arr1[i]);
}
}
which produces, when running, the following output:
$ comp2
a(unsorted)[1, 8, 3, 2, 6, 7]
b(unsorted)[2, 6, 1, 7, 4, 1, 9, 6]
a(final)[1, 2, 6, 7, 3, 8]
b(final)[1, 2, 6, 7, 4, 1, 9, 6]
Match #0: 1
Match #1: 2
Match #2: 6
Match #3: 7
$ _
You can reorder the values, there's no difference, in this case you had a two level for loop, mixed with a third level go back to the beginning and start again loop. The loop is warranted to finish, as when you go back to the top, you have increased i, which means the nested for loops will be shorter each time. We can rewrite the find_matches routine in this case by adjusting the array start points, in this manner:
comp3.c
/* ... as before */
int find_matches(int a[], int b[], int a_sz, int b_sz)
{
print(a, a_sz, "a(unsorted)");
print(b, b_sz, "b(unsorted)");
int i = 0;
loop:
for (int i_a = 0; i_a < a_sz; i_a++) {
for (int i_b = 0; i_b < b_sz; i_b++) {
/* we can only compare for equality */
if (a[i_a] == b[i_b]) {
swap(&a[i_a], &a[0]);
swap(&b[i_b], &b[0]);
i++;
print(a++, a_sz--, "a(after match)");
print(b++, b_sz--, "b(after match)");
goto loop;
}
}
}
print(a, a_sz, "a(final)");
print(b, b_sz, "b(final)");
return i;
}
/* ... as before */
that will produce this result (I changed the initial sort order to see how it affects the final result):
$ comp3
a(unsorted): [7, 8, 2, 3, 6, 1]
b(unsorted): [2, 6, 1, 7, 4, 1, 9, 6]
a(after match): [7, 8, 2, 3, 6, 1]
b(after match): [7, 6, 1, 2, 4, 1, 9, 6]
a(after match): [2, 8, 3, 6, 1]
b(after match): [2, 1, 6, 4, 1, 9, 6]
a(after match): [6, 3, 8, 1]
b(after match): [6, 1, 4, 1, 9, 6]
a(after match): [1, 8, 3]
b(after match): [1, 4, 1, 9, 6]
a(final): [8, 3]
b(final): [4, 1, 9, 6]
Match #0: 7
Match #1: 2
Match #2: 6
Match #3: 1
$ _

Find count of missing elements in an unsorted array of integers

How can I find how many elements are missing from an array of integers in C, if some of the numbers are duplicated?
Assume the array is int array = {1, 2, 1, 5, 4} and there should be numbers up to 6. Then, the program/function should output/return 2, as there are 2 elements missing (3, 6).
Note: 0 is not counted as a missing number, nor can it be present in an array.
This way?
int countMissing(int *x, int arrLen, int bound)
{
int * y = malloc ((bound + 1) * sizeof(int));
int i = 0;
int missing = 0;
memset(y,0,sizeof(int)*(bound+1));
for(i = 0; i<arrLen; i++)
{
if(x[i]<=bound)
{
y[x[i]] = 1;
}else
{
// error handling e.g.
return -1;
}
}
for(i = 1; i<=bound; i++)
{
if(y[i]==0) missing++;
}
free(y);
return missing;
}
Usage:
int main(void)
{
int array [] = {1, 2, 1, 5, 4};
printf("%d", countMissing(array, 5, 10));
return 0;
}
Output: 6.

Resources