How can I compare two 2D arrays in C? - c

İ try it, but this code not run stable.
İ have two 2D arrays first[a][b] and second[x][y].
I want to compare these two arrays. How can I do this?
My code:
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
if (first[i][j] == second[i][j])
return 1;

An alternative way would be using memcmp.
NOTE: This will work on modern architectures, where int does not have any padding bits. Thanks for #chqrlieforyellowblockquotes to pointing this out.
#include <stdio.h>
#include <string.h>
int main() {
int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int b[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int c[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 123}};
int ret;
ret = memcmp(a, b, 3 * 3 * sizeof(int));
if (ret == 0)
printf("a equal b\n");
else
printf("a not equal b\n");
ret = memcmp(a, c, 3 * 3 * sizeof(int));
if (ret == 0)
printf("a equal c\n");
else
printf("a not equal c\n");
return 0;
}
Output
a equal b
a not equal c

Through your code, I see that:
both the arrays are equal if one of the corresponding elements in the arrays are
equal.
But I think you want this:
both the arrays are equal if all the corresponding elements in the arrays are equal
That does not happen in your code because you are returning immediately when one of the corresponding elements are equal (==), so the remaining checks are omitted by your code.
Solution:
Change if( first[i][j]==second[i][j]) to if (first[i][j] != second[i][j])
This will look for the first unequal element. Then you can return the appropriate message or perhaps break depending on what exactly you are doing with that code.

You were on the right track, but the arrays are identical if all entries are. You should return 0 when you find a difference and return 1 otherwise:
int compare_matrices(int first[10][10], int second[10][10]) {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (first[i][j] != second[i][j])
return 0;
}
}
return 1;
}
An alternative for regular architectures without padding bits would use memcmp():
#include <string.h>
int compare_matrices(int first[10][10], int second[10][10]) {
return !memcmp(first, second, 10 * sizeof(*first));
}
The first code is simplistic but the compiler can optimize it by unrolling the loops and may produce performance comparable or better than that of memcmp().
Reducing the number of tests would increase the number of memory accesses but may produce better performance as the compiler can use SIMD instructions:
int compare_matrices(int first[10][10], int second[10][10]) {
for (int i = 0; i < 10; i++) {
int res = 0;
for (int j = 0; j < 10; j++) {
res |= (first[i][j] != second[i][j]);
}
if (res) return 0;
}
return 1;
}
You can use GodBolt's Compiler Explorer to compare code generators.

Related

How do I declare an empty array as a function parameter correctly?

I'm currently doing some free exercises on codeStepByStep, and I particularly don't know how to solve the max_row one.
I need to input a 2D array as a function parameter, but it keeps showing me this error:
note: declaration of ‘arr’ as a multidimensional array must have bounds for all dimensions except the first *
It seems like arrays should at least have a predefined column length, but it can't be dynamic like that right?
Here is my code :
int max=row(int numColumn, int arr[][numColumn], int numRow) {
int i, j, sum = 0, maxSum = 0, a, b=0;
for (i=0; i<numRow; i++) {
for (j=0; j<numColumn; j++) {
sum = arr[i][j] + sum;
}
if (maxSum < sum) {
maxSum = sum;
a = i;
}
if (maxSum = sum) {
b = i;
}
if (b < a) {
a = b;
}
}
return a;
}
int main()
{
int list[4][3] = {
{ 3, 8, 12},
{ 2, 9, 17},
{ 43, -8, 46},
{203, 14, 97}
};
printf("%d", max_row(3, list, 4));
return 0;
}
After asking here and there I found that I should start by declaring the column variable, so instead of this :
int max_row(int arr[][numColumn], int numRow, int numColumn)
it should be something like this as in the code above:
int max_row(int numColumn, int arr[][numColumn], int numRow)
but it won't be tested by the website.
The test question:
Write a function named max_row that accepts a number of rows and columns, and a 2-D array of integers, as parameters and that returns the index of the row where the elements add up to the greatest value. For example:
int list[4][3] = {
{ 3, 8, 12},
{ 2, 9, 17},
{ 43, -8, 46},
{203, 14, 97}
};
Then the call of max_row(list, 4, 3) should return 3. If there is a tie between two or more rows, return the row with the smaller index.
Your code should work for an array of any size at least 1x1.
Everything in main is me trying to see if the code works.
It's because you can't declare a multi-dimensional array with a variable as dimension (c and c++ don't support it unless you declare them in the heap memory).
A solution could be this one:
#define MAX 10
int row(int numColumn, int arr[][MAX], int numRow)
{
int i, j, sum = 0, maxSum = 0, a, b = 0;
for (i = 0; i < MAX; i++) {
for (j = 0; j < MAX; j++) {
sum = arr[i][j] + sum;
}
if (maxSum < sum) {
maxSum = sum;
a = i;
}
if (maxSum == sum) {
b = i;
}
if (b < a) {
a = b;
}
}
return a;
}
In the first line you declare a constant named MAX with value 10, then you use it to initialize the array.
Also I don't understand the use of maxSum and b, since you never actually use maxSum (you just initialized it) and you don't return b.
Plus you didn't even initialize a (you can't return a not initialized variable).
Moreover REMEMBER that you have to write == to make a comparison in an if statement, not =.

Code not displaying output properly

I'm new to C and wrote a code where I would like to display "?" on the screen where it matches the value in an array. If I have an array initialized with index_location[6] = {0, 1, 5, 8, 9, 12}; my expected output is detailed below. Any help or assistance in helping me is greatly appreciated.
Output:
??###?##??##?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//
int main(void)
{
int index_location[6] = {0, 1, 5, 8, 9, 12};
int len=sizeof(index_location)/sizeof(int);
for (int a = 0; a < len; a++)
{
for(int b = 0; b < len; b++)
{
if ( a == index_location[b])
{
printf("%c",'?');
} else {
printf("%c",'#');
}
}
}
printf("\n");
}
You only need a single loop. You need to go through index positions 0..12 inclusive (where 12 is the last entry in the index_location array), checking whether you need to print a ? or # each time. When you've printed the character corresponding to one of the index_location entries, you need to move on to looking at the next one. You could add a liberal collection of assert() invocations to ensure that things are under control, but as long as the array is in sorted order, you should be OK (and you might get away with it even if it's not, though you might miss some requested ? marks).
#include <stdio.h>
int main(void)
{
int index_location[6] = {0, 1, 5, 8, 9, 12};
int len = sizeof(index_location) / sizeof(index_location[0]);
int max = index_location[len - 1];
int idx = 0;
for (int a = 0; a <= max; a++)
{
if (a < index_location[idx])
putchar('#');
else
{
putchar('?');
idx++;
}
}
putchar('\n');
return 0;
}
Output:
??###?##??##?
The error lies in your for loops. I would go with the below solution.
If the array index_location[] is sorted in ascending order, use this for loop with double initialization intead:
int max = index_location[len-1];
for(int i = 0,j = 0; i <= max; i++)
{
if ( i == index_location[j])
{
printf("%c",'?');
j++;
}
else {
printf("%c",'#');
}
}

How to find top 6 elements in an array in C

I am trying to find top 6 elements from an array with their ordering number.
int x=0;
for (int k = 0; k < 6; k++) //
{
for (i = 1; i <= 90; i++)
{
if (sorted[k] < holder[i] && i >= x)
{
sorted[k] = holder[i];
x = i; //
}
}
}
But this does not work. I want it to give me output like 43->7 15 ->3 etc..
Haven't written C in a while, but here is a simple solution that modifies the array in place and uses selection sort to select the k highest numbers in the array and moves them to the front. It keeps an array of indices that correspond to where the number originally was and applies the same swaps to it.
#include <stdio.h>
#define ELEMENTS 10
void main(void)
{
// example input for execution
int numbers[10] = {9,4,5,1,8,2,3,6,0,7};
// tracks ordering of indices
int indexes[10] = {0,1,2,3,4,5,6,7,8,9};
int k = 6;
int i, j;
int max, temp;
// Partial selection sort, move k max elements to front
for (i = 0; i < k; i++)
{
max = i;
// Find next max index
for (j = i+1; j < ELEMENTS; j++)
{
if (numbers[j] > numbers[max]) {
max = j;
}
}
// Swap numbers in input array
temp = numbers[i];
numbers[i] = numbers[max];
numbers[max] = temp;
// Swap indexes in tracking array
temp = indexes[i];
indexes[i] = indexes[max];
indexes[max] = temp;
}
for (i = 0; i < k; i++) {
printf("%d -> %d\n", indexes[i], numbers[i]);
}
}
And the output:
0 -> 9
4 -> 8
9 -> 7
7 -> 6
2 -> 5
1 -> 4
Here's the answer I have for you.
I would love some constructive criticism on it from anyone who can provide some.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int numbers[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *ptrNumbers[10];
int i=0;
for(; i < 10; i++){
ptrNumbers[i] = &numbers[i]; // assign the addresses
}
int topSix[6];
int topSixIndex=0;
for(; topSixIndex < 6; topSixIndex++){
int **best = NULL; // Pointer to the pointer to the value.
int checkIndex=0;
for(; checkIndex < 10; checkIndex++){
if(ptrNumbers[checkIndex] != NULL){
if(!best){
/* best is not yet defined */
best = &ptrNumbers[checkIndex];
// best now points to the pointer for numbers[checkIndex]
}else if(*ptrNumbers[checkIndex] > **best){
// this else if statement could be attached to the main if as
// an or condition, but I've separated it for readability.
best = &ptrNumbers[checkIndex];
// best now points to the pointer for numbers[checkIndex]
}
}
}
// assign the topSix position and flag the ptrNumbers
topSix[topSixIndex] = **best;
*best = NULL;
}
// now we'll print the numbers
for(topSixIndex = 0; topSixIndex < 6; topSixIndex++){
printf("%d\n", topSix[topSixIndex]);
}
return 0;
}
Essentially the program works like this: Given an array of ten numbers, a second array is constructed to house pointers to those 10 numbers. A third array is then constructed to house the values of the top 6 numbers. A for loop is then initialized to loop 6 times to find the highest unrecorded value. When the highest value is found by looping the pointer array, the value is assigned to the next index of the top six array. Once that value is added, the pointer array's index that points to the top six value is then assigned to NULL. This acts as a flag insuring that the value will not be added again. Finally, all numbers are printed out.
After running this code, the output I received was:
9
8
7
6
5
4
Edit: as a note, the ordering number's can be stored in a second array. You would simply need to track the checkIndex of the highest value and then assign it to a second array which contained the index values.
maybe you aren't looking for a code-only answer, but this will work:
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
// return index of max element
int max_index( int* vec, int sz )
{
int idx, max, i;
if(!sz) return -1;
idx = 0;
max = vec[0];
for(i=1; i<sz; ++i)
{
if( vec[i] > max )
{
max = vec[i];
idx = i;
}
}
return idx;
}
// return indexes of N top elements
void top( int* vec, int sz, int* out_vec, int N )
{
int i, *tmp, idx;
tmp = (int*) malloc( sz*sizeof(int) );
memcpy( tmp, vec, sz*sizeof(int) );
for(i=0; i<N; ++i )
{
idx = max_index(tmp,sz);
out_vec[i]=idx;
tmp[idx] = INT_MIN;
}
free(tmp);
}
see it live here
Make an array of struct that contain data and index, then sort it and pick up first or last 6 elements to output.
Say that you are given an array numbers. Then create an array indexes with the same size as numbers in such a way that its values are equal to their indexes. Here is an illustration:
numbers = [ 1, 7, 3, 9, 2, 0 ]
indexes = [ 0, 1, 2, 3, 4, 5 ]
Sort numbers in descending order, performing the same operations on indexes. In the end, you should end up with something like this:
numbers = [ 9, 7, 3, 2, 1, 0 ]
indexes = [ 3, 1, 2, 4, 0, 5 ]
Finally, all you need to do is work with the first six elements of these arrays.
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int contains(int array[], int array_size, int value)
{
int i;
for (i = 0; i < array_size; i++)
{
if (array[i] == value)
{
return TRUE;
}
}
return FALSE;
}
int main()
{
int numbers[] = { 1, 7, 3, 9, 2, 0 };
int indexes[] = { 0, 1, 2, 3, 4, 5 };
int numbers_size = 6;
int largest[] = { -1, -1, -1, -1, -1, -1 };
int largest_index = 0;
int i;
for (i = 0; i < 6; i++)
{
int j;
int max_index = -1;
int max = -2147483648;
for (j = 0; j < numbers_size; j++)
{
if (numbers[j] >= max && contains(largest, numbers_size, j) == FALSE)
{
max_index = j;
max = numbers[max_index];
}
}
largest[largest_index++] = max_index;
}
for (i = 0; i < 6; ++i)
{
printf("%d->%d\n", largest[i], numbers[largest[i]]);
}
return 0;
}
You probably should use bubblesort (and keep a function holding all the original indexes) and then just make it show the 6 first number of both arrays (from the indexes array and from the array you sorted itself)

Longest increasing sequence in an array in C

I want to make a program that returns me the longest increasing sequence in an array.
For example:
Input: 1, 2, 3, 2, 6, 2
Output: 1, 2, 3
Input: 4, 3, 1, 2, 4, 6, 4, 1, 5, 3, 7
Output: 1, 2, 4, 6
I managed to put together a code, but this only returns me the first sequence of consecutive, increasing numbers:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
int j = 0;
int cou = 0;
int max = 0;
// c = final array; will contain the longest consecutive, increasing sequence of numbers
int c[10];
int n = 0;
int a[] = {1, 3, 5, 1, 5, 7, 8, 9, 10, 11, 12};
for (int i = 0; i < (sizeof(a)/sizeof(int)); ++i) {
if (a[i+1] > a[i])
++cou;
if (cou > max) {
max = cou;
c[j] = a[i];
c[j+1] = a[i+1];
j++;
}
if (j > n) //finding the size of my final array
n = j;
else {
cou = 0;
j = 0;
}
}
for (j = 0; j <= n; ++j)
printf("%d ",c[j]);
return 0;
}
So basically, I want the longest sequence of increasing, consecutive numbers.
Been busting my brains on this one for quite a while now, and still haven't managed to crack it open. Any help is welcome.
You need to iterate through array, finding sequences, and comparing their length. So, you need to remember previous length of sequence to compare. And you can't copy result to output array on the fly (if you need output array at all), because you can't predict length of next sequence. I'll better show you an example.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int previous_len=0, start=0, c[10], len=0; //c = final array; will contain the longest consecutive, increasing sequence of numbers
int a[] = {1, 3, 5, 1, 5, 7, 8, 9, 10, 11, 12};
for (int i = 0; i < (sizeof(a)/sizeof(int)); ++i) {
if(a[i+1] > a[i]) {
len++;
if (len > previous_len) {
previous_len=len;
start=i+1-len;
}
} else {
previous_len=len;
len=0;
}
}
for(int i = 0; i <= previous_len; ++i) {
c[i]=a[start+i]; //here you can copy data to output array, if you need it
printf("%d ",c[i]); //you can output a[start+i] instead
}
return 0;
}
It seems to mee that you miss some curly braces:
if(a[i+1] > a[i])
{
++cou;
if (cou>max)
{max = cou;
c[j]=a[i];
c[j+1] = a[i+1];
j++;}
if (j > n) //finding the size of my final array
n=j;
}
else
{cou = 0;
j=0;}
I suggest breaking this down into smaller pieces.
Start with a function:
int sequenceLength(int[] array, int arrayLen, int position)
... which returns the length of the sequence beginning at position. Test it and make sure
it works. You shouldn't need help to write that.
Once you have that, you can write something like:
int longestSequence(int[] array, int arrayLen) {
int longest = 0;
int longestLen = 0;
for(int i=0; i<arrayLen; i++) {
int seqLen = sequenceLength(array, arrayLen, i);
if(seqLen > longestLen) {
longest = i;
longestLen = seqLen;
}
}
return longest;
}
Again, test this and make sure it works for all circumstances.
Finally you need a function:
printSequence(int[] array, int arrayLen, int position)
... which prints the sequence beginning at that position. Again you should be able to tackle this on your own.
Put all those together:
printSequence(array,arrayLen(longestSequence(array,arrayLen)));
It's always easiest to break a challenge like this into smaller pieces to solve it.
There may be more efficient solutions that avoid backtracking, but guessing at your level, I don't think you need to go there.
(Note: although the code here may compile, consider it as pseudocode)
you used a array to store the longest sequence, that made your code go wrong in printing.
And you dint use braces for if() statement that resulted in wrong sequence.
you can make the following changes to make the code work,
int main()
{int j=0, cou=0, max=0, c[10], n=0; //c = final array; will contain the longest consecutive, increasing sequence of numbers
int a[] = {1, 3, 5, 1, 5, 7, 8, 9, 10, 11, 12};
int i,k,z;
for ( k=0,i = 0; i < (sizeof(a)/sizeof(int)); ++i)
{if(a[i+1] > a[i])
{ ++cou;
if (cou>max)
{max = cou;
z=k;
}
}
else
{
k=i+1;
cou = 0;
j=0;}
}
for( j = z; j <(sizeof(a)/sizeof(int)) ; ++j)
if(a[j]<a[j+1])
printf("%d ",a[j]);
else
break;
printf("%d",a[j]);
return 0;
}

value of pointer to a char array vs plain char pointer

I am having a hard time understanding where I can use a pointer to an array,
e.g: char (*a)[10];.
So two basic questions.
Please give me a simple example of how just a pointer to an array can be used in C code.
Why would one use it as apposed to just declaring a variable as a pointer and then incrementing/decrementing the address after that point.
Say you have a database query that returns a set of strings. Further, say that you know that these strings are no longer than 9 characters in length. Only, you don't know how many elements are in the set returned by the query.
char (*a)[10] = malloc( NumRecords * sizeof *a );
if ( a == NULL )
{
/* Handle error appropriately */
return EXIT_FAILURE; /* Naive */
}
for ( i = 0 ; i < NumRecords ; ++i )
{
assert(strlen(DbRecordSet[i]) < 10);
strcpy(a[i], DbRecordSet[i]);
}
Example: how to print the elements of an array of num_row rows and 3 columns:
#include <stdio.h>
#define NUM_ROW(x) (sizeof (x) / sizeof *(x))
// print elements of an array of num_row rows and 3 columns
void print(int (*a)[3], size_t num_row)
{
size_t num_col = sizeof *a / sizeof **a;
for (int i = 0; i < num_row; i++) {
for (int j = 0; j < num_col; j++) {
printf("%d\n", a[i][j]);
}
}
}
int main(void)
{
int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
int b[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
print(a, NUM_ROW(a));
print(b, NUM_ROW(b));
return 0;
}
Any time you pass an expression with a multi-dimensioned array type to a function, you're going to be working with a pointer to an array:
int a[10][20];
foo(a);
void foo(int (*p)[20]) // or int p[][20]
{ ... }

Resources