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
  1. #16
    Join Date
    Apr 1999
    Posts
    27,449

    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
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    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. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #18
    Join Date
    Jul 2013
    Posts
    161

    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
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    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. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

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
  •  





Click Here to Expand Forum to Full Width

Featured