Is there a more efficient way of comparing multiple elements of an array?

for example, if I wanted to check if int Array [0,1,2] were equal to 5, 3, and 6 respectively, (data is redundant) what I would use something like this:

1
2
if (Array [0] == 5 & Array [1] == 3 Array [2] == 6)
//statement) 

however if I have an array with multiple dozen elements or more, the code becomes large, hard to read, and unruly. I'm wondering if there's a more compact and expandable way to write this.
Thanks in advance,
- Ceddy
Last edited on
Firstly, your if statement should be :

 
if (Array[0] == 5 && Array[1] == 3 && Array[2] == 6)


If you have many conditions to test, one way would be use a vector/array of conditions to check.

As a simple proof of concept:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <iomanip>

struct Cond {
	size_t elem {};
	int val {};
};

int main()
{
	constexpr int array[] {5, 3, 6, 1, 2, 4, 7, 8};
	constexpr Cond conds[] {{0, 5}, {1, 3}, {2, 6}};

	bool OK {true};

	for (const auto& [e, v] : conds)
		if (!(OK &= array[e] == v))
			break;

	std::cout << std::boolalpha << OK << '\n';
}

for a large number of consecutive elements of a type that allows it (int, double, etc... or very simple objects made up of basic types) you can use memcmp or std::equal for more complicated items (but the more complex the item, the slower the compares will be). Use memcmp if you can, it is amazingly fast (due to not checking anything, it is a raw pointer themed tool and can be user-error prone).
much like above, have an array with the values you want to check for, then memcmp against the target to see if it matches.
you may also be able to rig a highly efficient test with valarray, take a cut across the target to get just the part you want, compare to your hard coded object with an ==
Last edited on
@seeplus

The code you sent sends error message, " [Error] could not convert '{0, 5}' from '<brace-enclosed initializer list>' to 'Cond' " on line 12. I am also having a hard time understanding the code you sent so I can't debug it myself. Could you give a better description of what each block does (give as much context as you need. I would just like to understand it)
P.S. Sorry if I came off as a little rude.
-Ceddy
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <vector>
using namespace std;

int main()
{
   vector<int> A = { 5, 3, 6 };
   vector<int> B = { 5, 3, 6 };
   vector<int> C = { 5, 2, 6 };
   cout << boolalpha << ( A == B ) << '\n';
   cout << boolalpha << ( A == C ) << '\n';
}
true
false
@Ceddy D What version of C++ are you using? That compiles OK with MS VS 2019 as C++17

@lastchance

Thank you for the code, but unfortunately the data (5,3,6) are constant, and there would be many values that it would have to compare to in quick succession, ie. (3,8,4) or (4,2,5) (arbitrary values), so doing it this way would make me have to define dozens of arrays, which I wouldn't like to do.
@seeplus I'm using Dev-C++ version 5.6.3.
Ceddy D wrote:
unfortunately the data (5,3,6) are constant


You can put whatever you like in A, B, C, whenever you like, and they certainly don't have to be constants.

This was only a trivial example.


1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <vector>
using namespace std;

int main()
{
   vector<int> A, B;
   // code goes here to put whatever you like in A and B
   cout << boolalpha << ( A == B ) << '\n';
}





If you want specific positions then you can use valarrays and mask arrays (or, switch to Fortran or Python where you can simply use vector subscripts).
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <valarray>
using namespace std;

int main()
{
   valarray<int> A = { 5, 3, 6 };
   valarray<bool> positions = { true, false, true };
   valarray<int> target = { 5, 6 };
   cout << boolalpha << ( valarray<int>(A[positions]) == target ).min() << '\n';
}
Last edited on
make me have to define dozens of arrays

there isnt any way to compare against a set of values without the values.
whatever you put them in, you have to have them *somewhere*, unless they are from a computation that you can do instead.
they can be in arrays, hard coded against == as you did, in a file, whatever ... lots of ways to stow them. You could maybe curve fit something to produce the sequence you want, but that has its own set of aggravations.
"efficient"
  • Efficiency has little to do with how small your code is

"large, hard to read, and unruly"
  • These are all orthogonal principles. Having one of the set does not imply any other.

"compact and expandable"
  • You've got to get out of knife and spread some peanut butter around to make a PBJ.

Skip the buzzwords.
I think what you are asking is if there is a way you can compare two arrays (or parts of arrays) with unknown data in a way that is:
  • simple to implement
  • not costly in terms of performance

I will assume that the second criterion is more important to you?

The code that lastchance gave you is as simple and efficient as it gets for any generalized array. For integers it won't get any better, no matter how big your array.

There are three concerns that will bite you:
  • If the comparison is for large arrays (> 1000 elements minimum) AND it will happen multiple times
  • How expensive it is to obtain and/or construct the arrays you are comparing your array against.
  • How many arrays are to be compared.

These three points will be your bottleneck. Figure them out and a solution should present itself.

For example, if you are comparing big arrays multiple times, generate a hash for each of your arrays and compare those. It will slow things down at the intake but speed things up to O(1) when you are performing the comparisons.

Good luck!
Topic archived. No new replies allowed.