HackerRank

Yes just an implementation problem.. a lot of typing work.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <sstream>
#include <set>
#include <string>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <unordered_set>
using namespace std;

typedef unsigned long UL;
typedef unsigned long long ULL;

struct Rec
{
    UL        oid;
    string    did;
    string    email;
    string    street;
    string    city;
    string    state;
    string    zip;
    string    ccd;
};

void decode(const string &in, Rec &r)
{
    size_t len = in.size();

    int inx = 0;
    int i = 0;
    string buf;
    while (i < len)
    {
        char c = in[i];
        if (c == ',')
        {
            switch (inx)
            {
            case 0:
                {
                istringstream in(buf);
                UL ul_oid; in >> ul_oid;
                r.oid = ul_oid; break;
                }
            case 1:
                r.did = buf; break;
            case 2:
                r.email = buf; break;
            case 3: 
                r.street = buf; break;
            case 4:
                r.city = buf; break;
            case 5:
                r.state = buf; break;
            case 6:
                r.zip = buf; break;            
            }
            inx++, i++;
            buf.clear();
            continue;
        }
        buf += c;
        i++;
    }
    r.ccd = buf; 
}

void trim(string &s)
{
    size_t len = s.length();

    int l = 0, r = 0;
    int i = 0;
    while (i < len)
    {
        if (isspace(s[i]))
            l++;            
        else
            break;
        i++;
    }
    i = len - 1;
    while (i >= 0)
    {
        if (isspace(s[i]))
            r++;
        else break;
        i--;
    }
    s = s.substr(l, len - l - r);
}

void toLowerAll(string &s)
{
    std::transform(s.begin(), s.end(), s.begin(), ::tolower);
}

void reformat(Rec &r)
{
    trim(r.did);
    trim(r.email);    toLowerAll(r.email);

    //
    string em;
    int i = 0;
    size_t len = r.email.length();
    bool bAppend = true;
    while (i < len)
    {
        char c = r.email[i];
        if (c == '.')
        {
            i++;
            continue;
        }
        if (c == '+')    bAppend = false;
        if (c == '@')    bAppend = true;
        if (bAppend)
        {
            em += c;
        }
        i++;
    }
    r.email = em;

    //
    trim(r.street); toLowerAll(r.street);
    string::size_type fi;
    if ((fi = r.street.find("rd.")) != string::npos)
    {
        r.street.replace(fi, 3, "road");
    }
    if ((fi = r.street.find("st.")) != string::npos)
    {
        r.street.replace(fi, 3, "street");
    }

    trim(r.city);    toLowerAll(r.city);
    trim(r.state);    toLowerAll(r.state);
    if ((fi = r.state.find("illinois")) != string::npos)
    {
        r.state.replace(fi, strlen("illinois"), "il");
    }
    if ((fi = r.state.find("california")) != string::npos)
    {
        r.state.replace(fi, strlen("california"), "ca");
    }
    if ((fi = r.state.find("new york")) != string::npos)
    {
        r.state.replace(fi, strlen("new york"), "ny");
    }
    trim(r.zip);    
    string nzip; i = 0;
    while(i < r.zip.length())
    {
        char c = r.zip[i];
        if(c == '-') break;
        nzip += c;
        i ++;
    }
    r.zip = nzip;

    trim(r.ccd);
}

int main()
{
    set<UL> ret;

    unordered_map<string, pair<string, set<UL>>> m1; // email   + did -> ccd, oids
    unordered_map<string, pair<string, set<UL>>> m2; // address + did -> ccd, oids

    int n; cin >> n;
    string dum; getline(cin, dum);
    while (n--)
    {
        string ln;    getline(cin, ln);
        Rec r;
        decode(ln, r);
        reformat(r);
        
        //    Rule 1
        string k1 = r.email + r.did;
        if(m1.find(k1) == m1.end())
        {
            set<UL> oids; oids.insert(r.oid);
            m1[k1].first = r.ccd;
            m1[k1].second.insert(r.oid);
        }
        else
        {
            if(m1[k1].first != r.ccd)
            {
                ret.insert(m1[k1].second.begin(), m1[k1].second.end());
                ret.insert(r.oid);
            }
            else
            {
                m1[k1].second.insert(r.oid);
            }
        }

        //    Rule 2
        string k2 = r.street + r.city + r.state + r.zip + r.did;
        if(m2.find(k2) == m2.end())
        {
            set<UL> oids; oids.insert(r.oid);
            m2[k2] = make_pair(r.ccd, oids);
        }
        else
        {
            if(m2[k2].first != r.ccd)
            {
                ret.insert(m2[k2].second.begin(), m2[k2].second.end());
                ret.insert(r.oid);
            }
            else
            {
                m2[k2].second.insert(r.oid);
            }
        }
    }

    for(auto it = ret.begin(); it != ret.end(); it ++)
    {
        if(it != ret.begin())
            cout << ",";
        cout << *it;        
    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/tonix/p/4594469.html