Scientifica
Scientifica

Reputation: 169

Map giving wrong values

In a puzzle in CodinGame called MIME Type, we're asked to make a program that:

I was able to solve this puzzle. My first attempt, that I present here, is more complicated. I'm posting it in this question, however, because I had a weird bug and I couldn't figure out what was the reason behind it.

Consider the following file ("MIME.dat") that contains extensions and their corresponding MIME types:

html
text/html
png
image/png
gif
image/gif

Consider as well the following file ("names.dat) that contains the name of the files:

animated.gIf
portrait.png
index.html

The expected output is (following the order by which the names appear in the file):

image/gif
image/png
text/html

Here's my code:

#include <iostream>
#include <string>
#include <map>
#include <fstream>
#include <cstdlib>

using namespace std;

struct cmp_ins {
    bool operator()(const string& s1, const string& s2) const
    {
        if(s1.length()!=s2.length())
            return false;
        else
        {
            bool b=true;
            string::const_iterator i,j;
            for(i=s1.begin(), j=s2.begin(); b && i!=s1.end();++i,++j)
            {
                if((isalpha(*i) && isalpha(*j)) && (toupper(*i)!=toupper(*j)))
                    b=false;
                else if((isalpha(*i) && !isalpha(*j)) || (!isalpha(*i) && isalpha(*j)))
                    b=false;
                else if((!isalpha(*i) && !isalpha(*j)) && *i!=*j)
                    b=false;
            }
            return b;
        }
    }
};

int main()
{
    try
    {
        map<string,string,cmp_ins> db;
        string name,MT;
        string::iterator j;
        ifstream fdb("MIME.dat"), fn("names.dat");
        if(!fdb.is_open())
            throw runtime_error("Couldn't open MIME.dat");
        if(!fn.is_open())
            throw runtime_error("Couldn't open names.dat");
        struct cmp_ins obj;//Will be used to verify if cmp_ins works correctly
        while(fdb >> name >> MT)
        {
            db[name]=MT;
            cout << "(" << name << "," << MT << ")" << endl;
        }
        cout << endl;
        fdb.close();
        while(fn >> name)
        {
            cout << "name:" << name << endl;
            for(j=name.end();*j!='.' && j!=name.begin();--j);
            if(*j!='.')
                cout << "UNKNOWN" << endl;
            else
            {
                string ac=name.substr(j-name.begin()+1,name.end()-j);
                cout << ac << "=gif? " << obj(ac,string("gif")) << endl;
                map<string,string,cmp_ins>::iterator t=db.find(ac);
                cout << "MIME: ";
                if(t==db.end())
                    cout << "UNKNOWN" << endl;
                else
                    cout << t->second << endl;
            }
            cout << endl;
        }
        fn.close();
        return EXIT_SUCCESS;
    }
    catch(exception& e)
    {
        cerr << e.what() << endl;
        return EXIT_FAILURE;
    }
}

Here's the output:

(html,text/html)
(png,image/png)
(gif,image/gif)

name:animated.gIf
gIf=gif? 1
MIME: image/gif

name:portrait.png
png=gif? 0
MIME: image/gif

name:index.html
html=gif? 0
MIME: UNKNOWN

As you can see, the program considers "portrait.png" as an image/gif file, while png!= gif, and the function cmp_ins was able to tell the difference (it return 0). Also, the program wasn't able to recognize the type of "index.html".

Could you please tell me what's wrong?

Upvotes: 1

Views: 687

Answers (1)

Slava
Slava

Reputation: 44238

For your comparator to be used with std::map it must satisfy Compare concept:

The return value of the function call operation applied to an object of type Compare, when contextually converted to bool, yields true if the first argument of the call appears before the second in the strict weak ordering relation induced by this Compare type, and false otherwise.

Your comparator seems to return true if objects equal, which is not what required by this concept. You need to rewrite it to satisfy "strict weak ordering relation"

Upvotes: 2

Related Questions