为了解决:“在1、2、3、......1000000这100W个连续自然数中任意删除2个,再把顺序打乱,请编码快速查找被删除的两个数”。采用JS异或运算如下:
<script type=text/javascript>
var i = 1000000, arr = [], m = n = "";
while (i --) {
    arr.push(i + 1);
}
m = arr.splice(Math.random() * arr.length, 1);
n = arr.splice(Math.random() * arr.length, 1);
//------------------------------------------------
var t = new Date();
var x = 1000000,
j = k = arr.length,
q = w = l = 0;
while (j --) {
    x ^= arr[j];
}
q = w = x;
while (! (q & 1)) {
    q >>= 1,
    l++;
}
while (k --) {
    if (arr[k] >> l & 1) {
        x ^= arr[k];
    }
}
t = new Date() - t;
//------------------------------------------------
document.write("随机删除的两个数为:" + m + " 和 " + n + "<br/>");
document.write("找到被删的两个数为:" + x + " 和 " + [x ^ w] + "<br/>");
document.write("查找被删两数时间为:" + t + "毫秒"); 
</script>
为什么测试1000个以上连续自然数准确,而个数为100或者10会发生错误呢?

解决方案 »

  1.   

    哦,“<br/>”标签被论坛吃掉了,再发HTML的看看:<script type=text/javascript>
    var i = 1000000, arr = [], m = n = "";
    while (i--) {
        arr.push(i + 1);
    }
    m = arr.splice(Math.random() * arr.length, 1);
    n = arr.splice(Math.random() * arr.length, 1);
    //------------------------------------------------
    var t = new Date();
    var x = 1000000,
    j = k = arr.length,
    q = w = l = 0;
    while (j--) {
        x ^= arr[j];
    }
    q = w = x;
    while (! (q & 1)) {
        q >>= 1,
        l++;
    }
    while (k--) {
        if (arr[k] >> l & 1) {
            x ^= arr[k];
        }
    }
    t = new Date() - t;
    //------------------------------------------------
    document.write("随机抽取的两个数为:" + m + " 和 " + n + "<br/>");
    document.write("找到抽取的两个数为:" + x + " 和 " + [x ^ w] + "<br/>");
    document.write("查找时间为:" + t); 
    </script>
      

  2.   

    去掉“/”再试试:<script type=text/javascript>
    var i = 1000000, arr = [], m = n = "";
    while (i --) {
        arr.push(i + 1);
    }
    m = arr.splice(Math.random() * arr.length, 1);
    n = arr.splice(Math.random() * arr.length, 1);
    //------------------------------------------------
    var t = new Date();
    var x = 1000000, j = k = arr.length, q = w = l = 0;
    while (j --) {
        x ^= arr[j];
    }
    q = w = x;
    while (! (q & 1)) {
        q >>= 1,
        l ++;
    }
    while (k --) {
        if (arr[k] >> l & 1) {
            x ^= arr[k];
        }
    }
    t = new Date() - t;
    //------------------------------------------------
    document.write("随机抽取的两个数为:" + m + " 和 " + n + "<br>");
    document.write("找到抽取的两个数为:" + x + " 和 " + [x ^ w] + "<br>");
    document.write("查找时间为:" + t + "毫秒"); 
    </script>
      

  3.   


    谢谢。
    就算法而言,不应该出错的,这不仅仅就JS而言。
    JS的位运算一定还有什么奥妙还未掌握,也许很简单,就像一层窗户纸,我猜。
      

  4.   

    哦,是我写错了,应该这样纸:<script type=text/javascript>
    var i = 1000000, arr = qrr = [], m = n = "";
    while (i --) {
        arr.push(i + 1);
    }
    qrr = arr.concat([]);
    m = arr.splice(Math.random() * arr.length, 1);
    n = arr.splice(Math.random() * arr.length, 1);
    //------------------------------------------------
    var t = new Date();
    var x = 1000000, i = arr.length, j = qrr.length, q = w = l = 0;
    while (i --) {
        x ^= arr[i];
    }
    q = w = x; 
    while (!(q & 1)) {
        q >>= 1, l ++;
    }
    while (j --) {
        if (qrr[j] >> l & 1) {
            x ^= qrr[j];
        }
        if (arr[j] >> l & 1) { 
            x ^= arr[j];
        }
    }
    t = new Date() - t;
    //------------------------------------------------
    document.write("随机抽取的两个数为:" + m + " 和 " + n + "<br/>");
    document.write("找到抽取的两个数为:" + x + " 和 " + [x ^ w] + "<br/>");
    document.write("查找时间为:" + t);
    </script>说明:x的初始值为连续整数间相互异或值,1-10个数的时候为11,1-100、1-1000...等等就等于最大的尾数,有代数式可一步求出来。我依然困惑的是,为什么错误的代码能够在大数量级的连续整数向量空间查找到正确的结果呢?
      

  5.   

    我以为我错了,以为还可以化简,原来是你错了....
    自然数1,2,3...n-1,n 求异或跟n相关。
    switch(n%4){
         case 0:return n;
         case 1:return 1;
         case 2:return n+1;
         case 3:return 0;
    }能在CSDN看到这样的代码,也难得。赞一个!
      

  6.   

    改进。x初始值缺省为0,1 — n个连续整数末尾的n可以为任何数(也可以改写为从m — n不一定从1起始,只要中间连续,但要再索引一路数组,速度会慢些。)。<script type=text/javascript >
    var i = 1000000, arr = qrr = [], m = n = "";
    while (i --) {
        arr.push(i + 1);
    }
    m = arr.splice(Math.random() * arr.length, 1);
    n = arr.splice(Math.random() * arr.length, 1);
    //------------------------------------------------
    var t = new Date();
    var x = y = q = l = k = 0, i = j = arr.length + 3;
    while (i --) {
        x ^= i ^ arr[i];
    }
    q = y = x;
    while (! (q & 1)) {
        q >>= 1, l ++;
    }
    while (j --) {
        if (k = j >> l & 1) {
            x ^= j;
        }
        if (arr[j] >> l & 1) {
            x ^= arr[j];
        }
    }
    t = new Date() - t;
    //------------------------------------------------
    document.write("随机抽取的两个数为:" + m + " 和 " + n + "<br/>");
    document.write("找到抽取的两个数为:" + x + " 和 " + [x ^ y] + "<br/>");
    document.write("查找时间为:" + t + "毫秒");
    </script>