CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Oct 2010
    Posts
    106

    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?

  2. #2
    Join Date
    Mar 2002
    Location
    Kent, United Kingdom
    Posts
    399

    Re: sorting on the basis of datetime

    Have you thought of using the string comparison operators?
    your humble savant

  3. #3
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    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

  4. #4
    Join Date
    Oct 2010
    Posts
    106

    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;
    		}
    	}
    }

  5. #5
    Join Date
    Oct 2010
    Posts
    106

    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

  6. #6
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    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.

  7. #7
    Join Date
    Oct 2010
    Posts
    106

    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
    		}
    	}

  8. #8
    Join Date
    Oct 2010
    Posts
    106

    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

  9. #9
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    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);
            }

  10. #10
    Join Date
    Oct 2010
    Posts
    106

    Re: sorting on the basis of datetime

    Oh thanks you sooo much Philip

  11. #11
    Join Date
    Nov 2010
    Posts
    146

    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);
    }

  12. #12
    Join Date
    Nov 2010
    Posts
    146

    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?

  13. #13
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    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.

  14. #14
    Join Date
    Nov 2010
    Posts
    146

    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
  •  





Click Here to Expand Forum to Full Width

Featured