针对小数据集和大数据集计算出漂亮数(谷歌面试题)

1.小数据集:

这里表示小于2^31-1的正整数。

2.大数据集:

大于2^31-1的正整数。

3.为何分出大数据集和小数据集:

因为解决小数据集的算法当遇到大数量数据时,往往无法解决

4.何为漂亮数:

输入的数被漂亮数求的余每一位都为1

以下为分别解小数据集和大数据集的java代码:

1.解小数据集
package com.zr.demo;

import java.util.Scanner;

/** @version: 1.0.0
 * @Description: 判断一些比较小的数的漂亮数(注意:比较小是指小于2^31-1,即小于整形的最大值。漂亮数是指:输入的数被漂亮数求的余每一位都为1)
 * @author: ZR
 * @date: 2019年12月26日 下午7:17:30
 */
public class BeautifulNumberSmall {

	/**
	 * 此方法适合处理小于2^31-1d的正整数,大于此数会导致数太大计算机计算时间太长,比如输入5415641564156415641,则需要很长的时间才能计算出结果,效率太低
	 * @param args
	 */
	public static void main(String[] args) {
		//创建键盘输入数据
		Scanner scanner=new Scanner(System.in);
		
		System.out.println("请输入要处理的数据个数,必须为大于0的正整数:");
		//键盘输入要处理的数据个数
		int cases=scanner.nextInt();
		for (int i = 1; i <= cases; i++) {
			System.out.println("请输入要处理的数,必须为大于2的正整数:");
			//输入要处理的数据
			long num=scanner.nextLong();
			for (long j = 2; j < num; j++) {
				//intNum可以保证每次处理的都是num
				long intNum=num;
				//当intNum大于漂亮数时
				while (intNum>0) {
					//判断intNum对j求余是否为1,如果不为1,则不是漂亮数,直接跳出while循环
					if (intNum%j!=1) {
						break;
					}
					//求下一位的余
					intNum/=j;
				}
				//此时得到j为漂亮数
				if (intNum<1) {
					//输出漂亮数
					System.out.println("Beautiful:"+j);
					//跳出当前for循环
					break;
				}
			}
		}
		scanner.close();
	}

}

2.解小数据集
package com.zr.demo;

import java.util.Scanner;

/** @version: 1.0.0
 * @Description: 判断一些比较大的数的漂亮数(注意:比较大是指大于2^31-1,即大于整形的最大值。漂亮数是指:输入的数被漂亮数求的余每一位都为1)
 * @author: ZR
 * @date: 2019年12月26日 下午8:13:19
 */
public class BeautifulNumberLarge {

	/**
	 * 此方法可以处理大于2^31-1d的正整数
	 * @param args
	 */
	public static void main(String[] args) {
		//创建键盘输入数据
		Scanner scanner=new Scanner(System.in);
	
		System.out.println("请输入要处理的数据个数,必须为大于0的正整数:");
		//键盘输入要处理的数据个数
		int cases=scanner.nextInt();
		for (int i = 1; i <= cases; i++) {
			System.out.println("请输入要处理的数,必须为大于2的正整数:");
			//输入要处理的数据
			long num=scanner.nextLong();
			System.out.println("Beautiful:"+beautiful(num));
		}
		scanner.close();
	}

	/**
	 * 获取漂亮数
	 * @param num 处理的数据
	 * @return 返回漂亮数
	 */
	private static Long beautiful(long num) {
		//最高为64位
		for (int bits = 64; bits >=2; bits--) {
			long minRadix=2;
			long maxRadix=num;
			while (minRadix<maxRadix) {
				long midRadix=minRadix+(maxRadix-minRadix)/2;
				//获取漂亮数对应的和
				long sum=getSum(midRadix,bits);
				//System.out.println("sum2:"+sum);
				//如果总和与输入的数据相等,则midRadix为漂亮数
				if (sum==num) {
					return midRadix;
				}else if (sum>num) {//此时漂亮数比midRadix小,即minRadix<漂亮数<midRadix
					maxRadix=midRadix;
				}else {//此时漂亮数比midRadix大,即midRadix<漂亮数<maxRadix
					minRadix=midRadix+1;
				}
			}
		}
		//循环所有的数仍未得到漂亮数,这是不可能的,所以如果抛出这个异常说明代码本身就是错的
		throw new IllegalStateException("Should not reach here.");
	}

	/**
	 * @param radix 
	 * @param bits
	 * @return 返回对应bits位算出的数据总和
	 */
	private static long getSum(long radix, int bits) {
		long component=1;
		long sum=0;
		for (int i = 0; i < bits; i++) {
			if (Long.MAX_VALUE - sum < component) {
		        sum = Long.MAX_VALUE;
		        return sum;
		    } else {
		        sum += component;
		    }

		    if (Long.MAX_VALUE / component < radix) {
		        component = Long.MAX_VALUE;
		    } else {
		        component *= radix;
		    }
		}
		//System.out.println("sum:"+sum);
		return sum;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值