Find symmetry in Array - c

Hi i need to check if the array is symmetry or not. i have a function that takes in a two-dimensional array of integer numbers M and the array sizes for rows and columns as parameters, and returns 1 if M is symmetric or 0 otherwise. I tried many times but the output will be either yes to non-symmetric array or no to symmetric array
Here is my code:
#include <stdio.h>
#define SIZE 10
#define INIT_VALUE -1
int symmetry2D(int M[][SIZE], int rowSize, int colSize);
int main()
{
int M[SIZE][SIZE], i, j, result = INIT_VALUE;
int rowSize, colSize;
printf("Enter the array size (rowSize, colSize): \n");
scanf("%d %d", &rowSize, &colSize);
printf("Enter the matrix (%dx%d): \n", rowSize, colSize);
for (i = 0; i < rowSize; i++)
for (j = 0; j < colSize; j++)
scanf("%d", &M[i][j]);
result = symmetry2D(M, rowSize, colSize);
if (result == 1)
printf("symmetry2D(): No\n");
else if (result == 0)
printf("symmetry2D(): Yes\n");
else
printf("Error\n");
return 0;
}
int symmetry2D(int M[][SIZE], int rowSize, int colSize)
{
int h, k, temp;
int result;
for (h = 0; h < rowSize; h++)
{
for (k = 0; k < colSize; k++)
{
M[h][k] = M[k][h];
}
}
result = 0;
for (h = 0; h < rowSize && result; h++)
{
for (k = 0; k < colSize; k++)
{
//if it is not equal to its transpose
if (M[h][k] != M[h][k])
{
result = 1;
break;
}
}
}
if (result == 0)
{
for (h = 0; h < rowSize; h++)
{
for (k = 0; k < colSize; k++)
{
return result = 0;
}
}
}
else
return result = 1;
}

Several issues:
By your definition, a matrix is symmetric if and only if it is equal to its transpose. That can be the case only for square matrices, yet you accommodate non-square matrices as well, for no apparent reason.
Your symmetry2D() function contains serious logical flaws:
It makes the input symmetric via the loop that performs M[h][k] = M[k][h]
Even if it did not do so, it would never find the input non-symmetric, because its test for that is if (M[h][k] != M[h][k]), which must always fail.
It's unclear what you think the if/else and loop nest at the end of symmetry2D() are achieving for you, but provided that rowSize and colSize are both greater than zero, the actual effect of the whole construct is the same as a simple return result;.
It looks like the idea might have been to create an array containing the transpose of the input, and then compare the input to that. That would have worked, despite being rather grotesquely inefficient, but you never in fact create that separate array for the transpose. If you're going to test without creating the transpose -- which you should -- then
Do not modify the input array (so remove the first loop nest altogether).
Get your indexing right for the symmetry comparisons: M[h][k] != M[k][h]
For best efficiency, avoid redundant and needless comparisons. For example, if you have already tested the M[1][2] == M[2][1] then you do not need to test whether M[2][1] == M[1][2]. And you never need to test elements on the main diagonal. You could achieve this efficiency pretty easily with a better choice of loop bounds.
Also, if indeed the symmetry2D() function is supposed to avoid modifying the input array, consider declaring the element type for its first argument to be const int instead of plain int (but do not modify the type of the corresponding variable in main()). If you had written it that way in the first place then the compiler would have noticed the function's logically erroneous attempt to modify the array elements, and rejected the code.

Related

checking if a array has numbers in it from 0 to length -1 in C

I have got an assignment and i'll be glad if you can help me with one question
in this assignment, i have a question that goes like this:
write a function that receives an array and it's length.
the purpose of the function is to check if the array has all numbers from 0 to length-1, if it does the function will return 1 or 0 otherwise.The function can go through the array only one.
you cant sort the array or use a counting array in the function
i wrote the function that calculate the sum and the product of the array's values and indexes
int All_Num_Check(int *arr, int n)
{
int i, index_sum = 0, arr_sum = 0, index_multi = 1, arr_multi = 1;
for (i = 0; i < n; i++)
{
if (i != 0)
index_multi *= i;
if (arr[i] != 0)
arr_multi *= arr[i];
index_sum += i;
arr_sum += arr[i];
}
if ((index_sum == arr_sum) && (index_multi == arr_multi))
return 1;
return 0;
}
i.e: length = 5, arr={0,3,4,2,1} - that's a proper array
length = 5 , arr={0,3,3,4,2} - that's not proper array
unfortunately, this function doesnt work properly in all different cases of number variations.
i.e: length = 5 , {1,2,2,2,3}
thank you your help.
Checking the sum and product is not enough, as your counter-example demonstrates.
A simple solution would be to just sort the array and then check that at every position i, a[i] == i.
Edit: The original question was edited such that sorting is also prohibited. Assuming all the numbers are positive, the following solution "marks" numbers in the required range by negating the corresponding index.
If any array cell already contains a marked number, it means we have a duplicate.
int All_Num_Check(int *arr, int n) {
int i, j;
for (i = 0; i < n; i++) {
j = abs(arr[i]);
if ((j >= n) || (arr[j] < 0)) return 0;
arr[j] = -arr[j];
}
return 1;
}
I thought for a while, and then i realized that it is a highly contrained problem.
Things that are not allowed:
Use of counting array.
Use of sorting.
Use of more than one pass to the original array.
Hence, i came up with this approach of using XOR operation to determine the results.
a ^ a = 0
a^b^c = a^c^b.
Try this:
int main(int argc, char const *argv[])
{
int arr[5], i, n , temp = 0;
for(i=0;i<n; i++){
if( i == 0){
temp = arr[i]^i;
}
else{
temp = temp^(i^arr[i]);
}
}
if(temp == 0){
return 1;
}
else{
return 0;
}
}
To satisfy the condition mentioned in the problem, every number has to occour excatly once.
Now, as the number lies in the range [0,.. n-1], the looping variable will also have the same possible range.
Variable temp , is originally set to 0.
Now, if all the numbers appear in this way, then each number will appear excatly twice.
And XORing the same number twice results in 0.
So, if in the end, when the whole array is traversed and a zero is obtained, this means that the array contains all the numbers excatly once.
Otherwise, multiple copies of a number is present, hence, this won't evaluate to 0.

C - Passing a 3D arrays of chars to a function

I'm trying to write a program that analyzes a (3 x 4) matrix of strings provided by the user. Ultimately, it needs to output the longest string present in the matrix, along with that string's length.
My program seems to read the input correctly, as judged its success in echoing back the input strings, but it does not correctly output the longest word. I'm sure I'm committing some kind of pointer-related error when I pass the value of longest word, but I do not have any idea how to solve it.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define M 4
#define N 5
#define MAX_DIM 20
void findMAX(char matrice[N][M][MAX_DIM]) {
char maxr;
int index;
int i, j, it;
index = 0;
maxr = *(*(*(matrice+0)+0)+MAX_DIM);
for (i = 0; i < N-1; i++) {
for (j = 0; j < M-1; j++) {
if (index < strlen(matrice[i][j])) {
index = strlen(matrice[i][j]);
// I save the longer line's value
it = i;
// I save the maximum's value
maxr = *(*(*(matrice+i)+j)+MAX_DIM);
}
}
}
printf ("The MAX is: -/%s/- and it's long: -/%d/- \n", maxr, index);
printf ("It is content in the: %d line, which is: \n", it);
for (j = 0; j < N-1; j++) {
printf("%s ", matrice[it][j]);
}
}
void leggi(char matrice[N][M][MAX_DIM]) {
int i, j;
for (i = 0; i < N-1; i++) {
for (j = 0; j < M-1; j++) {
printf ("Insert the element matrix [%d][%d]: ", i, j);
scanf ("%s", matrice[i][j]);
fflush(stdin);
}
}
}
void stampa(char matrice[N][M][MAX_DIM]) {
int i, j;
printf("\n(4 x 3) MATRIX\n");
for (i = 0; i < N-1; i++) {
for (j = 0; j < M-1; j++) {
printf("%s ", matrice[i][j]);
}
printf("\n\n");
}
}
int main(int argc, char *argv[]) {
char matrix[N][M][MAX_DIM]; //Matrix of N*M strings, which are long MAX_DIM
printf("************************************************\n");
printf("** FIND THE LINE WITH THE MAXIMUM ELEMENT **\n");
printf("** IN A (4 x 3) MATRIX **\n");
printf("************************************************\n");
printf ("Matrix Reading & Printing\n");
leggi (matrix);
stampa (matrix);
findMAX(matrix);
return 0;
}
First of all to address some misconceptions conveyed by another answer, consider your 3D array declared as
char matrix[N][M][MAX_DIM];
, where N, M, and MAX_DIM are macros expanding to integer constants.
This is an ordinary array (not a variable-length array).
If you want to pass this array to a function, it is perfectly acceptable to declare the corresponding function parameter exactly the same way as you've declared the array, as indeed you do:
void findMAX(char matrice[N][M][MAX_DIM])
But it is true that what is actually passed is not the array itself, but a pointer to its first element (by which all other elements can also be accessed. In C, multidimensional arrays are arrays of arrays, so the first element of a three-dimensional array is a two-dimensional array. In any case, that function declaration is equivalent to both of these:
void findMAX(char (*matrice)[M][MAX_DIM])
void findMAX(char matrice[][M][MAX_DIM])
Note in particular that the first dimension is not conveyed. Of those three equivalent forms, I find the last clearest in most cases.
It is quite odd, though, the way you access array elements in your findMAX() function. Here is the prototypical example of what you do:
maxr = *(*(*(matrice+i)+j)+MAX_DIM);
But what an ugly and confusing expression that is, especially compared to this guaranteed-equivalent one:
maxr = matrice[i][j][MAX_DIM];
Looking at that however, and it how you are using it, I find that although the assignment is type-correct, you are probably using the wrong type. maxr holds a single char. If you mean it to somehow capture the value of a whole string, then you need to declare it either as an array (into which you will copy strings' contents as needed), or as a pointer that you will set to point to the string of interest. The latter approach is more efficient, and I see nothing to recommend the former for your particular usage.
Thus, I think you want
char *maxr;
... and later ...
maxr = matrice[0][0];
... and ...
maxr = matrice[i][j];
That sort of usage should be familiar to you from, for example, your function stampo(); the primary difference is that now you're assigning the expression to a variable instead of passing it directly to a function.
And it turns out that changing maxr's type that way will correct the real problem here, which #AnttiHaapala already pointed out in comments: this function call ...
printf ("The MAX is: -/%s/- and it's long: -/%d/- \n", maxr, index);
requires the second argument (maxr) to be a pointer to a null-terminated array of char in order to correspond to the %s directive in the format string. Before, you were passing a single char instead, but with this correction you should get mostly the expected result.
You will probably, however, see at least one additional anomaly. You final loop in that function has the wrong bound. You are iterating with j, which is used as an index for the second dimension of your array. That dimension's extent is M, but the loop runs to N - 1.
Finally, I should observe that it's odd that you allocate space for a 5 x 4 array (of char arrays) and then ignore the last row and column. But that's merely wasteful, not wrong.
Try something like this:
void findMAX(char matrice[N][M][MAX_DIM]){
// char maxr
char maxr[MAX_DIM];
int index;
int i, j, it;
index = 0;
// maxr = *(*(*(matrice+0)+0)+MAX_DIM);
strncpy(maxr, *(*(matrice+0)+0), MAX_DIM);
for (i = 0; i < N-1; i++)
{
for (j = 0; j < M-1; j++)
{
if (index < strlen(matrice[i][j]))
{
index = strlen(matrice[i][j]);
it = i;
// maxr = *(*(*(matrice+i)+j)+MAX_DIM);
strncpy(maxr, *(*(matrice+i)+j), MAX_DIM);
}
}
}
printf ("The MAX is: -/%s/- and it's long: -/%d/- \n", maxr, index);
printf ("It is content in the: %d line, which is: \n", it);
// for (j = 0; j < N-1; j++){
for (j = 0; j < M-1; j++){
printf("%s ", matrice[it][j]);
}
}
It's possible to pass multi-dimensional arrays to C functions if the size of the minor dimensions is known at compile time. However the syntax is unacceptable
void foo( int (*array2d)[6] )
Often array dimensions aren't known at compile time and it is necessary to create a flat array and access via
array2D[y*width+x]
Generally it's easier just to use this method even if array dimensions are known.
To clarify in response to a comment, C99 allows passing of variable size arrays using the more intuitive syntax. However the standard isn't supported by Microsoft's Visual C++ compiler, which means that you can't use it for many practical purposes.

How do you break an array in to little arrays of a fixed size? (in C)

I was trying to do an exercise in Hacker Rank but found that my code(which is below) is too linear. To make it better I want to know if it is possible to break an array in to little arrays of a fixed size to complete this exercise.
The Exersise on HackerRank
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
int N, M, Y, X;
scanf("%d %d %d %d", &N, &M, &Y, &X);
int max = 0;
int total = 0;
int data[N][M];
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
{
scanf("%d",&(data[i][j]));
}
}
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
{
total = 0;
for(int l = 0; (l < Y) && (i + Y) <= N; l++)
{
for(int k = 0; (k < X) && (j + X <= M); k++)
{
total += data[i+l][j+k];
}
if(total > max)
max = total;
}
}
}
printf("%d",max);
return 0;
}
While "breaking" it into pieces implies that we'd be moving things around in memory, you may be able to "view" the array in such a way that is equivalent.
In a very real sense the name of the array is simply a pointer to the first element. When you dereference an element of the array an array mapping function is used to perform pointer arithmetic so that the correct element can be located. This is necessary because C arrays do not natively have any pointer information within them to identify elements.
The nature of how arrays are stored, however, can be leveraged by you to treat the data as arbitrary arrays of whatever size you'd like. For example, if we had:
int integers[] = {1,2,3,4,5,6,7,8,9,10};
you could view this as a single array:
for(i=0;i!=10;i++){ printf("%d\n", integers[i]); }
But starting with the above array you could also do this:
int *iArray1, *iArray2;
iArray1 = integers;
iArray2 = integers + (5 * sizeof(int));
for(i=0;i!=5;i++){ printf("%d - %d\n", iArray1[i], iArray2[i]);}
In this way we are choosing to view the data as two 5 term arrays.
The problem is not in the linear solution. The main problem is in your algorithm complexity. As it's written it's O(N^4). Also I think your solution is not correct since:
The ceulluar tower can cover a regtangular area of Y rows and X columns.
It does not mean exactly Y rows and X columns IMHO you could find a solution where the are dimension is less than X, Y.
The problems like that are solvable in reasonable time using dynamic programming. Try to optimize your program using dynamic programming to O(N^2).

Updating my array board game

So I'm creating a game. It has a 5 by 5 board filled with characters a, b and c. I need to create a function where if the board detects the same letter next to each other, it disappears and the emptied cells are replaced with a new set of letters (a,b,c). So a bit like the candy crush game. I also need to display the number of moves that are made before the game ends. Here's where I am so far
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX 10
//creates board and fills in the letters randomly
int board()
{
char grid[MAX][MAX];
char letter[3] = {'a', 'b', 'c'};
int i,j,row,col;
printf("Please enter your grid size: ");
scanf("%d %d", &row, &col);
if(row < 10 && col < 10){
for(i=0; i < MAX; i++){
for(j=0; j < MAX; j++){
grid[i][j] = letter[rand()%3];
}
}
for(i=0; i < MAX; i++){
for(j=0; j < MAX; j++){
printf("%c ", grid[i][j]);
}
printf("\n");
}
}
else{
printf("Board is too big\n");
board();
}
return 0;
}
//the count doesn't quite do what I need it to
int moveCount()
{
char s;
printf("Press s to start: ");
scanf("%c", &s);
if(s == 's' || s == 'S'){
int count;
int max = 10;
for(count=1; count < max; count++)
if(count == max){
-printf("No more moves can be made");
}
else{
printf("Number of moves made: %d\n", count);
}
}
else{
printf("That is not s\n");
moveCount();
}
}
//Trying to check to make sure that n board is always atleast three cells
int inputCheck(){
int n, m;
if(n == 3 || n > 3 && m == 1 || m > 1){
moveCount();
}
}
int main()
{
board();
inputCheck();
}
What's the best way to implement a function that checks if neighbouring cells are the same and then deletes them. I would imagine doing something like if(myArray[0][0] == 'a' && myArray[0][1] == 'a'{do something}...but i don't know if that's the best way or how I would loop that. Also how to correctly implement a count that displays the move made?
I realise this code has a lot of flaws but I'm quite new so go easy please. Thanks for any help or a push in the right direction.
A serious bug here:
int n, m;
if(n == 3 || n > 3 && m == 1 || m > 1){
n and m are used uninitialized.
And you need to #include <stdlib.h> for rand()
In answer to your actual question, something like this would work. This is rather sloppy, but it's my 5 min answer. I assume grid is the actual board, which exists only in your board() function at the moment, so I simply added that as a parameter. AKA You're going to have to make it fit your actual game.
inline int clamp (int v, int min, int max) {
return (v < min) ? min: (v > max) ? max: v;
}
void place (char ltr, int x, int y, char grid[MAX][MAX])
{
grid[y][x] = ltr; // TODO: put bounds checking around x & y
for (int i = clamp(y - 1, 0, MAX); i <= clamp (y + 1, 0, MAX); i++) {
for (int j = clamp(x - 1, 0, MAX); j <= clamp(x + 1, 0, MAX); j++) {
if (i != y || j != x && grid[i][j] == ltr) {
grid[i][j] = '\0'; // TODO: replace null char with desired one.
}
}
}
}
The board function is set up just fine.
As the previous answers said parameters are the best way to check a value if you are going to check them within a different function, if you wish to check them within your function a simple if command would do the trick.
I would not pass an entire array as a parameter, instead I would use a pointer to that specific cell. Then, upon a person choosing a cell they are given a memory address that you could then compare the information stored inside that memory address with the other they are comparing.
Quick Pointer Lesson
- * is used to create a pointer. For instance, char *ch = array; would point to the memory address of the entire array. And then through more research you will be able to go to a specific memory address in a 2-D array, such as your board, see what is at that location and compare it to the contents contained in another memory address within your 2-D array.
Why would you want to to this?
Since this is not Java, we can about memory management in C and using an entire array as a parameter is the easy but more memory costly way of doing it. Plus, pointers are a fundamental element within most programming languages and knowing them well will make you a much better programmer.
Happy Travels!!
Also this will also be easier to go through your board to say, this person chose this address at array[3][2], there are only four memory address they would be choosing from at that point. Which ever way they choose to go, the memory address will be there and you will be able to compare both with minimal system usage and a quick response.

missing numbers

Given an array of size n. It contains numbers in the range 1 to n. Each number is present at
least once except for 2 numbers. Find the missing numbers.
eg. an array of size 5
elements are suppose 3,1,4,4,3
one approach is
static int k;
for(i=1;i<=n;i++)
{
for(j=0;j<n;j++)
{
if(i==a[j])
break;
}
if(j==n)
{
k++;
printf("missing element is", a[j]);
}
if(k==2)
break;}
another solution can be..
for(i=0;i
Let me First explain the concept:
You know that sum of natural numbers 1....n is
(n*(n+1))/2.Also you know the sum of square of sum of first n natural numbers 1,2....n is n*(n+1)*(2n+1)/6.Thus you could solve the above problem in O(n) time using above concept.
Also if space complexity is not of much consideration you could use count based approach which requires O(n) time and space complexity.
For more detailed solution visit Find the two repeating elements in a given array
I like the "use array elements as indexes" method from Algorithmist's link.
Method 5 (Use array elements as index)
Thanks to Manish K. Aasawat for suggesting this method.
traverse the list for i= 1st to n+2 elements
{
check for sign of A[abs(A[i])] ;
if positive then
make it negative by A[abs(A[i])]=-A[abs(A[i])];
else // i.e., A[abs(A[i])] is negative
this element (ith element of list) is a repetition
}
The only difference is that here it would be traversing 1 to n.
Notice that this is a single-pass solution that uses no extra space (besides storing i)!
Footnote:
Technically it "steals" some extra space -- essentially it is the counter array solution, but instead of allocating its own array of ints, it uses the sign bits of the original array as counters.
Use qsort() to sort the array, then loop over it once to find the missing values. Average O(n*log(n)) time because of the sort, and minimal constant additional storage.
I haven't checked or run this code, but you should get the idea.
int print_missing(int *arr, size_t length) {
int *new_arr = calloc(sizeof(int) * length);
int i;
for(i = 0; i < length; i++) {
new_arr[arr[i]] = 1;
}
for(i = 0; i < length; i++) {
if(!new_arr[i]) {
printf("Number %i is missing\n", i);
}
}
free(new_arr);
return 0;
}
Runtime should be O(2n). Correct me if I'm wrong.
It is unclear why the naive approach (you could use a bitfield or an array) of marking the items you have seen isn't just fine. O(2n) CPU, O(n/8) storage.
If you are free to choose the language, then use python's sets.
numbers = [3,1,4,4,3]
print set (range (1 , len (numbers) + 1) ) - set (numbers)
Yields the output
set([2, 5])
Here you go. C# solution:
static IEnumerable<int> FindMissingValuesInRange( int[] numbers )
{
HashSet<int> values = new HashSet<int>( numbers ) ;
for( int value = 1 ; value <= numbers.Length ; ++value )
{
if ( !values.Contains(value) ) yield return value ;
}
}
I see a number of problems with your code. First off, j==n will never happen, and that doesn't give us the missing number. You should also initialize k to 0 before you attempt to increment it. I wrote an algorithm similar to yours, but it works correctly. However, it is not any faster than you expected yours to be:
int k = 0;
int n = 5;
bool found = false;
int a[] = { 3, 1, 4, 4, 3 };
for(int i = 1; i <= n; i++)
{
for(int j = 0; j < n; j++)
{
if(a[j] == i)
{
found = true;
break;
}
}
if(!found)
{
printf("missing element is %d\n", i);
k++;
if(k==2)
break;
}
else
found = false;
}
H2H
using a support array you can archeive O(n)
int support[n];
// this loop here fills the support array with the
// number of a[i]'s occurences
for(int i = 0; i < n; i++)
support[a[i]] += 1;
// now look which are missing (or duplicates, or whatever)
for(int i = 0; i < n; i++)
if(support[i] == 0) printf("%d is missing", i);
**
for(i=0; i < n;i++)
{
while((a[i]!=i+1)&&(a[i]!=a[a[i]-1])
{
swap(a[i],a[a[i]-1]);
}
for(i=0;i< n;i++)
{
if(a[i]!=i+1)
printf("%d is missing",i+1); }
this takes o(n) time and o(1) space
========================================**
We can use the following code to find duplicate and missing values:
int size = 8;
int arr[] = {1, 2, 3, 5, 1, 3};
int result[] = new int[size];
for(int i =0; i < arr.length; i++)
{
if(result[arr[i]-1] == 1)
{
System.out.println("repeating: " + (arr[i]));
}
result[arr[i]-1]++;
}
for(int i =0; i < result.length; i++)
{
if(result[i] == 0)
{
System.out.println("missing: " + (i+1));
}
}
This is an interview question: Missing Numbers.
condition 1 : The array must not contain any duplicates.
The complete solution is :
public class Solution5 {
public static void main(String[] args) {
int a[] = { 1,8,6,7,10};
Arrays.sort(a);
List<Integer> list = new ArrayList<>();
int start = a[0];
for (int i = 0; i < a.length; i++) {
int ch = a[i];
if(start == ch) {
start++;
}else {
list.add(start);
start++;
//must do this
i--;
}
}//for
System.out.println(list);
}//main
}

Resources