`
handrenliang
  • 浏览: 34092 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

大数相乘的算法

阅读更多

昨天去参加某个公司的面试,前面的聊天还是挺愉快的,最后他给我出了道题,叫我算1000的阶乘。首先的想法是递归或者循环计算,但是思考了一下1000的阶乘的结果int和long肯定是存不下的,改用BigInteger别人不允许,最后就结果可想而知---被深深地鄙视了。我肯定是吞不下这口气啊,五分钟不够你就让我写出来,还是只有笔和纸。回到小窝,怀着郁闷和悲愤的心情,坚决攻克。最后就有如下的成果了。

测试结果:

1000的阶乘139ms,结果长度为2568;

10000的阶乘21909ms,结果程度为35660

 

代码如下:

 

	/**
	 * 计算从Start到end的乘积
	 * 
	 * @param start
	 *            开始索引
	 * @param end
	 *            结束索引
	 * @return 结果的字符串
	 */
	private static String getNumber(int start, int end) {
		String str = Integer.toString(start);
		for (int i = start; i < end; i++) {
			str = getBigInteger(str, Integer.toString(i + 1));
		}
		return str;
	}

 

// 计算两个数的乘积,任何长度
	private static String getBigInteger(String str1, String str2) {
		// 字符串长度
		int len1 = str1.length();
		int len2 = str2.length();

		// 存储最先添加的尾数
		StringBuffer buffer = new StringBuffer();
		// 存储最后一次加法运算的结果
		StringBuffer b = new StringBuffer();

		// 存储每一位相乘的结果
		int[] result = new int[len1 + 1];

		// 将字符串转换为整型数组
		char[] temp1 = str1.toCharArray();
		char[] temp2 = str2.toCharArray();

		int[] num1 = new int[len1];
		int[] num2 = new int[len2];

		// 初始化数组
		for (int i = 0; i < len1; i++) {
			num1[i] = Character.getNumericValue(temp1[i]);
		}
		// System.out.println();
		for (int j = 0; j < len2; j++) {
			num2[j] = Character.getNumericValue(temp2[j]);
		}

		// 计算每一位相乘的结果
		for (int i = len2 - 1; i >= 0; i--) {
			// 进位
			int carry = 0;
			// 从最低位算起
			for (int j = len1 - 1; j >= 0; j--) {
				// 加上进位和上一次运算结果的第j位得到该位的值
				int res = num2[i] * num1[j] + carry + result[j];
				carry = 0;
				// 如果结果大于等于10,得到进位值
				if (res >= 10) {
					carry = res / 10;
				}
				// 得到该位的结果
				result[j + 1] = res % 10;
				if (i <= 0 && j < len1 - 1) {
					b.append(result[j + 1]);
				}
			}
			// 最高位为进位值
			result[0] = carry;
			// 添加结果的最后一位
			buffer.append(result[len1]);
			if (i <= 0) {
				// 添加最高位
				b.append(result[0]);
				buffer.append(b);
			}
		}

		return reverseStringAndClearZero(buffer.toString());
	}

 

// 反向输出结果并且去掉最前面的0
	private static String reverseStringAndClearZero(String str) {
		StringBuffer buffer = new StringBuffer();
		boolean isZero = true;
		for (int i = str.length() - 1; i >= 0; i--) {
			if (isZero && str.charAt(i) != '0') {
				isZero = false;
			}
			if (!isZero) {
				buffer.append(str.charAt(i));
			}
		}
		return buffer.toString();
	}

 

小子不才,速度只能这样了,如果哪位大侠有更好的解决方案,请告知,谢谢

0
0
分享到:
评论
3 楼 cloud21 2011-05-18  
月影无痕 写道
如果是应用中确实存在这个需求,那么我的解决办法可能就是预先缓存数据结果:

也就是说,将1--1000的阶乘结果直接编译到程序中,以后在程序中调用时,可以直接使用,无须消耗CPU资源。

即使消耗,也仅仅是程序第一次计算阶乘的时间代码


说的很有道理了。
2 楼 bobo 2010-10-26  
月影无痕 写道
如果是应用中确实存在这个需求,那么我的解决办法可能就是预先缓存数据结果:

也就是说,将1--1000的阶乘结果直接编译到程序中,以后在程序中调用时,可以直接使用,无须消耗CPU资源。

即使消耗,也仅仅是程序第一次计算阶乘的时间代码


空间换时间,相当于做了个缓存,看项目中使用的频率来采用不同的策略吧

另没有仔细阅读这个大数相乘的算法,是否可以理解自己实现一个BigInt的类以及乘法,这样参考BigInteger的源代码就好了
1 楼 月影无痕 2010-10-20  
如果是应用中确实存在这个需求,那么我的解决办法可能就是预先缓存数据结果:

也就是说,将1--1000的阶乘结果直接编译到程序中,以后在程序中调用时,可以直接使用,无须消耗CPU资源。

即使消耗,也仅仅是程序第一次计算阶乘的时间代码

相关推荐

    大数相乘算法c语言

    以下是对大数相乘算法的详细解释: 1. 数组表示大数:由于C语言的int类型不能存储非常大的数,我们可以使用数组来代替。每个数组元素代表大数的一位,数组的索引对应于位值,如从低位到高位存储。 2. 基本原理:...

    大数相乘,算法源码分析及实现

    随着数字的增大,标准的整数...总的来说,理解和实现大数相乘算法不仅有助于提升计算效率,也是深入理解计算机科学底层机制的关键步骤。通过源码分析,我们可以更好地了解算法的工作原理,并优化其在特定环境下的性能。

    大数相乘算法,java代码,包含独立大数相加算法

    大数相乘算法,java代码,包含独立大数相加算法 其中bigNumberPlus(String s1,String s2)为大数相加方法 bigNumberMultiply(String s1,String s2)为大数相乘方法

    两个大数相乘算法

    大数相乘算法是基础且关键的一环,它涉及到如何高效地计算两个超过普通整型变量所能表示范围的数的乘积。本主题将深入探讨如何用C语言实现大数相乘,并展示结果。 C语言本身并不直接支持大数运算,但我们可以自定义...

    大数相乘算法解析,实现20位的大数相乘

    【大数相乘算法解析】 在计算机科学中,处理大数是常见的问题,尤其是在加密算法、数学计算或金融计算等领域。对于20位左右的大数相乘,我们可以通过设计特定的算法来高效地完成。这里介绍一种基于数组表示的大数...

    大数相乘算法,用CSharp实现

    大数相乘算法,用CSharp实现,经过测试,应该没错了

    A*B 大数相乘 算法 很具有研究性。无错误!

    ### A*B大数相乘算法分析与实现 #### 核心知识点 1. **大数相乘背景**:在计算机科学中,对于超出标准整型数据类型范围的大数进行乘法运算是一项挑战。传统的整数乘法算法在处理非常大的数字时可能会导致溢出问题...

    三个不同大数相乘算法源代码

    大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码...

    C++实现大数相乘算法

    C++实现大数相乘算法 本文详细介绍了C++实现大数相乘算法的过程,包括算法原理、代码实现和结果分析。下面是对该知识点的详细解释: 一、算法原理 大数相乘算法的基本思路是模拟人工计算时的方法,即从低位向高位...

    大数相乘_大数相乘_python_分治_

    虽然Python内置的乘法运算可能已经足够快,但对于特定场景,例如在性能受限的设备上或需要优化计算时间的场合,自定义的大数相乘算法如Karatsuba算法可能会提供显著的优势。 总的来说,理解并掌握大数相乘的分治...

    C++实现的大数相乘算法示例

    C++实现的大数相乘算法示例 在计算机科学中,大数相乘是指那些相乘结果或是乘数本身用long long类型都会溢出的数字。这些数字通常通过string类型进行表示,借助于可动态调整大小的数据结构(vector,string,deque)...

    大数相乘,x^y的实现

    在大数相乘算法中,我们使用了一个循环来实现逐位相乘。在每次循环中,我们将当前位的数字相乘,并将结果加上前一位的进位。然后,我们将结果存储在一个新的字符数组中,并将进位保存到下一位中。 除了大数相乘算法...

    C++自定义API函数实现大数相乘算法

    本文详细介绍了C++自定义API函数实现大数相乘算法,主要包括普通的乘法计算、char版本的大数相乘算法和string版本的大数相乘算法。通过这些算法可以解决大数相乘问题,提高程序的效率。 一、普通的乘法计算 在C++...

    课题名称:大数相乘.pdf

    大数相乘算法设计与实现 大数相乘是计算机科学中一个经典的问题,如何高效地实现大数相乘运算是很多开发者和研究者所关心的。为了解决这个问题,本文将介绍一个基于栈的大数相乘算法的设计和实现。 算法设计 本...

    大数相乘代码及解析

    本文将深入分析一个使用字符数组实现的大数相乘算法,并通过具体的代码进行解释。 #### 二、问题背景与需求 在很多情况下,我们可能需要处理非常大的数字,这些数字超出了基本数据类型(如`int`、`long`等)所能...

    C++实现大数相乘的算法

    本文将介绍一种基于字符串表示的大数相乘算法,这种方法适用于C++编程环境。 首先,我们要理解大数相乘的基本原理。假设我们要相乘的两个大数分别为A和B,它们分别由m和n位组成。根据乘法规则,A的每一位与B的每一...

    大数相乘解决无限位数相乘问题

    大数相乘的算法多种多样,其中包括经典的Karatsuba算法、Toom-Cook算法,以及更为高效的FFT(快速傅里叶变换)算法。其中,Karatsuba算法是一种分治策略,它将两个数分别拆分为较小的部分,然后利用递归关系进行计算...

    大数相乘算法

    一个大数乘以一个short类型,也提供大数显示

    数据结构课程设计之大数相乘求解

    4. **大数相乘算法**:链表实现大数相乘的基本思路是采用经典的竖式乘法,但需要将其转换为链表操作。首先,将两个大数的每一位转换为链表节点,然后逐位相乘并累加结果,最后处理进位。这通常涉及到两个主要步骤:...

Global site tag (gtag.js) - Google Analytics