- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章java短网址服务(TinyURL)生成算法由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前不久做了一个优惠劵的分享功能,其中一个功能就是生成一个优惠劵分享短链接。生成的短链接要求每个链接都是唯一的,并且长度尽可能短。在网上查了一下相关的思路,发现了一个不错的算法。这个算法的思路就是用[a-za-z0-9]建立一个长度为62的矩阵,然后把矩阵打乱,再生成一个全局唯一的数字,再把这个数字用矩阵内的元素表示转换成62进制,生成的链接长度最大才11位。所以短链接的生成关键点就变成了如何生成一个全局唯一的数字和实现进制的转换.
1、生成全局唯一的数字 。
这本质是一个分布式id的问题。如果简单处理的话可以借用redis的incr操作这样每次取到的id都是单调递增且唯一的。另外一种方式是借用mysql,这里不是借用mysql的主键的auto_incr特性。而是每一台应用来请求时分配一个范围比如 s1 [100-200], s2 来请求的时候就分配 [201-301],本质是利用乐观锁进行一个cas操作.
如果不想借助外部去生成id的话,可以用uuid算法。uuid长度12个字节组成由,以下几个部分组成.
uuid是一类算法的统称,具体有不同的实现。优点是每台机器可以独立产生id,理论上保证不会重复,所以天然是分布式的,缺点是生成的id太长,不仅占用内存,而且索引查询效率低.
还有一个叫twitter snowflake算法,本质上看起来与uuid有些类似。 。
总的来说redis,mysql解决方案就比较简单直接可以满足大部分的场景,如果要保证高性能和高可用的话uuid和twitter snowflake算法就更合适,实现起来相对复杂一些。 。
2、进制转换 。
这个操作就相对简单了。直接上代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
/**
* 短链接生成
*/
public
class
tinyurl {
public
static
final
char
[] array =
{
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'q'
,
'w'
,
'e'
,
'r'
,
't'
,
'y'
,
'u'
,
'i'
,
'o'
,
'p'
,
'a'
,
's'
,
'd'
,
'f'
,
'g'
,
'h'
,
'j'
,
'k'
,
'l'
,
'z'
,
'x'
,
'c'
,
'v'
,
'b'
,
'n'
,
'm'
,
'q'
,
'w'
,
'e'
,
'r'
,
't'
,
'y'
,
'u'
,
'i'
,
'o'
,
'p'
,
'a'
,
's'
,
'd'
,
'f'
,
'g'
,
'h'
,
'j'
,
'k'
,
'l'
,
'z'
,
'x'
,
'c'
,
'v'
,
'b'
,
'n'
,
'm'
};
public
static
map<character, integer> charvaluemap =
new
hashmap<character, integer>();
//初始化map
static
{
for
(
int
i =
0
; i < array.length; i++) charvaluemap.put(array[i], i);
}
public
static
void
main(string[] args) {
for
(
int
i =
0
; i <
100
; i++) {
long
number =
long
.max_value - i;
string decimalstr = numberconverttodecimal(number,
62
);
system.out.println(number +
" 转换成 "
+ decimalstr);
long
tonumber = decimalconverttonumber(decimalstr,
62
);
system.out.println(decimalstr +
" 转换成 "
+ tonumber);
}
}
/**
* 把数字转换成相对应的进制,目前支持(2-62)进制
*
* @param number
* @param decimal
* @return
*/
public
static
string numberconverttodecimal(
long
number,
int
decimal) {
stringbuilder builder =
new
stringbuilder();
while
(number !=
0
) {
builder.append(array[(
int
) (number - (number / decimal) * decimal)]);
number /= decimal;
}
return
builder.reverse().tostring();
}
/**
* 把进制字符串转换成相应的数字
* @param decimalstr
* @param decimal
* @return
*/
public
static
long
decimalconverttonumber(string decimalstr,
int
decimal) {
long
sum =
0
;
long
multiple =
1
;
char
[] chars = decimalstr.tochararray();
for
(
int
i = chars.length -
1
; i >=
0
; i--) {
char
c = chars[i];
sum += charvaluemap.get(c) * multiple;
multiple *= decimal;
}
return
sum;
}
}
|
这里面有个小优化就是用charvaluemap记录每个字符对应的数值,这是一个用空间换时间的策略优化,把o(n)的时间降为o(1).
另外通常我们要记录短网址与长网址的对应的关系,相对于直接存储短网址的而言,存储对应的数值id会更省空间.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
最后此篇关于java短网址服务(TinyURL)生成算法的文章就讲到这里了,如果你想了解更多关于java短网址服务(TinyURL)生成算法的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在通过 NodeSchool.io 练习学习 React 和 Express 框架。 我想将所有练习文件存储在具有多个页面的单个应用程序中,例如 索引 索引2 索引3 索引4 .... local
从这里:http://developer.android.com/reference/android/os/AsyncTask.html doInBackground(URL... urls) onP
我最近收到了一封电子邮件,其中包含以下内容(请勿点击!): UNS 这是原始电子邮件的链接:https://gist.github.com/anonymous/16963a230cab0a3a1bc
在 android 中,可以单击带有 URL 的 TextView 以在网络中打开 URL,方法是: android:autoLink="web" 我想做的是捕获这次点击,如果这个 TextView
我在我的网站上以 mysite.anotherdomain.org 的形式实现 Facebook 登录。我在 JavaScript SDK 的文档中做了所有解释,但由于我遇到了一些问题,我想知道错误是
我在 window.location.href 中有响应网址,我需要其中的 error、error_description 和 state 的值 http://localhost:4200/#erro
我正在创建无限加载,意味着当用户到达页面底部/特定 div 时会加载新页面。目前我有这个代码可以在点击时加载新页面。 $("#about").click(function(){ // load
当我们在谷歌引擎中搜索时,它也会显示热门网站标签或链接。就像我们搜索“bing”或“net beans”时一样。 问:它如何显示这些链接。我们是否必须告诉它显示这些链接。 问:它是否与 sitemap
我想从我的网址中获取我的产品。例如: http://www.website.com/product-category/iphone 我想获取 iphone,这对我的代码来说没问题,但我有一个下拉菜单来
我对 Pythonanywhere 完全陌生,我不知道为什么静态文件没有加载...这是我存储 css 和图像的路径,即 static/images/wikiLang.png 等 /static/adm
我正在使用这个正则表达式来验证 youtube 网址。 ^http:\/\/(?:www\.)?youtube.com\/watch\?(?=.*v=\w+)(?:\S+)?$ 它很好用。 但我有这个
我刚刚在 gist.github 上传了一个我正在处理的小编码项目,因为它似乎是一次上传几个类的好方法。 我想将某人与我的“要点”联系起来,并在角落里写着: Public Clone URL: git
我正在使用 jQuery 验证引擎来解析我的表单数据: https://github.com/posabsolute/jQuery-Validation-Engine 验证 Twitter URL 的
我有一个 Django 应用程序,它可以在 localhost 上正常工作。即使对于 utf-8 URL 路径也是如此。但是当我在生产中使用它时,它给了我一个错误: 2019-09-01 14:32:
我已经安装了Laravel并开始尝试编写一个应用程序。我在/ app所在的目录中为 Assets 创建了一些目录。但是,当我尝试访问本地主机中的图像时,例如:http://localhost/asse
我们正在寻找一种方法来检查一长串 YouTube 网址,以查找目前私有(private)、已删除或不再可用的视频。我们可以检查状态,但即使视频不再公开可用,URL 也会返回 200。例如这两个: ht
我在 YouTube 上有现场事件,我想在我的网站上播放它。我想将我的事件设为私有(private),获取它的 RTMP 广播 URL 并将其粘贴到我的网站上,在 JWPlayer 中。 那可能吗?
当我在谷歌上搜索我的域时,它会显示我网站上的几个 https 网址,因为谷歌喜欢 https,但出于特殊原因我不想索引 https/ssl 版本。 如何避免这种情况,全世界都只通过 htaccess
我想获取在 Salesforce.com 授权期间作为回调收到的当前 URL。 url 中的数据位于片段部分。 最佳答案 您可以使用 $_SERVER['HTTP_HOST'] 和 $_SERVER[
我正在使用 ionic 创建一个应用程序,其中我使用 iframe 显示 URL。 这是 HTML 代码: 这是 Angular js: $scope.iframeHeight = windo
我是一名优秀的程序员,十分优秀!