【算法设计与分析基础】1、埃拉托色尼筛选法

就是筛选从1到n(不包括n)之间的所有质数

 

package algorithm.ch01;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.junit.Test;

/**
 * 实现埃拉托色尼筛选法
 * @author xiaof
 *
 */
public class Sieve {
	
	/**
	 * 输入正整数 n > 1 
	 * 输出:包含所有小于等于N的质数数组
	 * @param n
	 * @return
	 */
	public static List<Integer> result(int n)
	{
		if(n <= 1)
			return null;	//数据不合规范
		//初始化,遍历数据,初始化容量是n
		List<Integer> initData = new ArrayList<Integer>(n);
		//0到n-1一共是n个数据
		for(int value = 0; value < n; ++value)
		{
			initData.add(value);
		}
		
		//筛选数据
//		向上取整用Math.ceil(double a)
//		向下取整用Math.floor(double a)
		int midValue = (int) Math.floor(Math.sqrt(n));
		for(int p = 2; p <= midValue; ++p)
		{
			//判断这个序号的数据是否是为空的
			if(initData.get(p) != 0)
			{
				//求双倍这个数据,因为后面的遍历开始就是重这个数据开始的
				//相应的((2p~(p-1)p)这个区间的数据已经被前面的遍历消除了
				int doubleValue = initData.get(p) * initData.get(p);
				while(doubleValue < n)
				{
					//只要这个数据还在数组中数据范围内,消除这个倍数数据
					initData.set(doubleValue, 0);
					doubleValue += initData.get(p);	//添加一个倍数
				}
			}
		}
		
		//提取结果数据
		List<Integer> result = new LinkedList<Integer>();
		for(int k = 1; k < n; ++k)
		{
			if(initData.get(k) != 0)
			{
				result.add(initData.get(k));
			}
		}
		
		return result;
	}
	
	@Test
	public void test1()
	{
		int n = 26;
		List<Integer> result = Sieve.result(n);
		Sieve.printOut(result);
	}
	
	public static void printOut(List<Integer> result)
	{
		result.set(result.indexOf(1), null);  //1不属于质数
		for(Integer num : result)
		{
			if(num != null)
				System.out.print(num + "\t");
		}
	}
}

  

 

posted @ 2017-02-23 10:09  cutter_point  阅读(266)  评论(0编辑  收藏  举报