Home > Net >  c extract member of a key of a std::multiset into a std::vector without having a getter
c extract member of a key of a std::multiset into a std::vector without having a getter

Time:10-27

I encountered the problem during an interview. I had to create a multimap which had as keys objects with one private member(a string, the name of the object) and mapped value ints(not relevant). There was one restriction imposed by the person leading the interview: there should be not get or set functions associated to the member string of the object. After some processing of the multimap with STL functions(like removing some elements), the following was requested: to extract the name of the key objects into a vector while removing any duplicates. I do not know how to extract the name of the key objects without having a get function(I could remove the duplicates once the extraction is performed). The person leading the interview brought into discussion functors and possibility to use a functor which could be a friend of the Object class. Please let me know if you have any idea how this could be solved! I provide bellow a simplified version of the code creating the multimap.

class Object
{
    std::string m_name; /* no set or get function allowed */
public:
    Object(std::string name): m_name(name) {}
    friend bool operator< (const Object& o1, const Object& o2)
    {
        return o1.m_name.compare(o2.m_name) < 0;
    }
};
void testMap()
{
    std::multimap<Object, int> m1;
    m1.insert(std::make_pair(Object("abc"), 1));
    m1.insert(std::make_pair(Object("qwerty"), 2));
    m1.insert(std::make_pair(Object("def"), 3));
    m1.insert(std::make_pair(Object("qwerty"), 4))
    /* extract Objects names in a vector while removing duplicates without adding a get m_name function */
}

Please let me know if you have any idea how this could be solved! I do not know how to access m_name which is private without a get function...

CodePudding user response:

Not a nice solution, but using the fact that m1.begin() will always point to the alphabeticly first element we can decide if a given string would be the first in it, by inserting it to the map, and erasing it after the check. So we can start a binary-search caracter by character for the first string. Using this we can extract all keys from the map (by removing the already ones we find). I know this solution is a bit unortodox, and making a getter (or a friend function/class what is effectively a getter) is way better, but this can be done without modifying the class.

bool is_first(std::string s,std::multimap<Object,int>& m){
    auto it=m.insert(std::make_pair(Object(s), -1));
    bool res=it==m.begin();
    m.erase(it);
    return res;
}
bool eq(const Object&a,const Object& b){
    return (!(a<b)) && (!(b<a));
}
std::string get_first(std::multimap<Object,int> m){
    int len=0;
    std::string res;
    while (1){
        char mn=-128,mx=127,mid;
        res =mn;
        while(mn 1!=mx){
            mid=(mn (int)mx)/2;
            res[len]=mid;
            if (is_first(res,m)){
                mn=mid;
            }else{
                mx=mid;
                if (eq(m.begin()->first,Object(res)))
                    return res;
            }
        }
        res[len]=mn;
          len;
    }
}

void testMap()
{
    std::multimap<Object, int> m1;
    m1.insert(std::make_pair(Object("abc"), 1));
    m1.insert(std::make_pair(Object("abc"), 1));
    m1.insert(std::make_pair(Object("qwerty"), 2));
    m1.insert(std::make_pair(Object("def"), 3));
    m1.insert(std::make_pair(Object("qwerty"), 4));
    while (!m1.empty()){
        std::string s=get_first(m1);
        std::cout<<s<<" ";
        m1.erase(s);
    }
}

The motto for this solution: "If it stupid but it works, then it isn't stupid"

CodePudding user response:

If the interviewer mentioned "to use a functor which could be a friend of the Object class," this implies that you are allowed to modify class Object by adding a friend declaration. In that case, you can simply add a friend function (I don't see why a Functor would be better) like

class Object
{
    std::string m_name; /* no set or get function allowed */
public:
    Object(std::string name): m_name(name) {}
    friend bool operator< (const Object& o1, const Object& o2)
    {
        return o1.m_name.compare(o2.m_name) < 0;
    }
    friend std::string name(const Object& o)
    {
        return o.m_name;
    }
};

I cannot be sure, though, that the interviewer had this in mind; as @NathanOliver mentioned, there is a template trick to access a private member, but I cannot imagine that someone would ask that at an interview.

  • Related