分治算法经典案例分析-01 --大整数相乘问题

首先,我们来复习一下分治算法的思想:将一个大的问题,分解成 若干个性质相同或相似的小的问题(最好是独立的),每一个小的问题是可以求解的。再将小的问题,合并成原的大的问题。

而为了解决一个给定的问题,算法要一次或多次地递归调用 其自身来解决相关的子问题。这些算法通常采用 分治策略。

所以说,分治算法我递归调用是一对孪生的兄弟。

分治算法的三个步骤:

   分解:将一个问题分解成一系列子问题。

   解决:递归地解决各个子问题,(若子题足够小,通常n=1,或n=2时,则可以直接求解)

   合并:将子问题的结果可以完全合并成原问题的解(这是采用分治算法必要的条件。,也是最重要的一步。)


请设计一个有效的算法,可以进行两个n位大整数的乘法运算。

设X和Y都是n位的二进制整数,现在要计算它们的乘积XY。我们可以用小学所学的方法来设计一个计算乘积XY的算法,但是这样做计算步骤太多,显得效率较低。如果将每2个1位数的乘法或加法看作一步运算,那么这种方法要作O(n2)步运算才能求出乘积XY。

对于非2进制数,也一样。(135 *45)

135*
412204
515255
相加
41220 
 51525
6075
package ch02;

import java.util.Scanner;

public class Demo9 {

	static int N=100;
	static int a[]=new int[N];
	static int b[]=new int[N];
	static int c[]=new int[2*N];
	static String s1=new String(); 
	static String s2=new String(); 
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Demo9 demo=new Demo9();
		demo.Input();
		demo.Multiply(a, b, c);
		demo.Output();
	}
	
	private void Output() {
		System.out.println("result=");
		int flag=2*N-1;
		while(c[flag]==0) {
			if(flag==0) {
				System.out.println("0");
				return ;
			}
			flag--;
		}
		for(int i=flag;i>=0;i--) {
			System.out.print(c[i]);
		}
		System.out.println("");
	}
	
	private void Multiply(int a[],int b[],int c[]) {
		//逐个相乘
		for(int i=0;i<N;i++) {
			for(int j=0;j<N;j++) {
				c[i+j]+=a[i]*b[j]; //很重要的一点,这是,加号,这里有加号~~
			}
		}
		for (int i : c) {
			System.out.print(i+",");
		}
		//移位、进位
		for(int i=0;i<2*N-1;i++) {
			c[i+1]+=c[i]/10; //很重要的一点,这是,加号,这里有加号~~
			c[i]=c[i]%10;
		}
		System.out.println("=====================================================");
		for (int i : c) {
			System.out.print(i+",");
		}
	}
	
	private void Input() {
		Scanner scanner=new Scanner(System.in);
		System.out.println("input two big data:");
		s1=scanner.nextLine();
		s2=scanner.nextLine();
		GetDigit(s1, a);
		GetDigit(s2, b);
	}
	
	private static void GetDigit(String s,int a[]) {
		int len=s.length();
		for(int i=0;i<len;i++) {
			a[len-1-i]=s.charAt(i)-'0';
		}
		//test
//		System.out.println("test:");
//		for(int i=0;i<N;i++) {
//			System.out.print(a[i]);
//		}
//		System.out.println();
		//
	}
}
由以上分析可知,这算法的复杂度为O(m*n)有些高。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值