大数运算(c、java)

最近看剑指offer的时候,看到c语言操作大数,于是就想用java来写写大数,小伙伴们都表示看不懂,

java有强大的BigInteger和BigDecimal类来支持大数的操作,可是,咸的蛋疼的人总是有的。

目前只完成了加减乘。

java代码

<span style="font-size:18px;">import java.util.Arrays;

public class Test {
	// 将字符串转成整形数组
	static int[] StringToArray(String s) {
		int[] a = new int[s.length()];
		for (int i = 0; i < s.length(); i++) {
			a[i] = Integer.parseInt(s.substring(s.length() - i - 1, s.length()
					- i));
		}
		return a;
	}

	// 大数加法
	static int[] bigDataAdd(int[] a, int[] b) {
		if (a.length < b.length) {
			int[] temp = a;
			a = b;
			b = temp;
		}
		int len = a.length;
		// 多申请一位,存放进位
		int[] c = new int[len + 1];
		int flag = 0;// 判断是否进位

		for (int i = 0; i < b.length; i++) {

			c[i] = (a[i] + b[i] + flag) % 10;
			flag = (a[i] + b[i] + flag) / 10;
		}
		if (a.length == b.length && flag != 0) {
			c[len] = flag;
		} else {
			for (int i = b.length; i < a.length; i++) {
				c[i] = (a[i] + flag) % 10;
				flag = (a[i] + flag) / 10;
			}
			if (flag == 1) {
				c[len] = 1;
			}
		}
		return c;
	}

	// 加法打印结果
	static void printResult1(int[] result) {
		// 判断首位是否为0,为0不输出,不为0正常输出
		if (result[result.length - 1] == 0) {
			for (int i = result.length - 2; i >= 0; i--) {
				System.out.print(result[i]);
			}
		} else {
			for (int i = result.length - 1; i >= 0; i--) {
				System.out.print(result[i]);
			}
		}
	}

	// //将两个数组搞成等长的
	// static void equalLength(int[] a,int[] b){
	// int len = (a.length>b.length)?a.length:b.length;
	// a=Arrays.copyOf(a, len);
	// b=Arrays.copyOf(b, len);
	// // System.out.println(a.length+".."+b.length);
	// }

	// 大数减法:符号暂时没完成
	static int[] bigDataSubtract(int[] a, int[] b) {
		// 将a,b弄成同样长
		int len = (a.length > b.length) ? a.length : b.length;
		a = Arrays.copyOf(a, len);
		b = Arrays.copyOf(b, len);
//		System.out.println(a.length + ".." + b.length);

		int[] c = new int[len + 1];

		// 退位的标志位
		int flag = 0;

		for (int i = 0; i < len; i++) {

			c[i] = ((a[i] - flag) - b[i] + 10) % 10;
//			System.out.print(c[i] + "...");
			flag = (a[i] - flag) - b[i] >= 0 ? 0 : 1;
		}

//		System.out.println("c[len]=" + c[len]);

		if (flag == 0)
			return c;

		if (flag == 1) {
//			c[len] = 45;// 负号的int值为45
			return bigDataSubtract(b, a);
		}

		return c;
	}

	// 减法打印结果
	static void printResult2(int[] result) {
		System.out.println((char) result[result.length - 1]);
		if(result[result.length-2]==0){
			for (int i = result.length - 3; i >= 0; i--) {
				System.out.print(result[i]);
			}
		}else{
			for (int i = result.length - 2; i >= 0; i--) {
				System.out.print(result[i]);
			}
		}
		
	}

	// 乘法
	static int[] multiply(int a[], int b[]) {
		// 实现数组交换
		if (a.length < b.length) {
			int[] temp = a;
			a = b;
			b = temp;
		}
		int c[] = new int[a.length + b.length];
		int flag = 0;
		for (int j = 0; j < b.length; j++) {
			for (int i = 0; i < a.length; i++) {
				c[i + j] += a[i] * b[j];
			}

		}
		for (int i = 0; i < c.length; i++) {
			int temp = c[i];
			c[i] = (temp + flag) % 10;
			flag = (temp + flag) / 10;
//		System.out.println(c[i]);
		}

		return c;
	}
	//乘法打印
	static void printResult3(int[] result) {
//		System.out.println(result.length );
		System.out.println();
		if(result[result.length-1]!=0){
			for (int i = result.length-1; i >= 0; i--) {
				System.out.print(result[i]);
			}
		}else{
			for (int i = result.length-2; i >= 0; i--) {
				System.out.print(result[i]);
			}
		}
		
	}
	
	public static void main(String[] args) {

		int[] a = StringToArray("1800");
		int[] b = StringToArray("1300");
		
		int[] c1 = bigDataAdd(a, b);
		printResult1(c1);
		
		int[] c2 = bigDataSubtract(a, b);
		printResult2(c2);
	
		int[] c3 = multiply(a, b);
				
		printResult3(c3);
	}

}</span>
<span style="font-size:18px;">
</span>
BigInteger类实现大数操作

<span style="font-size:18px;">//java太强大了</span>
<span style="font-size:18px;">import java.math.BigInteger;
class Test1{
	
		//加
		static void add(BigInteger bigInteger1,BigInteger bigInteger2){
		bigInteger1=bigInteger1.add(bigInteger2);	
		System.out.println(bigInteger1);

	}	
		//减
		static void subtract(BigInteger bigInteger1,BigInteger bigInteger2){
			bigInteger1=bigInteger1.subtract(bigInteger2);	
			System.out.println(bigInteger1);

		}
		//乘
		static void multiply(BigInteger bigInteger1,BigInteger bigInteger2){
			bigInteger1=bigInteger1.multiply(bigInteger2);	
			System.out.println(bigInteger1);

		}
		//除
		static void divide(BigInteger bigInteger1,BigInteger bigInteger2){
			bigInteger1=bigInteger1.divide(bigInteger2);	
			System.out.println(bigInteger1);

		}
		//取反
		static void negate(BigInteger bigInteger1){
			bigInteger1=bigInteger1.negate();	
			System.out.println(bigInteger1);

		}
		//阶乘
		static void pow(BigInteger bigInteger1,int n){
			bigInteger1=bigInteger1.pow(n);	
			System.out.println(bigInteger1);

		}
		//取模
		static void remainder(BigInteger bigInteger1,BigInteger bigInteger2){
			bigInteger1 = bigInteger1.remainder(bigInteger2);
			System.out.println(bigInteger1);
			
		}

		public static void main(String[] args)throws Exception{
		BigInteger bigInteger1=new BigInteger("123214325345424");
		BigInteger bigInteger2=new BigInteger("5358038503535");
		
		add(bigInteger1,bigInteger2);
		subtract(bigInteger1,bigInteger2);
		multiply(bigInteger1,bigInteger2);
		divide(bigInteger1,bigInteger2);
		negate(bigInteger1);
		pow(bigInteger1,10);
		remainder(bigInteger1,bigInteger2);
		
		}
		
	}</span>

<strong><span style="font-size:18px;">c语言代码</span></strong>
<strong><span style="font-size:18px;"></span></strong><pre name="code" class="plain">#include<stdio.h>
#include <string.h>
#define M 10


//大数加法
void add(char s1[],char s2[])//参数为两个字符数组
{
	//初始化
	int num1[M]={0};
	int num2[M]={0};
	int i,j;
	
	
	int len1=strlen(s1);
	int len2=strlen(s2);




	for(i=len1-1,j=0;i>=0;i--)
	{
		num1[j++]=s1[i]-'0';
	}
	


	for(i=len2-1,j=0;i>=0;i--)
	{
		num2[j++]=s2[i]-'0';
	}
	for(i=0;i<M;i++)
	{
		num1[i]=num1[i]+num2[i];




		if(num1[i]>9)
		{
			num1[i]=num1[i]-10;
			num1[i+1]++;
		}
	}




	//打印输出
	//找到第一个不是0的位置
	for(i=M-1;(i>=0)&&(num1[i]==0);i--);
		if(i>=0)
		{
			for(;i>=0;i--)
				printf("%d",num1[i]);	
		}
		else 
			printf("0\n");
	
}




int compare(char* s1,char* s2)
{
	int sl1=strlen(s1);
	int sl2=strlen(s2);
	if(sl1>sl2)return 1;
	else if(sl1<sl2)return -1;
	else{
			
		int i=0;
		while(i<sl1-1){
			
			if(s1[i]>s2[i]){
				return 1;
			}else if(s1[i]<s2[i]){
			
				return -1;
			}else{
				i++;
			
			}		
		}
		return 0;
		}
	
}




//大数减法
void subtract(char s1[],char s2[]){
	//初始化
	int num1[M]={0};
	int num2[M]={0};
	int i,j;
	
	
	int len1=strlen(s1);
	int len2=strlen(s2);




	for(i=len1-1,j=0;i>=0;i--){
		num1[j++]=s1[i]-'0';
	}
	


	for(i=len2-1,j=0;i>=0;i--){
		num2[j++]=s2[i]-'0';
}
	int flag=compare(s1,s2);


	if(flag>=0){
		for(i=0;i<M;i++){
		num1[i]=num1[i]-num2[i];


		if(num1[i]<0)
		{
			num1[i]=num1[i]+10;
			num1[i+1]--;
		}


		}
		for(i=M-1;(i>=0)&&(num1[i]==0);i--);
		if(i>=0)
		{
			for(;i>=0;i--)
				printf("%d",num1[i]);	
		}
		else 
			printf("0\n");
	}
	else{
		for(i=0;i<M;i++){
		num2[i]=num2[i]-num1[i];
//		printf("%d",num2[i]);
		if(num2[i]<0)
		{
			num2[i]=num2[i]+10;
			num2[i+1]--;
		}
		
		}


		for(i=M-1;(i>=0)&&(num2[i]==0);i--);
		printf("-");
		if(i>=0)
		{
			for(;i>=0;i--)
				printf("%d",num2[i]);	
		}
		else 
			printf("0\n");		
	
	}


}




void Multiply(char s1[],char s2[])
{
	//初始化
	int num1[M]={0};
	int num2[M]={0};
	int num3[M]={0};
	int i,j;
	
	
	int len1=strlen(s1);
	int len2=strlen(s2);




	for(i=len1-1,j=0;i>=0;i--){
		num1[j++]=s1[i]-'0';
	}
	


	for(i=len2-1,j=0;i>=0;i--){
		num2[j++]=s2[i]-'0';
	}


	for(j=0;j<len2;j++){
		for(i=0;i<len1;i++){
			num3[i+j]+=num1[i]*num2[j];
		}
	}
//	printf("%d\n",num3[0]);


	int flag=0;
	for(i=0;i<M;i++){
		int p=num3[i];
		num3[i]=(p+flag)%10;
		flag=(p+flag)/10;
	}


	for(i=M-1;(i>=0)&&(num3[i]==0);i--){}
	if(i>=0)
			{
			for(;i>=0;i--){
			printf("%d",num3[i]);
			}
		}
	else
			//没有打印0
			printf("0\n");
	
}
<span style="color:#ff0000;">//注意定义char类型的字符串方式</span>
void main()
{
//	char s1[]={'1','2','\0'};
	char s1[]="10000";
	char s2[]="982323";
	Multiply(s1,s2);


}


 总结:java减法一直是困扰我的,因为符号判断很难,策略:1.看长度,但如果长度相同呢,2.只能先运行一遍再判断最高位是否退位了,退位了加负号,这么简单的还是没完成。 



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值