zoukankan      html  css  js  c++  java
  • [LeetCode] Encode and Decode Tiny URL | 短网址算法

    https://leetcode.com/problems/encode-and-decode-tinyurl

    一种做法是对于每一个请求的longURL,从0开始按递增的顺序用一个整数与之对应,这个整数就是对longURL的编码,同时做为索引;对短网址解码时,解析出短网址中的整数信息,查找原来的长网址即可。

    class Solution {
    public:
        // Encodes a URL to a shortened URL.
        string encode(string longUrl) {
            long_urls.push_back(longUrl);
            return "http://t.com/" + std::to_string(long_urls.size()-1);
        }
    
        // Decodes a shortened URL to its original URL.
        string decode(string shortUrl) {
            auto pos = shortUrl.find_last_of('/');
            auto id = std::stoi(shortUrl.substr(pos+1));
            return long_urls[id];
        }
        
    private:
        vector<string> long_urls;
    };
    

    递增方法的好处是编码的结果都是唯一的,但是缺点也是明显的:对相同的longURL,每次编码的结果都不同,存在id和存储资源的浪费。改用哈希表可以解决空间浪费的问题,但是递增方法会把短网址的计数器暴露给用户,也许存在安全隐患。

    改进的方法是用字符串去设计短网址,仅仅考虑数字和字母的话,就有10+2*26=62种,变长编码自然是可行的,但是编码规则可能比较复杂,定长编码足够了。至于多长,据说新浪微博是用7个字符的,$62^7 approx 3.5 imes 10^{12}$,这已经远远超过当今互联网的URL总数了。于是,一个可行的做法是:对每个新到来的长URL,随机从62个字符中选出7个构造它的key,并存入哈希表中(如果key已经用过,就继续生成新的,直到不重复为止,不过重复的概率是很低的);解码短网址时,在哈希表中查找对应的key即可。

    另外,为了不浪费key,可以再开一个哈希表,记录每个长网址对应的短网址。

    class Solution {
    public:
        Solution() {
            short2long.clear();
            long2short.clear();
            dict = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
            len_tiny = 7;
            srand(time(NULL));
        }
        
        // Encodes a URL to a shortened URL.
        string encode(string longUrl) {
            if (long2short.count(longUrl)) {
                return "http://t.com/" + long2short[longUrl];
            }
            string tiny = dict.substr(0, len_tiny);
            while (short2long.count(tiny)) {
                std::random_shuffle(dict.begin(), dict.end());
                tiny = dict.substr(0, len_tiny);
            }
            long2short[longUrl] = tiny;
            short2long[tiny] = longUrl;
            return "http://t.com/" + tiny;
        }
    
        // Decodes a shortened URL to its original URL.
        string decode(string shortUrl) {
            auto pos = shortUrl.find_last_of('/');
            auto tiny = shortUrl.substr(pos+1);
            return short2long.count(tiny)? short2long[tiny] : shortUrl;
        }
        
    private:
        unordered_map<string, string> short2long, long2short;
        string dict;
        int len_tiny;
    };
    

    参考:

  • 相关阅读:
    C# 协变 逆变
    go slice 理解
    为什么避免使用Task.Wait或者Task.Result
    IL笔记
    docker随笔
    领域事件
    总结笔记
    基于ASP.NET Core 3.x的端点路由(Endpoint Routing)实现控制器(Controller)和操作(Action)分离的接口服务
    CentOS7 多IP搭建SOCKS5代理服务器
    Springboot 实现数据库备份还原
  • 原文地址:https://www.cnblogs.com/ilovezyg/p/7009357.html
Copyright © 2011-2022 走看看