compare vectors for equality

Pages: 12
Hello all

Could anyone please help?

I have got two structs.

[code removed]

Data in both structs has been stored in vectors. Both structs also contain vectors inside it. I want to match each element of the vector [code]LC0413_IDs[/code] (of struct LC_block) with id1 and id2 (of struct TRS_block) for equality. If any of the elements of vector LC0413_IDs matches either of the two ids i-e id1 and id2, then e-g a flag would be set to true.

Could anyone please help, how do I go about it.

Thanks
Last edited on by admin
if you have vector<LC_block> LC_array; and just one element TRS_block TRS_var you could check like this (where i is declared beforehand and within LC_array... and j is declared and withing LC0413_IDs)
1
2
3
4
5
if ( LC_array[i].LC0413_IDs[j].compare(TRS_var.id1) == 0 ||
     LC_array[i].LC0413_IDs[j].compare(TRS_var.id2) == 0 )
{
  //.. set the flag
}


check http://www.cplusplus.com/reference/string/string/compare/ for using compare...
TRS_var could be changed to vector<TRS_block> TRS_array and you would have another iterator to make sure is inside of TRS_array called k and change to

1
2
3
4
5
if ( LC_array[i].LC0413_IDs[j].compare(TRS_array[k].id1) == 0 ||
     LC_array[i].LC0413_IDs[j].compare(TRS_array[k].id2) == 0 )
{
  //.. set the flag
}
Overload the equality operator for them:

1
2
3
4
5
6
7
8
9
10
11
12
bool operator == ( const TRS_block& trs, const LC_block& lc )
  {
  return (trs.trsLineID    == lc.lcLineID)
     and (trs.id1          == lc.LC0413_IDs)
     and (trs.id2          == lc.LC0419_IDs)
     and (trs.raw_contents == lc.raw_contents);
  }

bool operator == ( const LC_block& lc, const TRS_block& trs )
  {
  return (trs == lc);
  }

Now you just need an overload for the vector content.
 
#include <algorithm> 
1
2
3
4
5
6
7
8
9
10
bool operator == ( const std::vector <TRS_block> & trs, const std::vector <LC_block> & lc )
  {
  return (trs.size() == lc.size())
     and std::equal( trs.begin(), trs.end(), lc.begin() );
  }

bool operator == ( const std::vector <LC_block> & lc, const std::vector <TRS_block> & trs )
  {
  return (trs == lc);
  }

Now you can use it normally:
1
2
3
4
5
6
vector <TRS_block> foo;
vector <LC_block> bar;

...

if (foo == bar) ...

Hope this helps.
Thanks craniumonempty and Thanks Duoas

Duoas the code gives me an error for all four overloaded operators one of which is as follows.

error: ‘bool mergeTRSLCdata::operator==(const mergeTRSLCdata::TRS_block&, const mergeTRSLCdata::LC_block&)’ must take exactly one argument
That's because you're overloading them inside your structures. Overload them in the global scope.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct A
{
   // code
};

struct B
{
   //code
};

bool operator == (struct a, struct b)
{
   // compare code
}
wolfgang! I have initialized them in global space but it is still giving me this error.
From what the error says you have it inside mergeTRSLCdata:: because of the scope in front of the word operator. Remove it?
wolfgang I have done exactly the way Duoas suggested. I searched for the error on google and found that When overloading the == operator, define it as an external function, not as a member function, and declare that extern function a friend of the relevant class or struct. It removed the error. But now it gives me some other errors.

[code removed]

ERRORS:

[code removed]


is it because the code is trying to compare a variable with a whole vector? Sorry for being silly as I dont know about the syntax. I want to compare each element of the vectors [code]LC_block::LC0413_IDs[/code] and LC_block::LC0419_IDs with TRS_block::id1 and TRS_block::id2. If any of the elements of both these vectors equals any of the IDs then a flag should be set to true.

Please help.
Last edited on by admin
Yes. Lines 3 and 4 above are the problem. You are comparing a std::string against
a std::vector< std::string >, and no such operator== exists.

If you want to check if id1 exists in LC0413_IDs, you can do this:
 
std::find( lc.LC0413_IDs.begin(), lc.LC0413_IDs.end(), trs.id1 ) != lc.LC0413_IDs.end()


If the above expression is true, then a match was found.

Thank you so much jsmith but I am still confused about the syntax ;'(

The vector that has struct TRS_block data is trs_file_as_blocks and the vector that has struct LC_block data is lc_file_as_blocks. How am I going to check if any of the elements of the two vectors of type struct LC_block is equal to either id1 or id2 of struct TRS_block. Could you please write to me the lines of code.
Should it be something like this?

[code removed]

Could you please correct.
Last edited on by admin
Let me understand. You have an instance of TRS_block and an instance of LC_block.
You want to check if id1 or id2 is present in either vector instead LC_block?

The line I gave you above, which you would put in your first operator== (lines 3 and 4)
checks if id1 is in one of the vectors. You have to write three more similar checks for
the other three permutations. (check if id1 is in the other vector, check if id2 is in the
first vector, check if id2 is in the second vector).
You have an instance of TRS_block and an instance of LC_block. You want to check if id1 or id2 is present in either vector instead LC_block?

where those two vectors are declared inside the struct LC_block

The line I gave you above, which you would put in your first operator== (lines 3 and 4) checks if id1 is in one of the vectors.

I want to check if vector-1 of struct LC_block has an element equal to id1 of struct TRS_block or an element equal to id2 of struct TRS_block, similary check to see if vector-2 of struct LC_block has an element equal to id1 of struct TRS_block or an element equal to id2 of struct TRS_block.

[code removed]

That's the way I have done it without using the overloaded == operator and it is working fine but could you please modify the code for me according to the overloaded == operator?

[code removed]
Last edited on by admin
Your first block of code does what you say you want it to do.

Your second block of code now says I have a vector of TRS_blocks and a vector of
LC_blocks, and I want to see if any element of the TRS_block vector is equal to
any element of the LC_block vector according to the rules set forth in the first
code block.

Your second block is basically what you need to do, though lines 5-8 are nothing
more than operator== which std::find will call:

1
2
3
4
5
6
7
8
9
10
bool operator==( const std::vector<TRS_block>& trs, const std::vector<LC_block>& lc )
{
    typedef std::vector<TRS_block>::const_iterator TRS_iter;

    for( TRS_iter t = trs.begin(); t != trs.end(); ++t )
        if( std::find( lc.begin(), lc.end(), *t ) != lc.end() )
             return true;

    return false;
}


Thanks JSmith. But it still gives me an error.

[code removed]


I want to see if any element of the TRS_block vector is equal to any element of the LC_block vector according to the rules set forth in the first code block.

No I want to check if [code]id1 OR id2 of the struct TRS_block[/code] is equal to any element of the two string type vectors contained in the struct LC_block

[code removed]

Your code:
[code removed]


Should it not be something like [code]trs.id1 OR trs.id2[/code] and lc.LC0413_IDs AND lc.LC0419_IDs and friend bool operator == ( const TRS_block& trs, const LC_block& lc ).

Please suggest.

Thanks
Last edited on by admin
I am not sure of the compile error you posted. I need to see your code that generated the error.

You need two operator== functions. Here they are:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool operator ==( const TRS_block& trs, const LC_block& lc )
{
	return std::find( lc.LC0413_IDs.begin(), lc.LC0413_IDs.end(), trs.id1 ) != lc.LC0413_IDs.end()
     		|| std::find( lc.LC0413_IDs.begin(), lc.LC0413_IDs.end(), trs.id2 ) != lc.LC0413_IDs.end()
     		|| std::find( lc.LC0419_IDs.begin(), lc.LC0419_IDs.end(), trs.id1 ) != lc.LC0419_IDs.end()
     		|| std::find( lc.LC0419_IDs.begin(), lc.LC0419_IDs.end(), trs.id2 ) != lc.LC0419_IDs.end();
}

bool operator ==( const std::vector<TRS_block>& trs, const std::vector<LC_block>& lc )
{
	typedef std::vector<TRS_block>::const_iterator TRS_iter;

	for( TRS_iter t = trs.begin(); t != trs.end(); ++t )
       		if( std::find( lc.begin(), lc.end(), *t ) != lc.end() )
       			return true;
	return false;
}


The second one calls the first one indirectly via the std::find(). They should not be declared friends.

The second one returns true if any of the following conditions are true:
1) If any id1 in any TRS_block (trs) matches any element of LC0413_IDs in any LC_block (lc);
2) If any id1 in any TRS_block (trs) matches any element of LC0419_IDs in any LC_block (lc);
3) If any id2 in any TRS_block (trs) matches any element of LC0413_IDs in any LC_block (lc);
4) If any id2 in any TRS_block (trs) matches any element of LC0419_IDs in any LC_block (lc);

Is this not what you want?
Last edited on
Thank you so much jsmith but I can't seem to figure out the problem as it still is giving me an error ;'( . I think I should leave it like this for the moment as it is working and should show it the way it is. However, there is one other issue in this program. Could you please read my next thread and see if you could help me with that.

Thanks again
Perhaps you can post your code?
The structs and overloaded operators are:

[code removed]


And the method is:

[code removed]
Last edited on by admin
Pages: 12