comparing Boolean arrays

I’m new here so please bear with me, learning programming at 60 is an challenge!!

I have a 1D x 5 element Boolean array and a 3x5 2D element Boolean array.

I want to compare the 1D (single row) array with each row in the 2D array.

If a whole row matches this drives an output.

I wrote code that I thought would compare the first row in the 2D with the row of the 1D array but it doesn’t work.

bool they_match = true; // assume they match 
for ( int i = 0; i < 5; i++ ) { // for each element
if ( biDimArray[i] != ipArray[i] ) { // check if they don't match
they_match = false; // they don't match, so set flag
   
 }

Serial.println();
 Serial.println("Print match ");
Serial.print (they_match);

Once I can compare the first row I need to work out how to search each row of the 2D array to see if it matches the 1D array row.

??

The forum software has mangled your code because you did not use code tags, hence the italics

Please read read this before posting a programming question and follow the advice

Show a complete example.
2)
Consider the use of memcmp()

void function()
{
  int row;
  for (row = 0; row < 3; row++ )   // for each element
  {
    bool they_match = true; // assume they match
    for (int col = 0; col < 5; col++)
    {
      if (biDimArray[row][col] != ipArray[col])
      {
        they_match = false; // they don't match
        break;  // No need to look at remaining columns
      }
    }
    if (they_match)
      break; // No need to look at other rows
  }
  
  if (row < 3)
  {
    Serial.println();
    Serial.print("They match at row ");
    Serial.println (row);
  }
}

sterretje has the right idea:

void setup() {
  bool biDimArray[] = {true, true, false, true, true};
  bool ipArray[][5] = {{false, false, false, false, false}, 
                       {true, true, false, true, true},
                       {true, true, true, true, true}
                      };
  int i;
  int flag;

  Serial.begin(9600);

  while (!Serial)           // Some controllers need to wait for the object to be instantiated...
    ;

  for (i = 0; i < 3; i++) {
    Serial.print("i = ");
    Serial.print(i);
    flag = memcmp(biDimArray, &ipArray[i], sizeof(biDimArray));
    Serial.print("   flag = ");
    Serial.print(flag);
    if (flag == 0) {
      Serial.println(", Match");                         
    } else {
      Serial.println(", No match");                             
    }
  }
}

void loop() {
}

The memcmp() function uses the memory address for each array as the bases for the comparison. The sizeof() operator as the third argument tells the compiler how many bytes to compare. By placing the address-of operator before the array name (i.e., &ipArray[]), we are telling the compiler to fetch the address of that particular element, not its contents. Because the function performs its magic by subtracting each element from the other, it returns the result of that subtraction. Therefore, a zero means the elements match.

Also, before you post your code here, place the cursor in the IDE’s source window and press Ctrl-T. That will reformat your code into a common C style.

Slightly simpler:

void function()
{
  int row;
  for (row = 0; row < 3; row++ )   // each row
  {
    int col;
    for (col = 0; col < 5; col++)   // each column
    {
      if (biDimArray[row][col] != ipArray[col])
      {
        break;  // No need to look at remaining columns
      }
    }
    if (col == 5)  // no mismatch found
    {
      break; // No need to look at remaining rows
    }
  }
  
  Serial.println();

  if (row < 3)
  {
    Serial.print("They match at row ");
    Serial.println(row);
  }
  else
  {
    Serial.println("No match found.");
  }
}

johnwasser:
Slightly simpler:

Really? Take out the print statements, add an if test/break on flag and there’s not much left:

  for (i = 0; i < 3; i++) {
    flag = memcmp(biDimArray, &ipArray[i], sizeof(biDimArray));
    if (flag == 0) {
      break;
    }
  }
  if (!flag) {
    Serial.print("Match on row i = ");
    Serial.print(i);
  } else {
    Serial.println(", No match");
  }

I was trying not to read each element directly and making a compare, plus it’s useful to know about the mem*() functions.

Thanks guys!

Much appreciated.

I assume memcmp would still work with Int arrays as well?

Yes, it will. If you use sizeof() for the 3rd argument, it will scale as well for any size array of any type.

econjack:
Really? Take out the print statements, add an if test/break on flag and there’s not much left:

Oops. I meant “Slightly simpler than my previous attempt.” not comparing my solution to yours. Sorry for the misunderstanding.

sterretje:
Yes, it will. If you use sizeof() for the 3rd argument, it will scale as well for any size array of any type.

Actually, that’s not quite right because sizeof() returns bytes allocated to the data item, not elements. The sizeof() operator will only work that way on single-byte data types. If you have a type that takes more than one byte per element, try something like this:

#define ELEMENTS(x) (sizeof(x) / sizeof(x[0]))

int myArray[10];

// ...more code, followed by something like this in loop()

   for (i = 0; i < ELEMENTS(myArray); i++) {
      myArray[i] = i;
   }

// More code...

In this case, ELEMENTS(x) is a parametized macro that can figure out how many elements there are, even when used with multi-byte data types (e.g., int, long float, etc.).

For the for-loop, I agree, for the memcmp (that I was referring to), I don't agree :wink:

memcmp compares two areas of bytes; as sizeof() gives the number of bytes, it does not matter if they are ints, structs or whatever.

OK, I see what you're saying. I think I was interpreting the "will scale" statement the wrong way.

Hello econjack

econjack:
Really? Take out the print statements, add an if test/break on flag and there’s n

Interesting.
Have you compared the generated codes with several options of optimization?

Regards,
bidouilleelec