-1

I am writing a program that reads a text file in the form below, imports the data into a vector and then does some calculations with it. At the moment, I am able to import my data in pairs, insert them into a vector and sort the vector.. However all my efforts have failed when it comes to actually removing the duplicates so I can use the vector for other purposes.

1     4
5     6
4     5
4     5
5     4
6     7
...

This is currently my relevant code right now. If I do vec1.size() on the vector above(only the 6 lines), the output should be 5. However, every text file i try, I get an output of 1, I don't understand why..

while( getline( fs1, instrng ) ) {

    istringstream s1(instrng);
    int a, b;
    s1 >> a >> b;
    pair<int,int> pair1 = make_pair(a,b);
    vec1.push_back( pair1 );

    sort( vec1.begin(), myvec1.end() );
            auto last = std::unique(vec1.begin(), vec1.end());
            vec1.erase(last, vec1.end());
kal1nga
  • 19
  • 2
  • 3
    Use [`std::unique`](http://en.cppreference.com/w/cpp/algorithm/unique). – juanchopanza Sep 13 '14 at 06:13
  • 1
    @juanchopanza you should've posted that as an answer – Zaffy Sep 13 '14 at 06:14
  • 2
    @Zaffy I didn't, because there are already so many duplicates. – juanchopanza Sep 13 '14 at 06:15
  • @juanchopanza I disagree with the marking of this question as a duplicate. OP explicitly said: "The program also needs to count something like "1 5" and "5 1" as one." which is not discussed in the post you linked to. – balajeerc Sep 13 '14 at 06:20
  • Thank you @balajeerc, I agree. The requirement here is slightly different. It is not just removing basic duplicates. – kal1nga Sep 13 '14 at 06:21
  • @kal1nga It is only one small step away: figure out how to sort your elements such that `1, 5` and `5, 1` are equivalent, and use the same logic when calling `std::unique`. I will re-open the question though. – juanchopanza Sep 13 '14 at 06:24
  • @kal1nga I've come across a similar scenario in my work. I want to post code on how to resolve it but I can't as long as this question is marked duplicate. Basically, instead of a vector, I suggest you cache the incoming entries in a std::map>. At every insertion into the map,calculate the key as follows:bigger number in the pair and multiply that by a sufficiently large power of 10, say 1000,and add the other number. So irrespective of whether its 1,5 or 5,1 you have a key of 5001.Now iterate over this map to create another vector of pairs if you absolutely need a vector. – balajeerc Sep 13 '14 at 06:31
  • @balajeerc I re-opened the question. I don't think the sorting method would work, I don't think a robust strict weak ordering can be implemented. I would put data into an `unordered_set`, and then copy it into a vector. – juanchopanza Sep 13 '14 at 06:33
  • Related to [How to group values from the same line into a pair?](http://stackoverflow.com/questions/25783769/how-to-group-values-from-the-same-line-into-a-pair/25784069#25784069) – Jarod42 Sep 13 '14 at 17:35
  • `sort( vec1.begin(), myvec1.end() );`. Uh oh. – Puppy Sep 14 '14 at 23:08

2 Answers2

2

Seems like you want to use a set instead of a vector.

Emanuele Paolini
  • 9,912
  • 3
  • 38
  • 64
  • I have to use a vector for this program or else I would have used a set and also, I need to take care of data pairs like (1 5) and (5 1) and count them as one. – kal1nga Sep 13 '14 at 06:19
  • 1
    @kal1nga to treat (1 5) as equal to (5 1) you should define a new datatype (e.g. a Couple) which keeps its two values ordered. Also it would be useful if you explain why you cannot use a set instead of a vector. Anyway it is not difficult to construct the vector from the set. – Emanuele Paolini Sep 13 '14 at 13:20
  • Also, if you consider (4 5) equal to (5 4) in your example you should obtain 4 rows not 5 as you state in question... – Emanuele Paolini Sep 13 '14 at 13:23
  • @kal "I have to use a vector" Why's that? – Lightness Races in Orbit Sep 14 '14 at 23:12
-1
std::map<int, pair<int, int>> filter;
while( getline( fs1, instrng ) ) {
    istringstream s1(instrng);
    int a, b;
    s1 >> a >> b;
    pair<int,int> pair1 = make_pair(a,b);

    int larger = (a>b?a:b);
    int smaller = (a>b?b:a); 
    int key = larger*10000 + b;
    filter[key] = pair1;
}

Iterating over this map should let you extract the vector you want. You might want to change the arbitrarily assigned 10000 to a larger number if you envisage more entries. There ought to be more robust ways of doing this.

balajeerc
  • 3,998
  • 7
  • 35
  • 51