提到大数运算,JAVA绝对赖皮,不像C,JAVA自带大整数(java.math.BigInteger)的库。这方面也是了解了一下,关于大整数,这一篇文章还是讲的很全面的:(6条消息) Java 大数字运算_Darklovy-
题目大概效果就是这样:
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String a;
Scanner scanner=new Scanner(System.in);
a=scanner.nextLine();
BigInteger m=new BigInteger(a);
for (int i=2;i<10;i++){
BigInteger n=BigInteger.valueOf(i);
BigInteger result[]=m.divideAndRemainder(n);
int num=result[1].intValue();
if(num==0){
System.out.print(i+" ");
}
}
}
}
肯定是比纯数组的方法简单的多,有了自带的库无脑往上码就是了。
那么,如果没有这个库,用数组应该怎么做呢。
1.首先,将大数的每一位装进数组。比较通用的方法就是做一个循环一直mod10来求余数。
不过,大数是不能用int来初始化的,我们得到的是一个字符串类型的大数,mod10显然行不通。
于是想到String的toCharArray():
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String a;
Scanner input=new Scanner(System.in);
a=input.nextLine();
char[] c=a.toCharArray();
int[] d=new int[100];
for (int i=0;i<c.length;i++){
d[99-i]=(int)c[i]-48;
}
for (int i=0;i<100;i++){
System.out.print(d[i]);
}
}
}
运行的结果和预期一样。这段代码是我第一时间想到的,当然肯定会有更简洁的代码是可行的,仅做参考。值得注意的是,当我们强制int 类型为char的函数,我们得到的是它的ASCII码,而由于数组的每一个元素都是个位数,所以只要减去48就是我们想要的数字。
然后在循环的时候顺带做个逆序排列,得到的结果:
接下来加减法就很简单了:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String a,b;
Scanner input=new Scanner(System.in);
a=input.nextLine();
b=input.nextLine();
char[] c=a.toCharArray();
char[] e=b.toCharArray();
int[] d=new int[100];
int[] f=new int[100];
int[] res=new int[100];
for (int i=0;i<c.length;i++){
d[i+100-c.length]=(int)c[i]-48;
}
for (int i=0;i<e.length;i++){
f[i+100-c.length]=(int)e[i]-48;
}
for(int i=0;i<100;i++){
res[i]=d[i]-f[i];
if(res[i]<0){
res[i]+=10;
d[i+1]-=1;
}
}
boolean flag=false;
for (int i=0;i<100;i++){
if(res[i]!=0)flag=true;
if(flag)System.out.print(res[i]);
}
}
}
为了表达清楚,有些循环并没有合并,事实上用不到那么多for循环。这里是以减法为例子,答案也是正确的:
加减法是互通的,而难点就在于乘除。
乘除算法略比加减法复杂,先说乘法:
乘法可以想象我们的笔算
很容易想到用二维数组,再利用for循环每次错一位相加。但由于大数相乘除比较复杂,使用数组的性价比实在太低,不如好好掌握大数的库进行运算。因此,我们碰到的很多题目都是大数乘以小数。当然,当一个大数乘以一个个位数就简单多了,只要在对res[I]的计算做一些小改动即可,你也可以将加法循环n次;
那么,除法应该怎么做呢?显然,除法是这里最困难的一种算法,因为需要考虑到有余数的情况,这里就写了大整数除以个位数的情况:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String a;
Scanner input=new Scanner(System.in);
a=input.nextLine();
double b=input.nextDouble();
char[] c=a.toCharArray();
int[] d=new int[100];
int[] res=new int[100];
for (int i=0;i<c.length;i++){
d[i+100-c.length]=(int)c[i]-48;
}
int yu=0;
for(int i=0;i<d.length-1;i++){
double m=d[i];double n=d[i+1];
res[i]=(int)Math.floor((m*10+n)/b);
yu=(int)((m*10+n)%b);
d[i+1]=yu;
}
System.out.println(yu);
boolean flag=false;
for (int i=0;i<99;i++){
if(res[i]!=0)flag=true;
if(flag)System.out.print(res[i]);
}
}
}
虽然比加减法复杂,但应该还是很好想到的。这是我第一时间想到的代码,日后还会完善改良。
计算结果也是正确的:
第一行输出余数,第二行输出商。
总的来说JAVA在写大数的时候还是选择加入BigInteger比较好,今天也是在CSDN上没有找到数组方法的大数运算,于是顺便写了一篇。
学JAVA刚一个月,有不足之处还请大佬指出。