蒙特卡洛算法求主元素
问题描述:设T是一个含有n个元素的数组,当数组中的对数组中任一元素x超过数组的长度的一半时,称x是数组的主元素。给定一个数组,求该数组的主元素
1.从数组中随机取一个元素判断是否是主元素
public static boolean check(int[] arr)
{
boolean flag=false;
count=0;
Random rd=new Random();
random=rd.nextInt(arr.length);
for(int i=0;i<arr.length;i++)
{
if(arr[random]==arr[i])
{
count++;
}
if(count>arr.length/2)
{
flag=true;
break;
}
}
return flag;
}
2.上述check算法如果返回true,说明队列中一定含有主元素。但是,返回值为false的情况下,并不能确定数组中是不含主元素的,而且,由于数组非主元素数量小于n/2,所以上述情况发生的概率一定是小于1/2的。
所以,对于给定e>0,用一个算法重复log(1/e)次调用check,可以使这个问题的错误概率降低到e一下。
public static boolean majority(double e,int[] arr)
{
double s=Math.log(1/e)/Math.log(2.0);
for(int i=0;i<=s;i++)
{
if(check(arr))
return true;
}
return false;
}
主函数和测试
public static void main(String[] args) {
int[] arr;
Scanner sc=new Scanner(System.in);
System.out.println("输入数组的长度(输入0退出):");
int n=sc.nextInt();
while(n!=0)
{
System.out.println("请输入数组中的元素:");
arr=new int[n];
for(int i=0;i<n;i++)
{
arr[i]=sc.nextInt();
}
if(majority(0.01, arr))
System.out.println(arr[random]+"是数组的主元素");
else
System.out.println("该数组不含主元素");
System.out.println("输入数组的长度(输入0退出):");
n=sc.nextInt();
}
System.out.println("程序结束");
}
}