最近看到的两个有意思的算法Sleep Sort与硬币模拟
2011-06-26 13:26
639 查看
连接:/article/5481808.html
Sleep Sort
SleepSort是一个使用多线程不同的休眠时间的排序算法。先看一下原始的版本
相当给力啊。不过不懂Shell脚本的貌似看起来比较困难。比如我--!。其实这个算法主要的思想就是使用将要排序的数字作为线程的休眠时间,然后依次将其输出。我使用Java做了一个简单的实现。
不过此时的Sleep Sort无法进行负数与浮点数的排序。当然,对于负数,可以通过加上一个巨大的数变为正数。但是肯定时间变慢。而且,如果系统线程休眠精度不足的情况下,排序速度肯定不如那些传统的排序方法。
硬币模拟
问题描述:一个硬币向上向下的概率不均等,如何用这枚硬币模拟出一个概率均等的硬币。稍微抽象化一点。有一个随机函数f以p的概率输出1,1-p的概率输出0, 怎样通过这个函数构造一个以0.5概率输出1的函数。在一个群里面的一些牛人给了一个比较好的答案:
这段代码相当于将硬币投两次,组合为11,01,10,00.其中,10与01分别相当于p(1-p),(1-p)p。这两个概率是相等的。故仅仅考虑这两种情况分别输出1与0即可。别的情况不输出,仍做循环。
其中,在循环体内,有人给出了更简洁的写法
当然,也同样有人提出更深一步的问题。如果是构造30%的概率输出1怎么办呢。简单考虑。添加一个硬币,那么硬币的组合将会有2^3=8种,其中分别为000|001|010|011|110|100|101|111.其中,有一个1出现的有三种,为001|010|100.此时我们是不是就可以根据上述思想去构造一个概率分别为1/3与2/3的输出呢。照着这个思路走下去,10个硬币的话,只有一个1出现的情况有10种,那么就可以构造输出为30%为1的程序了。
Sleep Sort
SleepSort是一个使用多线程不同的休眠时间的排序算法。先看一下原始的版本
#!/bin/bash function f() { sleep "$1" echo "$1" } while [ -n "$1" ] do f "$1" & shift done wait ./sleepsort.bash 5 3 6 3 6 3 1 4 7
相当给力啊。不过不懂Shell脚本的貌似看起来比较困难。比如我--!。其实这个算法主要的思想就是使用将要排序的数字作为线程的休眠时间,然后依次将其输出。我使用Java做了一个简单的实现。
package Test; public class SleepSort extends Thread { public int temp; SleepSort(int para) { this.temp=para; } public void run() { try { Thread.sleep(temp); System.out.println(temp); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { try { int[] a = { 1, 1, 7, 2, 9 }; SleepSort[] test=new SleepSort[a.length]; for (int i = 0; i < a.length; i++) { test[i]=new SleepSort(a[i]); test[i].start(); } } catch (Exception e) { e.printStackTrace(); } } }
不过此时的Sleep Sort无法进行负数与浮点数的排序。当然,对于负数,可以通过加上一个巨大的数变为正数。但是肯定时间变慢。而且,如果系统线程休眠精度不足的情况下,排序速度肯定不如那些传统的排序方法。
硬币模拟
问题描述:一个硬币向上向下的概率不均等,如何用这枚硬币模拟出一个概率均等的硬币。稍微抽象化一点。有一个随机函数f以p的概率输出1,1-p的概率输出0, 怎样通过这个函数构造一个以0.5概率输出1的函数。在一个群里面的一些牛人给了一个比较好的答案:
int func() { int i ; int j ; while(true) { i = f() ; j = f() ; if(i == 1 && j == 0) return 1; else if(i == 0 && j == 1) return 0; } }
这段代码相当于将硬币投两次,组合为11,01,10,00.其中,10与01分别相当于p(1-p),(1-p)p。这两个概率是相等的。故仅仅考虑这两种情况分别输出1与0即可。别的情况不输出,仍做循环。
其中,在循环体内,有人给出了更简洁的写法
if(i!=j) return i;
当然,也同样有人提出更深一步的问题。如果是构造30%的概率输出1怎么办呢。简单考虑。添加一个硬币,那么硬币的组合将会有2^3=8种,其中分别为000|001|010|011|110|100|101|111.其中,有一个1出现的有三种,为001|010|100.此时我们是不是就可以根据上述思想去构造一个概率分别为1/3与2/3的输出呢。照着这个思路走下去,10个硬币的话,只有一个1出现的情况有10种,那么就可以构造输出为30%为1的程序了。
相关文章推荐
- 最近看到的两个有意思的算法Sleep Sort与硬币模拟
- 【数据结构与算法C】利用两个栈S1S2模拟一个队列,用栈的基本操作实线EnQueue,DeQueue,QueueEmpty
- ZOJ1016 题解此题一开始想用模拟算法结果调试了很久也没做出来,之后在网上看到这种方法很巧妙,果断采用。
- 【数据结构与算法】求二叉树中两个节点的最近祖先
- 今天看到的两个算法题 ,第一次做这种题目,希望大家提供更好的思路!!
- 【算法导论】33.4:两个最近的点
- 今天在《Exceptional C++》上看到的两个有意思的东西
- 使用最近未使用页淘汰(NRU)算法模拟实现页淘汰进程
- 【算法面试题】寻找二叉搜索树中两个节点的最近公共祖先节点(转)
- 求一颗不含指向父节点指针的普通树中任意两个结点的最近公共祖先(O(N*N) 和 O(N) 算法)
- [算法 笔记] 查找二叉树上任意两个结点的最近共同祖先(更新版本)
- 最近在论坛里面看到一个算法题,简单描述确有些离奇(微软面试题)。。
- git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比如: base'<--base<--A<--A' ^ | --- B<--B' 小米工程师常常需要寻找两个分支最近的分割点,即base.假设git 树是多叉树,请实现一个算法,计算git树上任意两点的最近分割点。 (假设git树节点数为n,用邻接矩阵的形式表示git树:字符串数组matrix包含n个字符串,每个字符串由字符'0
- 哈希分布与一致性哈希算法—在swift中看到这个有意思的算法
- 13、设计一个算法,找出二叉树上任意两个结点的最近共同父结点。
- 第一篇博客文章,发表试试。最近新看到的两道比较有意思的数据结构题
- 算法题----称硬币: 2n(并不要求n是2的幂次方)个硬币,有两个硬币重量为m+1, m-1, 其余都是m 分治 O(lgn)找出假币
- 设计算法查找二叉树的两个结点最近公共祖先(LCA)
- 在二叉树中,求任意两个节点的最近公共祖先(遍历的应用算法)
- 设计一个算法求节点值为x和节点y值得两个节点的最近共同祖先