找出所有符合情况的连续正整数_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 找出所有符合情况的连续正整数

找出所有符合情况的连续正整数

 2013/9/7 21:12:48  QuarterLifeForJava  程序员俱乐部  我要评论(0)
  • 摘要:不废话了,直接上代码:packagetest;importjava.util.ArrayList;importjava.util.List;/***题目描述:一个正整数有可能可以被表示为n(n>=2)个连续正整数之和,如:*15=1+2+3+4+5*15=4+5+6*15=7+8*请编写程序,根据输入的任何一个正整数,找出符合这种要求的所有连续正整数序列。*申明:只是提供了一种较好的算法,必然存在更好的*这是我一位同事的算法,思路很不错,借鉴了*缺点
  • 标签:情况
不废话了,直接上代码:
class="java">
package test;

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

/**
 * 题目描述:一个正整数有可能可以被表示为n(n>=2)个连续正整数之和,如:
 * 15=1+2+3+4+5
 * 15=4+5+6
 * 15=7+8
 * 请编写程序,根据输入的任何一个正整数,找出符合这种要求的所有连续正整数序列。
 * 申明:只是提供了一种较好的算法,必然存在更好的
 * 这是我一位同事的算法,思路很不错,借鉴了
 * 缺点:2*i如果大于int的最大范围就不行了
 */
public class Test {
	
	private static int maxNum =0;
	
	private static List<int[]> list= new ArrayList<int[]>();
	
	public static void main(String[] args) {
		long start=System.currentTimeMillis();
		int num=15;
		calculate(num);
		show(num);
		long end = System.currentTimeMillis();
		System.out.println(end -start);
	}
	
	//核心算法
	private static void judge(int i,int num){
		//maxNum要理解为项数,同时也表示连续整数和最多也就maxNum项
		//因此对于16最多maxNum(6)项相加
		/**
		 * 第一轮:
		 * 第一次:1+2+3+4+5+6 	符合结束循环,不符合继续
		 * 第二次:1+2+3+4+5		符合结束循环,不符合继续
		 * 第三次:1+2+3+4			符合结束循环,不符合继续
		 * 第四次:1+2+3 			符合结束循环,不符合继续
		 * 第五次:1+2				符合结束循环,不符合继续
		 * 第六次:1 				符合结束循环,不符合继续
		 * 
		 * 第二轮:
		 * 第一次:2+3+4+5+6+7 	符合结束循环,不符合继续
		 * 第二次:2+3+4+5+6		符合结束循环,不符合继续
		 * 第三次:2+3+4+5 		符合结束循环,不符合继续
		 * 第四次:2+3+4 			符合结束循环,不符合继续
		 * 第五次:2+3 			符合结束循环,不符合继续
		 * 第六次:2
		 * 
		 * 第最后轮:
		 * 第一次:8+9+10+11+12+13  符合结束循环,不符合继续
		 * 第二次:8+9+10+11+12	符合结束循环,不符合继续
		 * 第三次:8+9+10+11 		符合结束循环,不符合继续
		 * 第四次:8+9+10 			符合结束循环,不符合继续
		 * 第五次:8+9 			符合结束循环,不符合继续
		 * 第六次:8				符合结束循环,不符合继续
		 */
		
		/** 因为是等差数列,当只知道首项(i)和项数(maxNum)时,
		 *  要求首项+末项的和(当然末项也是能求出的,这里用不到)
		 *  公式为:(2*i+maxNum-1)=首项+末项的和=首项*2+项数-1
		 */
		//judgeNum=(首项+末项的和)*项数
		int judgeNum =maxNum*(2*i+maxNum-1);
		while(judgeNum >=2*num){
			if(judgeNum == 2*num){
				int[] a=new int[2];
				a[0]=i;//得到的是首项
				a[1]=maxNum;//得到的是项数
				list.add(a);
				break;
			}else{
				maxNum --;
				if(maxNum < 0){
					break;
				}
				judgeNum=maxNum*(2*i+maxNum-1);
			}
		}
	}
	
	//得到项数,该方法用法只执行一次
	private static int getMaxNum(int start,int num){
		int count =0;
		int i=0;
		for(i=start;i<num;i++){
			count+=i;
			if(count >=num){
				System.out.println(i);
				return i;
			}
		}
		return num;//为了满足语法,其实是根本不会走到的
	}
	
	private static void calculate(int num){
		maxNum=getMaxNum(1,num);//得到项数
		/**
		 * 以15为例
		 * 1+2+...+15    //其中加到某一个数,有可能符合情况
		 * 2+3+4+...+15  //其中加到某一个数,有可能符合情况
		 * ...           //其中加到某一个数,有可能符合情况
		 * 7+8+...+15    //其中加到某一个数,有可能符合情况
		 * 最多加到其一半的情况,即15最多是7+8,永远不可能是8+9
		 * 所以一个数最多加到其一半,不然就要超过这个数了
		 * 如101最多50+51,永远不可能从51开始,即51+52
		 */
		for(int i=1;i<=num/2;i++){
			judge(i,num);
		}
	}
	
	/**
	 * 这里是输出的逻辑,虽然输出看似比较繁琐,但是占用的时间很少,不影响效率
	 * a[0]=i;       //得到的是首项
	 * a[1]=maxNum;  //得到的是项数
	 */
	private static void show(int num){
		for(int i=0;i<list.size();i++){
			int[] ret=list.get(i);
			int start =ret[0];
			int count=ret[1];
			int[] show =new int[count];
			System.out.print(num+" = ");
			int flag =0;
			for(int j=0;j<count;j++){
				show[j]=start+j;
				if(j==0){
					System.out.print(" "+show[j]);
				}else{
					System.out.print(" +"+show[j]);
				}
				flag ++;
				if(flag >20000){
					System.out.println();
					flag =0;
				}
			}
			System.out.println();
		}
	}
}
发表评论
用户名: 匿名