comparing of each string in two lists

Here is the below, when comparing each element in list1 with list2 ,what is the better method for comparing each element in two lists other than begin and end searching list.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 #include<iostream>
#include<list>
#include<string.h>
using namespace std;

int main()
{
string str1,str2;
list<string>list1;
list<string>list2;
for(int i=0;i<3;i++)
{ cout<<"enter the string to store in list1";
  cin>>str1;
   list1.push_back(str1);
  cout<<"enter the string to store in list2";
  cin>>str2;
        list2.push_back(str2);
}
cout<<"elements in list\n";
for(list<string>::iterator itr = list1.begin(); itr!=list1.end(); ++itr)
        cout<<' '<<*itr<<endl;

for(list<string>::iterator itr=list1.begin();itr!=list1.end(); ++itr)
 {
   for(list<string>::iterator it2 = list2.begin(); it2!=list2.end(); ++it2)
        {
                if(*itr == list2.c_str())   // is this correct 
                {
                        list1.erase(itr);
                        cout<< *itr <<endl;
                        list2.erase(it2);
                }
                else
                        cout<<" No common element"<<endl;
        }
 }

cout<<"After comparing the elements in list\n";
for(list<string>::iterator itr = list1.begin(); itr!=list1.end(); ++itr)
        cout<<' '<<*itr<<endl;
}
 


Use std::vector instead of std::list - linked lists are only beneficial in special circumstances. (C++ has some pretty unfortunate naming)

Line 27 should be if(*itr == *it2)

You may be interested to know that C++ implements many algorithms for you:
http://www.cplusplus.com/reference/algorithm/
http://en.cppreference.com/w/cpp/header/algorithm
Last edited on
And the way your using erase is broken, amongst other things. Like line 30 where you're trying to write an invalidated iterator's value to cout.

After you call erase on an iterator it is no longer valid. But erase does return a new, valid iterator, so you can do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <list>
//#include <string.h> wrong header!
#include <string>
using namespace std;

int main()
{
    string str1, str2;

    list<string> list1;
    list<string> list2;

#if 0
    for(int i=0;i<3;i++)
    {
        cout<<"enter the string to store in list1";
        cin>>str1;
        list1.push_back(str1);
        cout<<"enter the string to store in list2";
        cin>>str2;
        list2.push_back(str2);
    }
#else
    // add values for testing
    list1.push_back("one");
    list1.push_back("two");
    list1.push_back("three");

    list2.push_back("two");
    list2.push_back("four");
    list2.push_back("six");
#endif

    cout<<"elements in list\n";
    for(list<string>::iterator itr = list1.begin(); itr!=list1.end(); ++itr)
        cout<<' '<<*itr<<endl;

    //for(list<string>::iterator itr=list1.begin();itr!=list1.end(); ++itr)
    for(list<string>::iterator itr=list1.begin();itr!=list1.end(); /*don't inc here*/)
    {
        bool erase_it = false;

        //for(list<string>::iterator it2 = list2.begin(); it2!=list2.end(); ++it2)
        for(list<string>::iterator it2 = list2.begin(); it2!=list2.end(); /*don't inc here*/)
        {
            cout << "compare : " << *itr << " vs " << *it2 << "\n";

            //if(*itr == list2.c_str())   // is this correct 
            if(*itr == *it2)   // as LB said...
            {
                cout<< *itr <<endl;
                it2 = list2.erase(it2); // update iter here
                erase_it = true; // erase in outer loop
                break;
            }
            else
            {
                cout<<" No common element"<<endl;
                ++it2; // inc iter here
            }
        }

        if(erase_it)
            itr = list1.erase(itr);
        else
            ++itr;
    }

    cout<<"After comparing the elements in list\n";
    for(list<string>::iterator itr = list1.begin(); itr!=list1.end(); ++itr)
        cout<<' '<<*itr<<endl;

    return 0;
}


Ugly, but it lives. And I haven't made the change to vector as LB suggested, though that would be a smart idea.

Andy
Last edited on
Thanks for reply,

But, here i m trying to erase the string in both lists when the string matches in both lists.

Thanks andy
Last edited on
The code as repaired by me does erase the string in both lists: line 53 is where it erases it in list2, line 65 where it erases it in list1.

But is does only erase single occurences of a string, which was my guess at what you were trying to do on lines 29 and 31 of your original code. By which I mean that, in this case:

input:
list1 = "one", "two", "three", "one", "two", "three"
list2 = "two", "four", "six"


the result would be:

output:
list1 = "one", "three", "one", "two", "three"
list2 = "four", "six"


Or was your intention that in this case that all occurences of "two" would be stripped?

Andy
Last edited on
Topic archived. No new replies allowed.