0%

最近遇到一个问题:

须要在20万号段数据中查找对应的地市,并且这个过程是发生在遍历几百万数据中的。也就是说正常情况下须要执行20万*几百万次。

这个时间太久了,且因为号段是长数字,执行起来速度超慢。

后来突然想到可以用二分法。

二分法的原理就是:把有序的数据分为2段,通过比较得到数据在哪段,然后再把这段的数据分为2段,这样就省去了很多不必要的遍历,复杂度O(logn)。

下面两个例子就是二分法的示例,一个是递归,一个是循环。

java二分法循环示例

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
package cn.sunzn.dichotomy;

public class DichotomySearch {
public static void main(String[] args) {
int[] arr = new int[] { 12, 23, 34, 45, 56, 67, 77, 89, 90 };
System.out.println(search(arr, 12));
System.out.println(search(arr, 45));
System.out.println(search(arr, 67));
System.out.println(search(arr, 89));
System.out.println(search(arr, 99));
}

public static int search(int[] arr, int key) {
int start = 0;
int end = arr.length - 1;
while (start <= end) {
int middle = (start + end) / 2;
if (key < arr[middle]) {
end = middle - 1;
} else if (key > arr[middle]) {
start = middle + 1;
} else {
return middle;
}
}
return -1;
}
}

java二分法递归示例

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
/**
* 二分法查找,必须对已经排好序的序列进行查找,假设现在有一个递增序列,取中间位置的数及序号midIndex=(beginIndex+endIndex)/2,
* 然后将一个序列折成两半,beginIndex~midIndex,midIndex~endIndex,如果目标数T等于S[midIndex],找到,
* 否则,如果T<S[midIndex],则在beginIndex~midIndex中继续查找;如果T>S[midIndex],则在midIndex~endIndex
* 中继续查找,如此反复进行,直到找到目标数据,
* 初始对传入参数进行约束及避免无效计算的条件为,T<S[beginIndex]或T>S[endIndex]或beginIndex>endIndex
* 或beginIndex>S.length-1||endIndex>S.length-1||beginIndex<0||endIndex<0
*
*/
package junit.test;

public class BinarySearchTest {
/**
* 找到返回索引下标,否则返回-1;
* @return index
*/
public int binarySearch(int dataset[],int target,int beginIndex,int endIndex){
//数组校验
if(dataset==null||dataset.length==0){
return -1;
}
//beginIndex,endIndex校验
if(beginIndex>endIndex||beginIndex>dataset.length-1||endIndex>dataset.length-1||beginIndex<0||endIndex<0){
System.out.println("error arguments!");
return -1;
}

//无效参数处理
if(target<dataset[beginIndex]||target>dataset[endIndex]||beginIndex>endIndex){
return -1;
}
int midIndex=(beginIndex+endIndex)/2;

//System.out.println(midIndex);
if(target==dataset[midIndex]){
return midIndex;
}
else if(target<dataset[midIndex]){
return binarySearch(dataset,target,beginIndex,midIndex-1);//注意midIndex-1
}
else{
return binarySearch(dataset,target,midIndex+1,endIndex);//注意midIndex+1
}

}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
BinarySearchTest bs=new BinarySearchTest();

int[] data=new int[]{1,3,5,7,9,12};

int index=bs.binarySearch(data,12,0, 5);

System.out.println("The position of the target number in the array is :"+ index);
}

}

后记:算法无穷妙,看来得好好学习下算法。

这两天没事折腾了一下微信的公众号,我的公众号(订阅号,不支持自定义菜单)在右边,有兴趣的可以扫下:)

1. 注册并提交自己的手持身份证照片

2. 简单的订阅的话,可以选择高级功能里面的编辑模式,想要更多功能还是选择开发模式。

3. 在BAE注册并创建移动web应用,我选择的是PHP的。

4. 下载微信接口示例代码,并参考微信接口文档,开启折腾之路。

5. 目前采用了很多第三方API,支持有

*    机器人聊天
*    查天气(发送 城市+天气,如 深圳天气,目前支持全国各省市地区)
*    查PM2.5(同上,如 珠海空气)
*    看笑话(发送 笑话,支持分类)
*    看妹子图(发送 妹子 或者 MM 或者 美女,单次查看妹子图目前有限制:D)
*    藏头诗(发送 藏头诗+任意字句,如 藏头诗徐不猛)
*    翻译(发送 翻译+词句,如翻译i love you)
*    看歌词(发送 歌词+歌曲名,如歌词后来)
*    查域名信息(发送 域名+域名地址,如域名xubumeng.com,或者直接发送域名地址)
*    查IP信息(发送 归属+IP地址,如归属192.168.1.111,或者直接发送IP地址)
*    查看手机归属(同上,如归属13888888888 或者 13888888888)
*    计算器(发送 计算+计算式,如 计算1+1,该功能暂时有些问题,敬请期待更新:p)

6. 更多功能,后续更新,谢谢您的使用,有什么意见和想法可以反馈在下面,cheers:)

好久没写博客了,因为太忙。

至于忙什么,谁也不知道!

这大半年经历挺多的:

  • 女朋友3月来深圳,开始一起生活的日子。
  • 7月6号和女友一起去许昌,全家大团圆。
  • 10月1号和女友一起去同里她妈妈那。
  • 未完待续

每天都很累,也多少感觉一些充实。

时间在过,世界在变。

当时间走过,如果不能留点什么给将来,简直是个遗憾。

所以我决定重新写博客,有空的时候写一点点,以备后看。

加油吧,少年!

windows xp下创建符号链接

今天给女友的电脑设置dropbox同步的时候遇到一个问题,就是她想同步指定的文件夹,
当时立马就想到了windows中的mklink,可惜她用的是悲剧的xp系统,去网上找了下,找到一个junction的东东。
点此下载
使用方法如下:

  1. 下载刚才那个文件,并解压到c:/windows/system32
  2. 打开cmd,进入比如D盘,输入junction d:/linkdir "d:/srcdir"
  3. 删除这个链接可以直接删除链接后的文件夹,也可以用junction -d d:/linkdir

Hello, 这是我的新博客。

它托管在github上。不定时更新。
以前的博客使用wordpress,基于革命同志的俭朴精神,现在使用免费的github+jekyll+markdown。

本博客于2013年5月23正式启用。

于2015年7月21日正式更新2.0,使用免费的github+hexo+markdown.

记得有个人说过,开blog的人有几步:
1.在csdn,iteye这样的网站上开blog
2.自己搞定域名和主机,开blog
3.最终会把blog托管给别的地方。
现在我已经走到第3步了,因为不想折腾这个wp了,虽然开了一年也没怎么折腾,就是写写blog。
本来想搞定域名可以做做自己的网站什么的,但是暂时太忙了,等以后闲下来再说吧。
先准备迁到github上去。
我的github地址:http://xumeng.github.io/

不能打开磁盘vmname- 000001.vmdk或者是所依赖的磁盘快照。原因:创建子磁盘快照后父磁盘被修改过.
某次在vm用linux的快照的时候,不能恢复了,提示上述错误,google it的方案是:
每个虚拟磁盘都有两个附属VMDK文件,较大的文件名称最后有-flat,是虚拟磁盘的实际原始数据。较小的文件是描述符文件,包含虚拟磁盘配置的基本 信息。使用诸如Nano等文本编辑器打开原始磁盘的描述符文件(通常情况下和虚拟机的名称相同,如myvm.vmdk),可以看到列出来的CID和父 CID。第一个磁盘的父CID一般是“ffffffff”,在下面的例子中需要注意快照的父CID和原始磁盘的CID并不一致。
  原始磁盘文件:
  CID=37b6f123
  parentCID=ffffffff
  快照磁盘文件:
  CID=afafa03b
  parentCID=ba4f9916
  为了重新关联父子CID,编辑快照的描述符VMDK文件。标识原始磁盘文件的CID,修改快照磁盘文件的父CID,保证两者一致。如下所示:
  原始磁盘文件:
  CID=37b6f123
  parentCID=ffffffff
  快照磁盘文件:
  CID=afafa03b parentCID=37b6f123
  重新启动虚拟机,就可以顺利重新引导系统了。

PS:如果是分盘的,我们会发现,vmdk1的CID是vmdk2的parentCID,vmdk2的CID是vmdk3的parentCID,依此类推,按顺序修改即可。

flex下载文件的时候很恶心,第一次下载完后,如果服务器上这个文件又修改了,再下载时是还是取的缓存里第一个文件。
通过加随机数(也就是方法二)目测是解决了这个问题,后台仔细测试的时候发现居然在ie中还是不行,在chrome中可以。
后台又找了第一种方法,是ok的。

方法一:
本人解决的方法,保证可用。
添加过滤器(代码如下)
package com.cn.util;

import java.io. ;
import javax.servlet.
;
import javax.servlet.http.HttpServletResponse;

public class ForceNoCacheFilter implements Filter {

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException
{
((HttpServletResponse) response).setHeader(“Cache-Control”,”no-cache”);
((HttpServletResponse) response).setHeader(“Pragma”,”no-cache”);
((HttpServletResponse) response).setDateHeader (“Expires”, -1);
filterChain.doFilter(request, response);
}
public void destroy()
{
}
public void init(FilterConfig filterConfig) throws ServletException
{
}
}

然后在web.xml中添加这个过滤器


NoCache
com.cn.util.ForceNoCacheFilter


NoCache
/*

com.cn.util.ForceNoCacheFilter为刚才过滤器的包名.类名,/*为匹配所有请求。

这样你所有的请求都将会传到服务器处理,不会查看缓存了。

方法二:
inComeHttp.url=”familyGroup.do?method=query&tmp=”+Math.random();
url上随意传一个随机数

今天用sql脚本初始化数据库数据的时候出现在了标题中的错误。
后经检查怀疑是格式或编码的问题。
如果是格式的问题,需要用dos2unix,windows中和linux系统的换行符不同。
命令如下:
dos2unix initData.sql
如果是编码的问题,需要用iconv来转换文件的编码为数据库的编码。
命令如下:
iconv -f fromencode -t toencode fileName

查看数据库编码:
select * from nls_database_parameters where parameter =’NLS_CHARACTERSET’;