-
November 12th, 2010, 04:42 AM
#1
sorting on the basis of datetime
I have a file that has duplicates and I have to select the one with the earliest time
Code:
0:1:OrderReceive,01.07.2010 10:38:09.984,0G508Q090,0000F9F5,A,15,0,15,0,115
0:1:OrderReceive,01.07.2010 10:30:36.903,0G508Q090,0000F9F5,A,15,0,15,0,115
0:2:OrderReceive,01.07.2010 10:23:58.390,0G508Q086,0000F9DA,A,15,0,15,0,70
0:2:OrderReceive,01.07.2010 10:16:25.340,0G508Q086,0000F9DA,A,15,0,15,0,70
where first two lines are identical except the time part and the last two lines are identical but again except for its time part. I need to select the second line of each pair (because they have the earliest time) and the final output should be
Code:
0:1:OrderReceive,01.07.2010 10:30:36.903,0G508Q090,0000F9F5,A,15,0,15,0,115
0:2:OrderReceive,01.07.2010 10:16:25.340,0G508Q086,0000F9DA,A,15,0,15,0,70
could anyone please help?
-
November 12th, 2010, 04:58 AM
#2
Re: sorting on the basis of datetime
Have you thought of using the string comparison operators?
your humble savant
-
November 12th, 2010, 07:12 AM
#3
Re: sorting on the basis of datetime
You have asked a number of questions concerning this data. I don't
know what the current status of your code is. But the solution I would use:
1) create a class with ALL of the diffrent fields in the record asmember variables.
2) read the file into a vector
Then sorting / removing duplicates come down to supply a function which
compares the fields you are interested in.
So the first question I would have ... what are the fields in the line:
0:1:OrderReceive,01.07.2010 10:38:09.984,0G508Q090,0000F9F5,A,15,0,15,0,115
-
November 12th, 2010, 08:31 AM
#4
Re: sorting on the basis of datetime
yes that's exactly the line and the code I have so far for this task is
Code:
struct ordRecvblock
{
std::string lineID; // 0:1:OrderReceive
std::string dateTime; // 01.07.2010 10:38:09.984
std::string remSTr; // 0G508Q090,0000F9F5,A,15,0,15,0,115
ordRecvblock()
{}
ordRecvblock(const std::string& _lineID, const std::string& _dateTime, const std::string& _remSTr):
lineID(_lineID), dateTime(_dateTime), remSTr(_remSTr)
{}
bool operator==(const ordRecvblock& p) const
{
return lineID == p.lineID && remSTr == p.remSTr;
}
bool operator<(const ordRecvblock& p) const
{
if(remSTr < p.remSTr) return true;
if(remSTr > p.remSTr) return false;
return false;
}
};
//.................................
size_t pos1 = line.find("OrderReceive");
if (pos1 != string::npos)
{
istringstream ss(line);
getline(ss,ordb.lineID,',');
getline(ss,ordb.dateTime,',');
getline(ss,ordb.remSTr);
dupOrdTime.push_back(ordb);
continue;
}
else
{
std::sort(dupOrdTime.begin(), dupOrdTime.end());
std::pair<std::vector<ordRecvblock>::iterator, std::vector<ordRecvblock>::iterator> ret;
for(std::vector<ordRecvblock>::iterator i = dupOrdTime.begin(); i != dupOrdTime.end(); i = ret.second)
{
std::vector<ordRecvblock>* dupVec = new std::vector<ordRecvblock>; // stores values that were duplicated
//cout << i->lineID << ',' << i->dateTime << ',' << i->remSTr << " =>\n";
ret = std::equal_range(i, dupOrdTime.end(), *i);
for(std::vector<ordRecvblock>::iterator j = ret.first; j != ret.second; ++j)
{
//cout << j->lineID << ',' << j->dateTime << ',' << j->remSTr << endl;
dupVec->push_back(*j);
}
for(std::vector<ordRecvblock>::iterator i = dupVec.begin(); i != dupVec.end(); ++i)
{
cout << i->lineID << ',' << i->dateTime << ',' << i->remSTr << endl;
}
}
}
-
November 12th, 2010, 08:52 AM
#5
Re: sorting on the basis of datetime
Thanks Philips I have been able to do it . Let me test it with different and many lines
-
November 12th, 2010, 08:57 AM
#6
Re: sorting on the basis of datetime
1) I'm not sure what the :"else" section is doing. In it, you create a vector using
new, but do not do a delete, causing a memory leak. If you did not add anything
to the vector, whyb are you sorting it ? I really can't figure out that section at all.
-
November 12th, 2010, 09:08 AM
#7
Re: sorting on the basis of datetime
I have deleted the vector in my code. Sorry I missed it here :P
Code:
if (pos1 != string::npos)
{
istringstream ss(line);
getline(ss,ordb.lineID,',');
getline(ss,ordb.dateTime,',');
getline(ss,ordb.remSTr);
dupOrdTime.push_back(ordb); // I am populating the vector here
continue;
}
and finally trying to find duplicates
Code:
for(std::vector<ordRecvblock>::iterator i = dupOrdTime.begin(); i != dupOrdTime.end(); i = ret.second)
{
std::vector<ordRecvblock>* dupVec = new std::vector<ordRecvblock>; // stores values that were duplicated
ret = std::equal_range(i, dupOrdTime.end(), *i);
for(std::vector<ordRecvblock>::iterator j = ret.first; j != ret.second; ++j)
{
dupVec->push_back(*j);
}
for(std::vector<ordRecvblock>::iterator i = dupVec.begin(); i != dupVec.end(); ++i)
{
cout << i->lineID << ',' << i->dateTime << ',' << i->remSTr << endl; // printing the duplicates
}
}
-
November 12th, 2010, 09:11 AM
#8
Re: sorting on the basis of datetime
Do I necessarily have to convert the date/time part of the string to proper date time (time_t&)? because the simple string comparison is working and is picking up the correct time
-
November 12th, 2010, 01:35 PM
#9
Re: sorting on the basis of datetime
You almost have it ...
Code:
istringstream ss(line);
getline(ss,ordb.lineID,',');
getline(ss,ordb.dateTime,',');
getline(ss,ordb.remSTr);
// Check if the "lineID + remSTr" combination is already in the vector.
// If it is, compare dates and use the lesser one
vector<ordRecvblock>::iterator it = find(dupOrdTime.begin(),dupOrdTime.end(),ordb);
if (it != dupOrdTime.end())
{
if (ordb.dateTime < it->dateTime)
{
cout << "removing : " << it->lineID << ',' << it->dateTime << ',' << it->remSTr << endl;
*it = ordb;
}
else
{
cout << "not adding: " << ordb.lineID << ',' << ordb.dateTime << ',' << ordb.remSTr << endl;
}
}
else
{
dupOrdTime.push_back(ordb);
}
-
November 15th, 2010, 03:59 AM
#10
Re: sorting on the basis of datetime
Oh thanks you sooo much Philip
-
December 3rd, 2010, 04:49 AM
#11
Re: sorting on the basis of datetime
Hello Philips. Could you please tell me at which point do I include/print those strings which do not have any matches at all while deleting/excluding the ones which do have one/more matches?
Thanks
Code:
istringstream ss(line);
getline(ss,ordb.lineID,',');
getline(ss,ordb.dateTime,',');
getline(ss,ordb.remSTr);
// Check if the "lineID + remSTr" combination is already in the vector.
// If it is, compare dates and use the lesser one
vector<ordRecvblock>::iterator it = find(OrdTime->begin(),OrdTime->end(),ordb);
if (it != OrdTime->end())
{
if (ordb.dateTime < it->dateTime)
{
cout << " adding : " << ordb.lineID << ',' << ordb.dateTime << ',' << ordb.remSTr << endl;
*it = ordb;
}
}
else
{
cout << "NOT adding : " << ordb.lineID << ',' << ordb.dateTime << ',' << ordb.remSTr << endl;
OrdTime->push_back(ordb);
}
-
December 3rd, 2010, 05:10 AM
#12
Re: sorting on the basis of datetime
and also, there can be more than one similar string but with different time and I have to select the one with the minimum time out of many. Could you please tell me how do I go about that?
-
December 3rd, 2010, 10:03 AM
#13
Re: sorting on the basis of datetime
1) in your last "cout" statement , you say "NOT adding" , but you are adding
2) I am guessing that your operator < is not what you want. But you need to tell us exactly
what it means for 2 records to be duplicates. I think that it should probably be:
Code:
bool operator<(const ordRecvblock& p) const
{
if(remSTr < p.remSTr) return true;
if(remSTr > p.remSTr) return false;
return lineID < p.lineID;
}
2) " and also, there can be more than one similar string but with different time and I have to select the one with the minimum time out of many. Could you please tell me how do I go about that?"
Doesn't the code do that ? If not, post an example.
3) What do you mean by : "Could you please tell me at which point do I include/print those strings which do not have any matches at all while deleting/excluding the ones which do have one/more matches?"
Do you mean records that do not have any duplicates ? If so, you have to do that
after reading in all the data. You can create a map to count the number of times
a parttcular string occurs in the file (ignoring the dateTime):
Code:
map<ordRecvblock,int> record_count;
While reading ...
Code:
getline(ss,ordb.remSTr);
++record_count[ordb]; // keeps track of how many time "ordb" is in the file
And when completely done reading ...
Code:
map<ordRecvblock,int>::iterator it = record_count.begin();
while (it != record_count.end())
{
cout << it->first.lineID << "|" << it->first.remSTr << " : count = " << it->second << "\n";
++it;
}
Last edited by Philip Nicoletti; December 3rd, 2010 at 10:26 AM.
-
December 3rd, 2010, 11:29 AM
#14
Re: sorting on the basis of datetime
oh thanks Philip. That's soo soo soooo nice of you . Let me make changes to my code according to your suggestions
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|