During my C++ exam I found I had some difficulties with what is probably supposed to be something relatively simple. I think I am overlooking something on my problem. For the sake of not getting in trouble for posting part of an exam online, I will make a very simple representation of the part I had troubles with.
What was expected was to make a class myClass in which i could add items item. Then i was supposed to be able to make lists of some items i wanted in that list. The amount of items able to be in the list should be infinite. Each list should have a certain (unique) name. I am also told not to make a new class for the lists and to choose the right container myself.
myClass::myClass(){
itemlist= {};
lists= {};
}
void myClass::addItem(Item &item){
itemlist.emplace_back(item);
}
void myClass::makeList(string listname){
vector <Item> list = {};
// list .name = listname
lists.emplace_back(list);
}
void myClass::addItemToList(string listName, Item &item){
for (int i=0; i<lists.size; i++){
if lists[i].name == listName {
lists.emplace_back(item);
return;
}
}
}
I don't know how to link a name to a list without creating a new class for the lists. I thought about storing another list containing the names of the lists and using that, but it seemed wrong to do so, as they aren't actually linked then. Tried to look up if there is a way to make a list variable listname from the string listname parameter, but apparently that's not possible.
As for the containers, I chose a vector as they can store an "infinite" amount of data in it. I use the itemlist to store all items ever added to myClass, and lists to store all the lists ever created.
In what way is it possible to store a name for each list and for it to be linked?
I think the simplest way to name lists is to use std::unordered_map http://en.cppreference.com/w/cpp/container/unordered_map
Then you'll be able to use your lists like this:
lists["first_list"].push_back(...);
lists["another_list"].size();
lists["create_new_list"] = {};
Maybe what you are looking for "link a name to a list" is a std::map
Something like
std::map<std::string, std::vector<Item>>
Related
I am trying to add a long list of movies and rating into an unordered map or some type of array that would allow me to match by index.
I have another file that already iterates through the entire list. The only thing that I need to worry about is how to put the movies and rating into one index. My issue is that I keep getting an error on insert or ratings.
Insert Error
Ratings error
I want to know if I am doing this correctly.
Movies(std::vector<std::string> movies, std::vector<int> ratings) {
std::unordered_map<std::string, int> movielist;
movielist.insert(movies, ratings);
}
I think this has something to do with the constructor arguments being vector but I don't know how to set it in a list.
I am quite new to C++ so I am not familiar with the specific syntax needed.
Now I have :
struct vote
{
int user; // ID of the user
int item; // ID of the item
float value; // Rating
};
typedef struct vote vote;
And testVotes iterates this data type:
std::set<vote*> testVotes;
Given the testVotes pointing to the vote data contains the information that a certain user give a certain rating to a certain item. Now I want to get the items which the user, let's say, the first user(user id =1) has not rated yet.
In addition, as this code is written by others, and there has been thousands of lines already, I do not prefer to change the existing struct. How can I do what I want without changing the existing code?
Thank you in advance!
------------------------------new demand-----------------------------------
given a known element user id, 3, and another known element item id, 5, how can I get the corresponding element value (3, 4, ?) ?
If looking for the solution for a single specific user a function could build an std::set of all items that him/her rated:
std::set<int> rated_items(int user) {
std::set<int> result;
for (auto p : testVotes) {
if (p->user == user) result.insert(p->item);
}
}
however if you need to do this for all users then building a single map from users to rated items would be more efficient:
std::map<int, std::set<int>> rated_items() {
std::map<int, std::set<int>> result;
for (auto p : testVotes) {
result[p->user].insert(p->item);
}
}
Knowing which items a user rated makes trivial to know which items the user has NOT rated.
PS: the data structure std::set<vote *> looks a very questionable choice (a std::set<vote> would seem much more reasonable, or an std::vector<vote> if the same user can rate the same item multiple times).
Thousands of lines already written is nothing compared to the grief of living forever with a bad data structure.
You really should spend several days to read much more about Programming using C++ and about C++ standard containers.
You might have some map or set indexed by user ids (e.g. have some appropriate class userdata then use std::map<int,userdata> and/or std::set<int> with the int key being the user id).
Contrarily to your claims, if you are working in a team, you should consider (after discussion with co-workers) to improve the data structure and the existing code (so patching the struct vote should be discussed and attempted, and you should consider patching the code at other places too!). A version control system like git facilitate doing that.
Perhaps you should use smart pointers, for example by declaring std::set<std::shared_ptr<vote>> testVotes; or you just want a set of votes std::set<vote> testVotes;
In one of the interviews, I asked by one of the interviewers how to implement history of web browser but don't show duplicates and need to show in reverse order meaning from most recent till the 5th website visited.
I told we can use linked list. When user enters a website it will be checked against a list of nodes and if the site is already present in the list, we will remove it from the list and add it as head. If it is not in the list, it will be simply added as head of the list. But he told order of complexity is O(n*n) and he asked me are there any other data structures or combination of data structured we could use to make the order of complexity as O(n). I didn't get any clue at that time. Can any one please let me know if you have any idea.
You could do it in constant time if you are using your linked list plus a hash table with pointers to the list items.
um...
With a linked list, Add URL to the start of the list (O(1)), continue throught list, deleting if found (O(n))
As others have mentioned, Using a list and an unordered map would be your best bet. When visiting a new page, if the user has never visited it, add it to the end. if they have visited, recall the iterator using the hash map and remove it. The last step is to then add the url to the start of the list and give it a fresh new iterator in the map.
#include <list>
#include <unordered_map>
class browser
{
public:
void visit (const std::string& page)
{
auto location = locations.find(page);
if (location != locations.end())
{
pages.erase(location->second);
}
pages.push_front(page);
locations[page] = pages.begin();
}
private:
using Pages = std::list<std::string>;
using Locations = std::unordered_map<std::string, Pages::iterator>;
Pages pages;
Locations locations;
};
My list having variable length list items. ContainerList supports variable length list items. When I explored it on internet, I can't find any samples for ContainerList. Give me a sample piece of code to work on ContainerList.
LWUIT demo contains a ContainerList sample in the Scroll demo.
There is also an explanation in our blog http://codenameone.blogspot.com/
Generally ContainerList is a drop-in replacement for list, just replace the usage of List with ContainerList and it should work pretty seamlessly (albeit slower).
Try this:
Vector variableLengthVector = new Vector();
variableLengthVector.clear();
for(int i=0;i< variableLengthStringArray.length;i++)
{
variableLengthVector.add(variableLengthStringArray[i]);
}
List myListToBeDisplaye = new List(variableLengthVector);
variableLengthStringArray--> It contains the items that you wish to show in your list.
So whenever you want to display a list , just populate a vector and initialize your list with that vector. Ensure, that you clear that vector or re initialize the vector before populating it.
Now, simply paste your list on a form or wherever you wish to display it..
Ok, you can find stuff about containerList here:
http://lwuit.java.net/nonav/javadocs/com/sun/lwuit/list/ContainerList.html
You can use a container list like this:
ContainerList abc = new ContainerList(new DefaultListModel(variableLengthVector));
I searched for a sample program to work on with the CList.But i could not find it.I got some basic definitions about the CLists(template class that behaves similar to the doubly linked lists).. and is used to store the aggregate data..The 1st argument is stored internally by the list..I could not see what elements are stored in the list and how to retrieve it.
RsData Data; //object of class RsData
RsEvent* Event;//pointer to class RsEvent
CList<Event*,Event*> EventQueue;
Data.EventQueue.RemoveAll();
//removing the attributes and methods of the class RsEvent stored in the list.
So the doc is CList on MSDN
And there is a link there for the COLLECT Sample: Illustrates MFC Collection Classes
I'm not sure how this doc was not found, so perhaps your question needs to be clarrified.
The list offers front/back inserting and looking, aswell as methods for iterating.
// Define myList.
CList<CString,CString&> myList;
// Add an element to the front of the list.
myList.AddHead(CString("ABC"));
// Verify the element was added to the front of the list.
ASSERT(CString("ABC") == myList.GetHead());