bitwise | in a 2d-array C - c

I haven't used C for quite a long time.
I have a 2d array, where each element is 1 or 0. I want to know for each line whether there is 1 or not. I am doing so :
for (row = xa; row < 50; row++) {
// need to know first if there is any '1' in the next line
if (|schemaArray[row] == 1) {
printf("1 found in row %d\n",row );
}
}
Am I using it wrong?
schemaArray is an argument in my parameter list :
int findPerimeter(int schemaArray[50][50]) {

You will have to iterate over all columns of the row to check if there exists a 1.
Sample code:
for (int row = xa; row < 50; row++ ) {
int bIsOne = 0;
for (int i = 0;i < col_size && !bIsOne; i++ ) {
bIsOne = bIsOne | schemaArray[row][i];
}
if( bIsOne )
printf("1 found in row %d\n",row );
}
This can't be done using bit-wise operators unless you construct a bitmap for the schemaArray. In that case, you could check the entire row at once.
This is mostly an overkill. Do it only if your piece of code is performance critical.
Preprocessing step: Construct a bitmap array for schemaArray
long long bitMapSchemaArray[ROW_SIZE];
for (int i = 0; i < row_count; i++) {
long long columnBitMap = 0;
for (int j = 0; j < col_count; j++ ) {
columnBitMap <<= 1; // Multiplies by 2
columnBitMap = columnBitMap | schemaArray[i][j]; // Add a 1 if schemaArray[i][j]=1 else 0
}
bitMapSchemaArray[i] = columnBitMap;
}
In your function, you could then use the bitmap as:
for (int i = 0; i < row_count; i++) {
if( bitMapSchemaArray[i] )
printf("There is a 1 in %d row\n", i+1);
}
However, at most, you will be able to have 64 columns in 2-D array assuming we use an array of 64 bit integers. Of course, you can also extrapolate this to have more than 64 columns by using ceil(column_count)/64 64 bit integers. In that case, bitwise OR each column to check if the cumulative result is still non-zero.

Simple just iterate over the entire row and find out
for (row = 0; row < 50; row++) {
for (col= 0; row < 50; col++) {
if (schemaArray[row][col] == 1){
printf("1 found in row %d\n",row );
break;
}
}
}

Related

adding an array table (bidimensional) to a List (Java)

I am doing a Bingo program and now, the section of the bingoCard, to do this I am using an a bidimensional array but I need to shuffle the numbers of each row. For the shuffle part I saw that the setList is much better, but I don't know how to relate the List with the array here is a part of the code:
public static Integer[][] bingoCard(){
Integer [][] bingoCard= new Integer[3][9];
for(int x =0; x<bingoCard.length; x++){
for(int y =0; y<bingoCard[x].length; y++){
if(y <5){
int random = (int)(Math.random()*90+1);
System.out.print((bingoCard[0][y] = random) + " ");
}
if(y >4 && y <9){
System.out.print((bingoCard[0][y] = 0) + " ");
}
}
System.out.println();
}
List<Integer[]> list =Arrays.asList(bingoCard);
Collections.shuffle(list);
list.toArray(bingoCard);
return bingoCard;
}
Any question please ask me!!
Thanks.
In your code, when you do List<Integer[]> list = Arrays.asList(bingoCard), you are converting the outer array into a List and then shuffling its contents. The effect of this will be that the order of the 3 rows are shuffled rather than the contents of the 3 rows which is what you want. You could achieve this by shuffling the contents of each row within your for-loop. Or, after constructing the 2D array, you can loop over each row again and shuffle them.
Also, you have another small bug. When you assign the value, you are doing bingoCard[0][y] = ... but it should be bingoCard[x][y]. Otherwise, you are only assigning the first row new values on each iteration.
I would recommend not converting the array to a List just to shuffle it and then converting it back. Instead, you can use Random.nextInt to pick indexes of the array to assign. That would look something like this:
public static Integer[][] bingoCard(){
int numRows = 3;
int numCols = 9;
int randomNumbersPerRow = 5;
int randomNumberBound = 90;
Random random = new Random();
Integer[][] bingoCard = new Integer[numRows][numCols];
for (int row = 0; row < numRows; row++) {
for (int col = 0; col < numCols; col++) {
// Initialize all spots to 0
bingoCard[row][col] = 0;
}
for (int i = 0; i < randomNumbersPerRow; i++) {
// Choose a spot to assign a random number
int indexToAssign = random.nextInt(numCols);
// Make sure we haven't already chosen it
while (bingoCard[row][indexToAssign] != 0) {
indexToAssign = random.nextInt(numCols);
}
int numToAssign = random.nextInt(randomNumberBound) + 1;
bingoCard[row][indexToAssign] = numToAssign;
}
}
// Print the bingo card
for (int row = 0; row < numRows; row++) {
for (int col = 0; col < numCols; col++) {
System.out.printf("%2d ", bingoCard[row][col]);
}
System.out.println();
}
return bingoCard;
}

Checking whether a number exist in the same row or column matrix

I want to output Yay if the matrix doesn't contain the same number on the same row or column otherwise output Nay
this is for my college homework. I already tried to check the column and row in the same loop but the output still not right
#include <stdio.h>
int main()
{
int size;
int flag;
scanf("%d",&size);
char matrix[size][size];
for (int i = 0; i < size; i++)
{
for (int l = 0; l < size; l++)
{
scanf("%s",&matrix[i]);
}
}
for (int j = 0; j < size; j++){
for (int k = 0; k < size; k++){
if(matrix[j] == matrix[j+1] || matrix[j][k]==matrix[j][k+1])
{
flag = 1;
}
else
{
flag = 0;
}
}
}
if (flag == 1)
{
printf("Nay\n");
}
else
{
printf("Yay\n");
}
return 0;
}
I expect to output "Nay" when I input
3
1 2 3
1 2 3
2 1 3
and "Yay" when i input
3
1 2 3
2 3 1
3 1 2
Your matrix is a 2D array and you are referencing it using only a single subscript matrix[index] at several places which returns the address of the row. Index it using both the row and column indices. Try the code below:
{
int size;
int flag;
scanf("%d",&size);
char matrix[size][size];
for (int i = 0; i < size; i++)
{
for (int l = 0; l < size; l++)
{
scanf("%s",&matrix[i][l]);
}
}
for(int j = 0; j < size; j++){
for (int k = 0; j < size; j++){
if(matrix[j][0]== matrix[j][k] || matrix[k][0]==matrix[k][j])
{
flag = 1;
break;
}
else
{
flag = 0;
}
}
}
if (flag == 1)
{
printf("Nay\n");
}
else
{
printf("Yay\n");
}
return 0;
}
Your have a logic problem. Your flag is reset on every element in the matrix and thus only reflects the result of the last check.
In addition, you need a break; in your nested loop. The logic is, if your flag becomes 1, you are sure to say Nay, and you don't want the flag to be reset to 0.
int flag = 0;
for (int i = 0; i != size && !flag; ++i) {
for (int j = 0; j != size; ++j) {
if ( /* detection */ ) {
flag = 1;
break;
}
}
}
if (flag)
printf("Nay\n");
else
printf("Yay\n");
Note: The commented /* detection */ part requires more work. Since it's your homework, you may try it first. You could use a hash table for memorization. Or brutal force to make the program simply work. It seems that your detection only checks for neighboring elements, which is not sufficient to assert that an element is unique in its row or column. Consider
1 2 1
3 4 5
6 7 8
I can't do your homework for you. The following is the brutal-force way you may consider.
The if ( /* detection */ ) part could be if (has_same_element(matrix, i, j)), with a function (pseudo code)
int has_same_element(matrix, row, col)
{
for each element a in matrix's row except matrix[row][col] itself
if (a == matrix[row][col])
return 1
for each element b in matrix's col except matrix[row][col] itself
if (b == matrix[row][col])
return 1
return 0
}
Of course there are smarter ways, like using a hash table, in which case you don't even need the nested loop. For the time being, work out a feasible solution, instead of the best solution.

C 2D Arrays removing certain predetermined rows by shifting the ones below it

This is my first post here.
An assignment of my online course in C asked me to remove each row in a real(non dynamically allocated, pointers are not used) whose average sum is greater than the average sum of the whole matrix. The rows should be "removed" by shifting the ones below it up by one position.
I have set up a matrix with the following code:
int matrix[100][100]
Now, my idea was to create a regular 1D array which stores the indexes of the rows to-be-removed.
This is how I did it:
k = 0;
for (i = 0; i < no_of_rows; i++) {
average_sum_of_row = 0;
for (j = 0; j < no_of_columns; j++) {
average_sum_of_row += matrix[i][j];
}
average_sum_of_row = average_sum_of_row / no_of_columns;
if (average_sum_of_row > average_sum_of_matrix) {
indexes_of_rows_to_remove[k] = i;
k++;
l++;
}
}
Which works just fine! I get an array whose elements are the indexes of the rows which need to be removed. However, while implementing my code into the following:
m = 0;
for (i = 0; i < V; i++) {
if (indexes_of_rows_to_remove[m] == i) {
for (k = i; k < no_of_rows - 1; k++) {
for (j = 0; j < no_of_columns; j++) {
matrix[k][j] = matrix[k + 1][j];
}
}
i--;
no_of_rows--;
}
m++;
}
It does not work. What I used is my existing code of removing a row by shifting the ones below it up and decreasing the number of rows by one, but this simply doesn't work and I don't know why.
I tried using a separate integer(m) to go through all elements of the array of indexes, but for some reason it does not work.
Thanks all!
You can use this algorithm, which skips the rows to be deleted:
k = 0
For i in number of rows:
If i not to be deleted:
matrix[k] = matrix[i] # copy the whole row here
k++
The algorithm you are trying to implement is complicated and very inefficient.

Printing a single dimension array in user specified columns in C language

I am trying to display the elements of an array in the number of columns that the user specifies. They decide how large the array is and how many columns it will be displayed in. Right now, I am printing the elements of the array in columns but, I have extra rows and columns with numbers that are not in the array. Thus if I select array size and column number as 5 3, I would hope to see:
1 3 5
2 4
Instead, I get something like:
1 3 5
2 4 107863456
128976543 58764 896543221
5643217 90876543456 8976543
I am getting 3 columns with 4 rows. I do not know why this is happening. Here is the portion of my code that deals with creating columns, let me know if more code is needed (x is variable that holds array size, y holds number of columns):
void colDisplay(int *aPtr, int x, int y) {
int i, j;
srand(time(NULL));
for(i = 0; i < x; i++) {
aPtr[i] = rand()%5+1;
}
/*Trying to format display for number of columns used*/
printf("Unsorted columns\n");
for(i = 0; i < x; i++) {
for(j = 0; j < y; j++) {
//printf("%d = %d ", (i*y)+j, aPtr[(i*y)+j]);
printf("%d ", aPtr[(i*y)+j]);
}
printf("\n");
}
}
The inner loop is counting the columns correctly, but the outer loop is using x as a row count, instead of an item count. To fix the problem you can use a single loop that counts items, and outputs newlines at the correct times.
j = 0;
for ( i = 0; i < x; i++ )
{
printf("%d ", aPtr[i] );
j++;
if ( j == y || i == x-1 )
{
printf( "\n" );
j = 0;
}
}
I agree with the solution by #user3386109.
Also, the following change will help:
Original 'for' loop with j:
for(j = 0; j < y; j++)
Modified code:
for (j = 0; (j < y) && (i*y+j < x); j++)
Reason: index = i*y+j may exceed x if (x % y != 0) i.e. if x (array size) is not integral multiple of y (display column size).
Because of arrays index out of bound.
You should do the following:
for(i = 0; i >= 0; i++) {
boolean isContinue = true;
for(j = 0; j < y; j++) {
int index = i*y+j;
if(index==x){
isContinue = false;
break;
}
printf("%d ", aPtr[(i*y)+j]);
}
if(!isContinue){
break;
}
printf("\n");
}

Delete matched pairs in an Array

I'm attempting to write a game of Go Fish where points are given for matched pairs of cards. However, I can't seem to find a way to remove the matched pairs from the hand.
I have implemented a little loop to remove single cards used in other aspects of the game, as shown here:
for ( i = position - 1 ; i < user_size - 1 ; i++)
{
user_hand[i] = user_hand[i+1];
user_count[i]--;
user_size--;
}
Where the user_size is the number of cards in the user's hand, and the user_count is how many of each of the 13 card values the user holds. I can't find a way to remove pairs of the same valued cards however.
For example if the user_hand was: 2 2 4 5 6 6 6 6 1 2
I would like to remove all but one of the 2's (one pair) and all four of the 6's (two pairs). Leaving the user_hand as: 4 5 1 2. But for the life of me I can't think of a way to do this. Any help would be greatly appreciated!
In case reordering cards in users hand is not a problem, you could:
int *hand;
int handSize;
...
sort(hand, handSize); // 1. sort
int *newHand = malloc(sizeof(int) * handSize);
int i, newHandSize = 0;
for (i = 1; i < handSize; ++i) {
if (hand[i - 1] == hand[i]) {
hand[i] = -1; // 2. "flag" last value of a pair
continue;
}
newHand[newHandSize] = hand[i - 1]; // 3. copy last examined card to new hand
newHandSize++;
}
if (hand[handSize - 1] != -1) { // 4. copy last element if needed
newHand[newHandSize] = hand[handSize - 1];
newHandSize++;
}
int* handToFree = hand;
hand = newHand; // 5. replace users hand with new hand
free(handToFree); // 6. clean up
but I don't think it can go under O( n*log(n) + n )
Normally you would use 1 array for the cards and one variable to hold the number of cards.
Then you can iterate with a nested loop like this:
for (int i = 0; i < user_size; i++){
for (int j = i+1; j < user_size; j++){
if(user_hand[i] == user_hand[j]){
/* remove card at index i */
for(int z = i; z < user_size - 1; z++) user_hand[z] = user_hand[z + 1];
user_size--;
/* remove card at index j */
for(int z = j; z < user_size - 1; z++) user_hand[z] = user_hand[z + 1];
user_size--;
}
}
}
But in your example, you also got user_count[]. If I understood you right (otherwise please correct me) user_count[] holds how many cards of a specific value the user has on his hand.
So in your example with: 2 2 4 5 6 6 6 6 1 2
user_count[0] = 0
user_count[1] = 1
user_count[2] = 3
user_count[3] = 0
user_count[4] = 1
user_count[5] = 1
user_count[6] = 4
If that's what user_count[] is for, then you could simply do:
for (int i = 0; i < user_size; i++){
for (int j = i+1; j < user_size; j++){
if(user_hand[i] == user_hand[j]){
int cardNumber = user_hand[i];
/* remove card at index i */
for(int z = i; z < user_size - 1; z++) user_hand[z] = user_hand[z + 1];
user_size--;
/* remove card at index j */
for(int z = j; z < user_size - 1; z++) user_hand[z] = user_hand[z + 1];
user_size--;
/* decrement user_count by 2 */
user_count[cardNumber] = user_count[cardNumber] - 2;
}
}
}
void removePairs(int * hand, int size)
{
for(int i = 0; i < size; i++)
{
for(int j = i+1; j < size; j++)
{
if((hand[i] == hand[j]) && hand[i] != -1)
{
hand[i] = -1; // set card "ready to remove"
hand[j] = -1;
break;
}
}
}
for(int k = 0; k < size; k++)
{
if(hand[k] != -1)
{
printf("%d ", hand[k]); // you can store remaining cards here
}
}
}
Start by looping through your user_count array, and keep calling remove_card twice as long as user_count[rank] >= 2:
for(int rank = 1; rank <= 13; rank++)
while(user_count[rank] >= 2) {
remove_card(user_hand, user_count, &user_size, rank);
remove_card(user_hand, user_count, &user_size, rank);
}
For remove_card, just find the first matching card, and call your existing routine:
void remove_card(int *user_hand, int *user_count, int *user_size, int rank) {
for(int pos = 0; pos < *user_size; pos++)
if(user_hand[pos] == rank)
remove_card_at(user_hand, user_count, user_size, pos+1);
}
remove_card_at is the routine you provided in your original post to remove a card at a particular position. Note you'll have to turn user_size into a pointer and dereference it in order to modify the variable in the calling function.
Also, you should really look into using a structure or class to hold the user's hand, depending on if you're using C or C++.

Resources