[LintCode][System Design] Tiny Url II

Problem

As a follow up for Tiny URL, we are going to support custom tiny url, so that user can create their own tiny url.

Solution

class TinyUrl2 {
private:
    const long long hashSize = 62 ^ 6;
    map<long long, string> id2long;
    map<string, long long> long2id;
    const string tinyHeader = "http://tiny.url/";
    map<string, string> custom2long;
    map<string, string> long2custom;

public:
    /**
     * @param long_url a long url
     * @param a short key
     * @return a short url starts with http://tiny.url/
     */
    string createCustom(string& long_url, string& short_key) {
        string tinyURL = tinyHeader + short_key;
        if (custom2long.count(short_key) > 0) {
            if (custom2long[short_key] == long_url) {
                return tinyURL;
            } else {
                return "error";
            }
        }
        
        if (long2custom.count(long_url) > 0) {
            if (long2custom[long_url] == short_key) {
                return tinyURL;
            } else {
                return "error";
            }
        }
        
        long long id = shortURL2id(short_key);
        if (id2long.count(id) > 0) {
            if (id2long[id] == long_url) {
                return tinyURL;
            } else {
                return "error";
            }
        }
        
        custom2long[short_key] = long_url;
        long2custom[long_url] = short_key;
        
        return tinyURL;
    }

    char number2char(int n) {
        if (n <= 9) {
            return '0' + n;
        } else if (n <= 35) {
            return 'a' + (n - 10);
        } else {
            return 'A' + (n - 36);
        }
    }
    
    long long char2number(char c) {
        if ('0' <= c && c <= '9') {
            return c - '0';
        } else if ('a' <= c && c <= 'z') {
            return c - 'a' + 10;
        } else if ('A' <= c && c <= 'Z') {
            return c - 'A' + 36;
        }
        return 0;
    }
    
    long long shortURL2id(string url) {
        long long id = 0;
        for(int i = 0; i < url.size(); i++) {
            id = id * 62 + char2number(url[i]);
        }
        return id;
    }
    
    string longToShort(string& url) {
        if (long2custom.count(url) > 0) {
            return tinyHeader + long2custom[url];
        }
        
        long long number = 0;
        for(int i = 0; i < url.size(); i++) {
            number = (number * 256 + (long long)url[i]) % hashSize;
        }
        
        while (id2long.count(number) > 0 && id2long[number] != url) {
            number++;
        }
        id2long[number] = url;


        string shortURL;
        while (number > 0) {
            int mod = number % 62;
            number /= 62;
            //shortURL = number2char(mod) + shortURL;
            shortURL.push_back(number2char(mod));
        }
        
        while (shortURL.size() < 6) {
            // shortURL = "0" + shortURL;
            shortURL.push_back('0');
        }
        
        reverse(shortURL.begin(), shortURL.end());
        shortURL = tinyHeader + shortURL;
        
        return shortURL;
    }

    /**
     * @param url a short url starts with http://tiny.url/
     * @return a long url
     */
    string shortToLong(string& url) {
        string urlWithoutHeader = url.substr(tinyHeader.size(), url.size());

        int id = shortURL2id(urlWithoutHeader);
        if (id2long.count(id) > 0) {
            return id2long[id];
        }
        
        if (custom2long.count(urlWithoutHeader) > 0) {
            return custom2long[urlWithoutHeader];
        }
        
        return "";
    }
};
    原文作者:楷书
    原文地址: https://www.jianshu.com/p/494e0dca106b
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞