月度归档:2013年11月

AJAX Redirect

By  JQuery , we can very easily handle AJAX

But when some functions the native XMLHTTPREQUEST not support , there are nothing JQuery can do
For example :  A redirect problem

$.ajax({
    type: 'POST',
    url: 'A.html',
    data: '....',
    statusCode: {
        302: function() {
            alert("302"); // this is never called 
        },
        200: function() {
            alert("200"); 
        },
    },
    success: function (data, textstatus) {
        alert('You are now at URL: ' + ??);
    },
    error: function (data) { },
    complete: function (jqXHR, textstatus) {
        alert('You are now at URL: ' + ??);
    },
});



Because the redirect action will be executed by the brower automatic, and will not trigger any event about the redirct.
That means we can’t do something like prevent redirect, although we donot need it for the most times.
However, there is a actual problem when redirct in a AJAX:
 Normally,  `redirect`  means the resource moves to the other place, tell the brower to request the new url.
 Because using AJAX, we use JSON or XML , even HTML as the content-type. When we get the result , use JavaScript parse the result, and show it on page (window)
In the process, we change the page content , but we do not change the location url
That’s the problem, we want to change the location url which showed in the browser’s address bar to reflash the whole page, just like NO AJAX.
How to do ?
Even the XMLHttpRequest2 not support to distinguish the two sections. I mean we can’t detect the redirect happens by XHR API, and cannot get the new url.
If we have the privileges to configue web server like nginx,  then we can resolve it very easily.
nginx:
  add_header x-req-path $request_uri
JavaScript/JQuery:
 new_url =  jxhr.getResponseHeader(‘x-req-path’) || ”
 
if the new_url path not equals the location url then redirected, so your can change the location url to the new_curl or just ignore it

 

 

农历日历 我的周六

又一次想起农历的日历系统,这次是用python。
网上下了个Python的阳历和阴历转换的程序(代号ccal),为了验证正确性,于是有了这篇日志。
计划,先从网上找靠谱的日历统计已有数据对比。
感觉 中国科学院国家授时中心的 时间科普网的在线万年历 应该比较靠谱。
首先分析了下时间科普网站的日梭万年历网络版,其JS被压缩优化。
并且在chrome和IE下不能执行,语法错误。要使用IE兼容模式才可以。
看了下代码,找出了一些JS函数,分析了HTML结构。但是实在难以统计。
想到 Google日历也显示农历,于是爬取Google日历数据。
计划 先统计基本信息,再弄好数据进行对比。
Google 日历 从 2000年 到 2050 年有显示农历数据。
先用 JS 在 chrome 的 console 中 把数据 从 HTML中简单解析出来。
然后 再保存数据到文本中 用 python 解析为日期。
悲剧的是 从网上下的Python程序即ccal是基于 python2,而且 空格 和 Tab 不分,执行不了。
于是 伤心了。开始 思考 如何 有效的对比。对比的关键自然是农历数据。
只好只保存ccal的农历数据,自己解析。突然想到,QQ 日历也是有农历数据的。
虽然 QQ 网站的 JS 也是 被压缩过的,但 只要语法没问题,可以格式化 解析,以前就分析过QQ的JS。比较好弄。
果然,用 chrome 没到1分钟,就找到了 QQ 日历的农历数据。
简单的分析了下JS代码,两者保存农历数据的格式是一致的,只要对比大小 就可以了。
对比发现 有4处不同,分别是农历的1916年、1954年、1956年和1978年的数据 有差异。
谁是错的呢? 自然 查找第三方,人工检索 在线万年历。
如果 手头有本万年历也不错,但印刷也有可能出错。
这个东西 采取 少数服从多数比较好,大家总不会错的一样的吧。后面发现还真有可能~ ,错的人多了 就三人成虎。。。 真理在少数人手中吗?还是先对比数据。
首先 看了下 百度APP 万年历,Nokia的 日历 和 网易邮箱日历(只对比不同之处):
公历1916年1月1日 是 农历1915年冬月二十六日。农历年从公历1916年2月3日到1917年1月22日。
从数据分析有:NETEase 与 QQ 完全相同
农历1916年数据 APP与QQ相同 , Nokia 与 QQ相同
农历1954年数据 APP与ccal相同, Nokia 与 ccal相同
农历1956年数据 APP与ccal相同, Nokia 与 ccal相同
农历1978年数据 APP与ccal相同, Nokia 与 ccal相同
既然 这样 只好 去看 时间科普网站, 发现与 APP,Nokia是相同的。初步认为 这几个是靠谱的。所以。。。其他的就是错的。。。
网易和腾讯错都错的一样,谁抄谁的呢?哈哈。。。不知道
相比之下ccal只错了一个还是很靠谱的。赞一个,特此链接:http://cxterm.sourceforge.net/ccal.html
数据 和 相关代码,整理后 会 发到 github网站上,按 python, javascript ,Java,PHP 的 顺序实现。
先实现基本日历转换,再加上 二十四节气、天干地支纪年法、十二生肖等。
对农历总算掌握了一部分数据,有空的时候再充到2100年。

BTW,因为google的JS和HTML混在一起,弄不清,也不好设断点,只好直接AJAX翻页,然后解析HTML。
还是 灰常感谢 Google 没有屏蔽我,虽然 每次间隔2秒,但也集中请求了600次。
NETEase 的 JS 写的像教科书一样,很好阅读,只进行了压缩,没有进行代码混淆处理。农历日历系统还用了单例模式。卡哇伊~~~

覆盖数字 解题分析

题目详情

给定整数区间[a,b]和整数区间[x,y],你可以使用任意多次a,b之间的整数做加法,可以凑出多少个[x,y]区间内的整数?

输入 a,b,x,y,其中1<= a < b <= 1000000000,  1 <= x < y <= 1000000000。

输出: 用[a,b]内的整数做任意多次加法,可以得到多少个[x,y]内的整数。

例如a = 8, b = 10, x = 3 , y = 20

我们可以得到 [3..20]之间的整数 8, 9, 10, 16 ( 8 + 8), 17(8 + 9), 18(9 + 9), 19(9 + 10), 20(10 + 10),因此输出8。

 

问:2+3=5 1+4=5 这算1个还是2个?

答:算1次 问你能覆盖多少个不同的数字 [x,y]全覆盖住得话 就是y – x + 1。

 

 

难度等级 3 一般难度
根据题意, 可以证明 [a,b] 区间 通过操作 可以得到 [a,b] [2a,2b] [3a,3b] ….. 无穷多个区间。
证明:
 对 任意一个区间 [ka,kb] ,我们知道 ka = a+a+…. a ,  kb = b + b+..b。
 所以 只要 证明 对 区间 (ka,kb) 之间数 可以 被 [a,b] 之间的数 用 加法 表示 即可。
 数学归纳法
      ka+1 = a +a +.. +a + (a+1)  即 最后一个a 换成 a+1。
      假设 t 属于 [ka,kb) 可以 被表示。
      那么 因为 t < kb 所以 t 的表示 中 不是 全部都是 [a,b] 中的最大数b组成的。
      故而 存在一个数c 属于 [a,b) 使得 c+1 属于 (a,b] .
      因此 将t的表示中一个数c 替换成 c+1 , 即可 表示t+1 。
      综上 [ka,kb] 中 每一个数 都可以 被 [a,b] 中的数使用任意多次加法表示。
对以上区间 编号 R1,R2,R3,…  可以知道 每个区间包含的数字个数 为 Cn = nb – na + 1 = n(b-a)+1
所以 从 对任意 1<=p<=q , 区间Rp到 区间Rq 的 这些区间 共包含的数字个数为
            Spq = Cp +.. + Cq = (b-a)(p+q)*(q-p+1)/2 + q-p+1
题目 求 R1,R2,R3… 这些区间 与 [x,y]区间 的 交集的数字的个数。
我们 可以 先求 [x,y] 区间内的 完整的 R区间, 再处理两端的不完整的区间。 当然这两种情况也可能不存在。
① 求 完整区间
   可以证明 ,   当 i=c(x/a) ,j= f(y/b) , i<=j 时 , [ ia,jb] 区间 在 [x,y] 区间内  , (c 表示 上取整,f 表示 下取整)
                也就是 区间 Ri 到 区间Rj 之间的R区间都 属于 [x,y].
   如果 存在 完整R区间,那么 完整R区间 与 [x,y] 的 交集 为 Sij 个。
② 再看 两端 , 即 Ri-1 和 Rj+1 两个 区间 与 [x,y] 的 交集部分
左边:
    当i=1时 Ri-1 即 R0 不属于 [a,b] 区间 或  x 在 Ri-1 与 Ri 之间 时 左边 交集 为空。
    当  x 在 Ri-1区间 内 即  x ∈ ( (i-1)a, (i-1)b ] , 交集为 [x,(i-1)b] 区间 , 交集数字的个数 为 (i-1)b-x+1 。
右边:
    当  y ∈ ( jb, (j+1)a )  时,y 不属于 Rj+1 故而 交集为空
    当  y ∈ [ (j+1)a, (j+1)b )  即 y 在  Rj+1 区间内 时,交集为 [ (j+1)a, y ] 区间 , 交集数字的个数 为 y – (j+1)a+1 。
综上, 即可 求得 交集个数。
对于 R 区间, 我们 还可以 得到 一个结论:
     存在整数M 使得 对任意 一个 大于等于M 的 数字 x  属于 某个或某些R区间。
证明:
    因为 有 无穷个R区间,所以 我们 只要 证明 存在 从 某个R区间 开始 所有 的 R区间 的 相邻区间有交集即可。
    当 (t+1)a <= tb 时 Rt+1 与 Rt 即有 交集,
    解得 t = c(a/(b-a)) >= a/(b-a)
    当 h >= t 时,hb –  (h+1)a = h(b-a) – a >= t(b-a) – a >=0 。
    M = t*a = a*a/(b-a).
   证毕.
 
为了 节约 计算时间, 我们 可以先 判断 以下 几个情况:
当 y < b 时 , 肯定 没有 交集
当 x>=t*a  或 x,y 在 一个 R区间时 , 交集 为 [x,y]
 
 
Java 代码 如下:
 
public static  int howmany(int a,int b,int x,int y)
{
if( a>=|| x>=|| a<1 || x<1 || b>1000000000 || y>1000000000 ){ // 参数检查
return 0;

if(  y < a ){
return 0;
}
int p = x/a , d = ba , n = a/+ ( a%== 0 ? 0 : 1 ) , na = n*a ;
if ( x >= na || (p*<= x && y<= p*b) ){
return yx+1;
}

int s = p+ ( x%==0 ? 0 : 1) , e = y >= na ? n1 : y/b ,c = 0 ;

if( s <= e ){
+= d*(s+e)*(es+1)/2 + es+1 ;
}

if( x <= (s1)*b ){
+= p* x + 1 ;
}

if( y >= (e+1)*a ){
+= y  (e+1)*+ 1;
}
return c;
}

 

test math

本来是打算写一篇解题的博客的,但由于不支持 数学公式,所以 先配置了一下MathJax,来支持 Tex 数据公式。
话说 Wiz 支持 MathJax了,赞一个。
配置过程 很简单,见下面文档。
使用 MathJax写公式 也很简单,不过 弄对齐 试了 好长时间。总算是弄的差不多了。
题目 是 求 字符串重排列后 所有为回文字符串的排列的个数 模1000000007.
MathJax 参考文档

Config