2018-03-09 15:19:04
TinyURL,短地址,或者叫短鏈接,指的是一種互聯網上的技術與服務。此服務可以提供一個非常短小的URL以代替原來的可能較長的URL,將長的URL地址縮短。
用戶訪問縮短后的URL時,通常將會重定向到原來的URL。
大多數的URL縮短服務都提供有API。URL縮短服務在Twitter等一些每條消息有字數限制的微博客及其他社交網絡中有廣泛的使用。
一、TinyURL的興起原因
由於某些類似於Twitter的微博客服務對於每條貼子或消息有字數限制(多為140字)。某些BBS文章超過一行78個字符時,也會造成一些會自動為網址加上超鏈接的Telnet及BBS軟件無法正確運行該動作,因此需要通過縮短網址的功能來達到網址縮短的目的。
縮址另外也有方便用戶記憶及發送網址的功能,短址可將太長的網址轉換成15個字以內的替代網址,也有部分網站提供自定義名稱以及密碼保護的功能,可以讓用戶獲取更有自己風格的短網址。
二、實現算法
問題描述:實現一個算法,將長地址轉成短地址。實現長和短一一對應。然后再實現它的逆運算,將短地址還能換算回長地址。
問題求解:
方法一、使用最簡單的列表來進行保存,當前的附加位就是其在列表中的序號。這種方法可以很容易的實現長短的轉換,但是也有明顯的不足。
- 如果我們對同一URL多次進行申請,可以得到多個不同的短鏈接,這無疑會造成浪費。
- 使用者可以發現已經有多少URL進行過轉換了,這個信息是我們不希望用戶得到的。
- 或許有人會為了得到一個喜歡的數字,反復不斷的進行申請
- 如果僅僅使用數字的話,那么6位數字的表達能力是很差的,最多也就是百萬級別,如果加入字母的話效果會好很多。
class Codec: def __init__(self): self.urls = [] def encode(self, longUrl): self.urls.append(longUrl) return 'http://tinyurl.com/' + str(len(self.urls) - 1) def decode(self, shortUrl): return self.urls[int(shortUrl.split('/')[-1])]
方法二、
針對上面提出的各種問題,我們在方法二中會一一解決。
首先是重復問題,對於已經生成的短鏈接,我們會維護一個longToTiny的hash表,如果當前的長鏈接已經出現了,那么就直接返回之前生成的TinyURL。
然后是數字的信息泄漏問題,我們這里使用隨機數的方法來生成6位的隨機數,這里的6位能表達的范圍位62^6,是個非常龐大的數字。
最后是使用隨機數可能會生成一樣的序列,於是采用一個Set來保存已經出現的序列,直到生成未出現的序列。
public class TinyURL { Map<String, String> tinyToLong = new HashMap<String, String>(); Map<String, String> longToTiny = new HashMap<>(); Set<String> flag = new HashSet<>(); // Encodes a URL to a shortened URL. public String encode(String longUrl) { if (longToTiny.containsKey(longUrl)) return longToTiny.get(longUrl); String code = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; String base = "http://tinyurl.com/"; String key = ""; do { for (int i = 0; i < 6; i++) { key += code.charAt((int)Math.random() * code.length()); } } while (flag.contains(key)); flag.add(key); tinyToLong.put(base + key, longUrl); longToTiny.put(longUrl, base + key); return base + key; } // Decodes a shortened URL to its original URL. public String decode(String shortUrl) { return tinyToLong.get(shortUrl); } }