Thread: Search a product using STD::SET find()

  1. #1
    Registered User IndioDoido's Avatar
    Join Date
    Apr 2007
    Posts
    194

    Search a product using STD::SET find()

    hi, i'm trying to find a product using .find(), but it doesn't work :-(

    Code:
    void grocery::findProduct()
    {
    	string id;
    
    	cout<<"Product ID: ";
    	cin>>id;
    
    	set <product>::const_iterator it;
    
    	if( Prod.find(id) == Prod.end() ) //set <product> Prod; is inside the grocery.h
    		cout<<"not found\n";
    	else cout<<"\nthe product type is: "<<it->getType() <<"\n";
    
    	system("pause");
    
    }

    i know the product was inserted because after insertion, i view all products to be certain.
    can anyone tel me what i'm doing wrong?
    "Artificial Intelligence usually beats natural stupidity."

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    In order to find an object in a set, you have to lookup the object with another object.

    I assume that Prod is a set<Product> and is a member variable of your Grocery class, right?

    If so, then that means that Product has an operator< that sorts it by its product ID, correct?

    If so, then you need to create a fake Product with the ID you want to lookup, then use that. Something like this might work:
    Code:
    Product lookup("", "", 0, id);
    set <product>::const_iterator it = Prod.find(lookup);
    if( it == Prod.end())
    	cout<<"not found\n";

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    If so, then you need to create a fake Product with the ID you want to lookup,
    That's the part I really hate about std::set. It often forces me to compromise my class invariants.
    The better alternative, a std::map, still forces me to duplicate data (the ID).

    I personally prefer a Boost.MultiIndex with a ordered (or even unordered) unique index using an index extractor on the ID. Then I can just pass an ID and it will look up the product.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by CornedBee View Post
    That's the part I really hate about std::set. It often forces me to compromise my class invariants.
    The better alternative, a std::map, still forces me to duplicate data (the ID).

    I personally prefer a Boost.MultiIndex with a ordered (or even unordered) unique index using an index extractor on the ID. Then I can just pass an ID and it will look up the product.
    Another option is to store the products in a sorted vector and use a binary search on the product ID. Just as efficient as map (for lookup, anyway), with no data duplication.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    More efficient than the map, in fact. But very slow on insertion. Really depends on the usage pattern here.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by CornedBee View Post
    More efficient than the map, in fact. But very slow on insertion. Really depends on the usage pattern here.
    I would certainly hope that a product list is not updated that often Even if it took a whole second to add a new item, you're still fine, unless you're adding more than one item per second. That would be one CRAAAAZY store!

  7. #7
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by CornedBee View Post
    I personally prefer a Boost.MultiIndex with a ordered (or even unordered) unique index using an index extractor on the ID. Then I can just pass an ID and it will look up the product.
    That sounds great! Several times I had the problem, that I just couldn't instantiate such a "fake object", because the constructor does complex things like plugging the object into a scheduler for execution, which isn't really wanted for objects needed just to compare with. My solution was then writing an extra ctor just to create more simple comparision-objects. Think I'll try multiindex instead in the future

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> unless you're adding more than one item per second.
    You'd probably only do that if you were adding items en masse a bunch at a time. In that case you'd just add them to the end and do one sort afterwards, which is still probably faster than a map. So a sorted vector is still an excellent option.

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by CornedBee View Post
    More efficient than the map, in fact. But very slow on insertion. Really depends on the usage pattern here.
    Both map and binary search are O(log N) for lookup. Are you talking about overhead or algorithmic efficiency?

    Another domain-specific observation: product IDs probably increase over time as new products are added. Therefore, a new product is very likely going to end up getting inserted at the very end of the vector, which is super-cheap.

  10. #10
    Registered User IndioDoido's Avatar
    Join Date
    Apr 2007
    Posts
    194
    This is a school assignment, and they want me to use specifically std::set :-(
    I prefer vectors because i'm already adapted to them.

    Daved, i did what you said, and it still doesn't work :-(

    Code:
    void grocery::findProduct()
    {
    	string id;
    
    	cout<<"Product ID: ";
    	cin>>id;
    
    	set <products>::const_iterator it;
    
    	products lookup(id, "", "", 0, 0);
    	
    	it = Prod.find(lookup);
    
    	if( it == Prod.end())
    		cout<<"not found\n";
    	else cout<<"\nfound: "<<it->getType() <<"\n";
    
    	system("pause");
    
    }
    Last edited by IndioDoido; 11-01-2007 at 03:51 PM.
    "Artificial Intelligence usually beats natural stupidity."

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Please post the declaration of the Prod member variable. Please post the constructor declaration for the products class. Please post the implementation of the operator< for the products class.

    Also, please be more specific with what happens, why do you think it doesn't work. If it doesn't compile, post compiler errors.

  12. #12
    Registered User IndioDoido's Avatar
    Join Date
    Apr 2007
    Posts
    194
    Sorry Daved!
    I had the Product operator<sorted by its product type and not ID. I changed it to ID and know its working :-D

    sorry...my bad :-(
    Last edited by IndioDoido; 11-01-2007 at 07:03 PM.
    "Artificial Intelligence usually beats natural stupidity."

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Logical errors with seach function
    By Taka in forum C Programming
    Replies: 4
    Last Post: 09-18-2006, 05:20 AM
  2. disk file search algorithm
    By rwmarsh in forum C++ Programming
    Replies: 5
    Last Post: 02-12-2006, 11:46 AM
  3. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  4. Big help in Astar search code...
    By alvifarooq in forum C++ Programming
    Replies: 6
    Last Post: 09-24-2004, 11:38 AM
  5. search array program
    By z.tron in forum C++ Programming
    Replies: 3
    Last Post: 11-15-2002, 07:33 AM