array matrix problem - Page 2
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 2 FirstFirst 12
Results 16 to 19 of 19

Thread: array matrix problem

  1. #16
    Join Date
    Apr 1999
    Posts
    27,418

    Re: array matrix problem

    Quote Originally Posted by TheLionKing View Post
    Am sorry guys but maybe i didnt make my self clear...because after trying to use the code of mckenzie and not getting the desired result
    If the original order doesn't matter, then the fix is simple. Use a map:
    Code:
    #include <vector>
    #include <map>
    #include <iostream>
    #include <iterator>
    #include <algorithm>
    
    template <typename T>
    std::vector<T> CreateUniqueVector(T* firstItem, T* lastItem)
    {
       std::map<T, int> tMap;
       std::vector<T> vReturn;
       T* curItem = firstItem;
       while ( curItem != lastItem )
       {
          tMap[*curItem]++;
          ++curItem;
       }
       typename std::map<T, int>::iterator it = tMap.begin();
       while (it != tMap.end() )
       {
          if (it->second == 1 )
            vReturn.push_back(it->first);
         ++it;
        }
        return vReturn;
    }
    The first loop keeps track of the number of times a number is encountered and saves this info in the map. The second loop then goes through the map that was built and only pushes back items with a "hit count" of 1. If it's more than 1, then the item was seen 2 or more times. But remember, the map will order the items, so if you want to keep the original order, then a different container (a std::vector) can be used instead of std::map.

    Now, if you tried to do this with your "simple" code, you will find very easily that it isn't so simple, especially if the order must be kept. You will wind up doing basically what the code I posted above is doing, but without an official "map" type. More than likely you will find yourself using an array that keeps track of the "hit count", no different than the code above (without the STL), and then going through the array at the end to find out which items showed up more than once.

    Here is a solution using std::vector that keeps the order:
    Code:
    template <typename T>
    std::vector<T> CreateUniqueVector(T* firstItem, T* lastItem)
    {
       typename std::vector<T>::iterator it;
       std::vector<T> vReturn;
       T* curItem = firstItem;
       while ( curItem != lastItem )
       {
           it = std::find(vReturn.begin(), vReturn.end(), *curItem);
           if ( it != vReturn.end() )
              vReturn.erase(it);
           else
              vReturn.push_back(*curItem);
          ++curItem;
       }
       return vReturn;
    }
    The issue with this solution is that it isn't the best performing solution due to the call to std::find each time a number is encountered. But basically, this does the job. It works by seeing if an item is already in the vector. If it is in the vector, the item is erased.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; July 29th, 2013 at 05:04 AM.

  2. #17
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,020

    Re: array matrix problem

    Note that this solution only works correctly if there are an even number of a repeated number per row. If there are an odd number of a repeated number then the number will still be output. If an odd number of a repeated number is possible then consider the revised code below

    Code:
    #include <vector>
    #include <iostream>
    #include <algorithm>
    
    template <typename T>
    std::vector<T> CreateUniqueVector(const T* firstItem, const T* lastItem)
    {
    std::vector<T> vReturn;
    
    bool dup = false;
    
    	for (const T* curItem = firstItem; curItem != lastItem; ++curItem, dup = false) {
    		for (const T* chkItem = firstItem; chkItem != lastItem && !dup; ++chkItem)
    			if ((chkItem != curItem) && (*chkItem == *curItem)) dup = true;
    
    		if (!dup) vReturn.push_back(*curItem);
            }
    
            return vReturn;
    }
    
    using namespace std;
    
    const int no_cols = 6;
    
    int main()
    {
    const int tmat [][no_cols] = {	{1, 2, 3, 4, 4, 4},
    				{7, 4, 5, 7, 6, 7},
    				{4, 0, 7, 9, 0, 0},
    				{4, 5, 5, 9, 0, 5},
    				{4, 5, 9, 9, 0, 9},
                   			};
    
    const int no_rows = sizeof(tmat) / sizeof(tmat[0]);
    
    	for (int i = 0; i < no_rows; ++i) {
    		vector<int> iv = CreateUniqueVector<int>(&tmat[i][0], &tmat[i][no_cols]);
    		copy(iv.begin(), iv.end(), ostream_iterator<int>(cout, " "));
    		cout << endl;
    	}
    
    	return 0;
    }
    This produces the output below

    Code:
    1 2 3
    4 5 6
    4 7 9
    4 9 0
    4 5 0
    Last edited by 2kaud; July 29th, 2013 at 07:37 AM.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  3. #18
    Join Date
    Jul 2013
    Posts
    11

    Re: array matrix problem

    HI master 2Kaud...I needed to use this code you wrote for me last time...mmm trying to read it again I couldn't understand a step...
    am gonna post the code and write in the comments...
    template <typename T>
    std::vector<T> CreateUniqueVector(const T* firstItem, const T* lastItem)
    {
    std::vector<T> vReturn;

    bool dup = false;

    for (const T* curItem = firstItem; curItem != lastItem; ++curItem, dup = false) { //pt curItem start from first item, condition ok,
    //first curItem should move once and dup should remain false..
    for (const T* chkItem = firstItem; chkItem != lastItem && !dup; ++chkItem) //MY PROBLEM IS HERE... chkItem starts from // firstItem, chkItem not equal to lastItem and dup being true??? HOW CAN DUP BE TRUE IF WE ALWAYS SETS IT TO FALSE? i can't see // where dup changes to true..or where it can or what makes it be true..because from the previous line..anytime chkItem is //increased..dup is resetted to false...pls explain
    if ((chkItem != curItem) && (*chkItem == *curItem)) dup = true;

    if (!dup) vReturn.push_back(*curItem);
    }

    return vReturn;
    }

  4. #19
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,020

    Re: array matrix problem

    The outer for loop resets dup to be false every time round the loop. This is to set the initial condition of dup for the inner for loop which tests it as part of its condition test. Dup can be set as part of the if statement for the inner for loop.

    When dup is false, !dup is true so the inner for loop condition is true if chkItem not equal lastItem and dup is false.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center