诚恳向高手求教一个JS位运算错误问题

prototyper 2012-11-19 12:53:34
为了解决:

“在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会发生错误呢?
...全文
190 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
JParser 2012-11-20
  • 打赏
  • 举报
回复
我以为我错了,以为还可以化简,原来是你错了.... 自然数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看到这样的代码,也难得。赞一个!
prototyper 2012-11-20
  • 打赏
  • 举报
回复
哦,是我写错了,应该这样纸:

<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...等等就等于最大的尾数,有代数式可一步求出来。 我依然困惑的是,为什么错误的代码能够在大数量级的连续整数向量空间查找到正确的结果呢?
宛飓如风 2012-11-20
  • 打赏
  • 举报
回复
弱弱的问一下算法的过程。。。麻烦楼主解释下。
prototyper 2012-11-20
  • 打赏
  • 举报
回复
改进。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>
prototyper 2012-11-19
  • 打赏
  • 举报
回复
哦,“<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>
prototyper 2012-11-19
  • 打赏
  • 举报
回复
引用 3 楼 xzy21com 的回复:
算法很深奥,但确实不准确: 随机抽取的两个数为:186 和 82找到抽取的两个数为:954 和 850查找时间为:1毫秒 随机抽取的两个数为:6270 和 2542找到抽取的两个数为:12030 和 16238查找时间为:0毫秒 1000,10000刷新几次同样会有错误的情况。
谢谢。 就算法而言,不应该出错的,这不仅仅就JS而言。 JS的位运算一定还有什么奥妙还未掌握,也许很简单,就像一层窗户纸,我猜。
scscms太阳光 2012-11-19
  • 打赏
  • 举报
回复
算法很深奥,但确实不准确: 随机抽取的两个数为:186 和 82找到抽取的两个数为:954 和 850查找时间为:1毫秒 随机抽取的两个数为:6270 和 2542找到抽取的两个数为:12030 和 16238查找时间为:0毫秒 1000,10000刷新几次同样会有错误的情况。
prototyper 2012-11-19
  • 打赏
  • 举报
回复
去掉“/”再试试:

<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>

87,997

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧