LintCode-232: Tiny Url (System Design 经典题)

这题也是System Design经典题,与Tiny Url II的区别是它要求没有那么严格,不需要生成全局唯一的id。
这两种方案区别如下:

Tiny Url:
long_url <-(256Base mapping)-> id <-(62Base mapping)-> short_key

Tiny Url II:
long_url <-(system generate unique)-> id <-(62Base mapping)-> short_key

这里的short_key就是short_url去掉那个固定头。

具体来说:
1)Tiny Url里面是把long_url通过256 Base转换成一个(long long) id,再把这个id跟short_key通过62 Base 一一对应。要注意long_url和id不一定是一一对应的,所以要加个while循环来检查该id是不是已经用过。而id与short_key的62 Base是严格的一一对应的。
2) Tiny Url II里面long_url和id之间是严格一一对应的,因为是系统生成的全局唯一id。 short_key和id之间也是严格一一对应。

class TinyUrl {
public:
    const long long SIXTY_TWO_POWER_SIX = 56800235584L;
    const string TINYURL = "http://tiny.url/";

     /*
     * @param url: a long url
     * @return: a short url starts with http://tiny.url/
     */
    string longToShort(string &url) {
        long long id = 0;
        for (int i = 0; i < url.size(); ++i) {
            id = (id * 256 + (long long)url[i]) % SIXTY_TWO_POWER_SIX;
        }
        id %= SIXTY_TWO_POWER_SIX;

        while (hashmap.find(id) != hashmap.end() && hashmap[id] != url) id++;

        hashmap[id] = url;
        return TINYURL + id2ShortKey(id);
    }

    /*
     * @param url: a short url starts with http://tiny.url/
     * @return: a long url
     */

    string shortToLong(string &url) {
        string shortKey = url.substr(TINYURL.size());
        //62 based mapping (url -> long long)
        long long id = 0;
        for (int i = 0; i < 6; ++i) {
            char c = shortKey[i];
            if (c >= '0' && c <= '9') id = id * 62 + c - '0';
            if (c >= 'a' && c <= 'z') id = id * 62 + c - 'a' + 10;
            if (c >= 'A' && c <= 'Z') id = id * 62 + c - 'A' + 36;

         }
         return hashmap[id];
    }

private:
    map<int, string> hashmap;  //id to long string

    string id2ShortKey(long long id) {
        const string charSets = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        string shortKey;
        while (id > 0) {
            shortKey = charSets[id % 62] + shortKey;
            id /= 62;
        }

        while (shortKey.size() < 6) {
            shortKey = "0" + shortKey;
        }
        return shortKey;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值