大数是算法语言中的数据类型无法表示的数,其位数超过最大数据类型所能表示的范围,所以,在处理大数问题时首先要考虑的是怎样存储大数,然后是在这种存储方式下其处理的实现方法。
一般情况下大数的存储是采用字符数组来存储,即将大数当作一个字符串来存储,而对其处理是按其处理规则在数组中模拟实现。
大数除法,应该算是四则运算里面最难的一种了。不同于一般的模拟,除法操作步数模仿手工除法,而是利用减法操作实现的。
其基本思想是反复做除法,看从被除数里面最多能减去多少个除数,商就是多少。
我做的思路是先将待除的数后面补零到长度跟被除数一样
循环计算可以被减几次后值为负数,如果为负后,将除数的值去掉一个零,然后将之前不是负数的余数做重复计算,
最后将每次计算的值做大数加和计算,同时最后一次得的余数即为最终的余数
具体的代码如下:
import java.util.ArrayList;
public class Solution {
public static void main(String[] args) {
Solution solution=new Solution();
//System.out.println("423".compareTo("345"));
String aString="123456789012345678901234567890";
String bString="345";
// String temp="fjdk fdjk fjdk ";
// String[] arrStrings=temp.split("\\s{1,}");
int zeronum=0;
String tempbString=bString;
if(tempbString.length()<aString.length())
{
for(int i=0;i<1000;i++)
{
if(tempbString.length()<aString.length())
{
zeronum++;
tempbString+="0";
}
else {
break;
}
}
}
ArrayList<String> arrayList=new ArrayList<String>();
String resultString=aString;
while(zeronum>=0)
{
int nums=0;
String nodivString=resultString;
resultString=bigNumberSub(resultString,tempbString);
if(resultString.indexOf("-")==-1)
{
nums++;
nodivString=resultString;
}
while(resultString.indexOf("-")==-1)
{
resultString=bigNumberSub(resultString,tempbString);
if(resultString.indexOf("-")==-1)
{
nums++;
nodivString=resultString;
}
}
String result1=nums+"";
for(int i=0;i<zeronum;i++)
{
result1+="0";
}
arrayList.add(result1);
zeronum--;
tempbString=tempbString.substring(0,tempbString.length()-1);
resultString=nodivString;
}
//此时结束后的resultString是余数
String buisString="0";
for(int i=0;i<arrayList.size();i++)
{
buisString=bigNumberAdd(buisString, arrayList.get(i));
}
System.out.println(buisString+" "+resultString);
}
public static String bigNumberAdd(String f, String s) {
//翻转两个字符串,并转换成数组
char[] a = new StringBuffer(f).reverse().toString().toCharArray();
char[] b = new StringBuffer(s).reverse().toString().toCharArray();
int lenA = a.length;
int lenB = b.length;
//计算两个长字符串中的较长字符串的长度
int len = lenA > lenB ? lenA : lenB;
int[] result = new int[len + 1];
for (int i = 0; i < len + 1; i++) {
//如果当前的i超过了其中的一个,就用0代替,和另一个字符数组中的数字相加
int aint = i < lenA ? (a[i] - '0') : 0;
int bint = i < lenB ? (b[i] - '0') : 0;
result[i] = aint + bint;
}
//处理结果集合,如果大于10的就向前一位进位,本身进行除10取余
for (int i = 0; i < result.length; i++) {
if (result[i] > 10) {
result[i + 1] += result[i] / 10;
result[i] %= 10;
}
}
StringBuffer sb = new StringBuffer();
//该字段用于标识是否有前置0,如果有就不要存储
boolean flag = true;
for (int i = len; i >= 0; i--) {
if (result[i] == 0 && flag) {
continue;
} else {
flag = false;
}
sb.append(result[i]);
}
return sb.toString();
}
public static String bigNumberSub(String f, String s) {
// System.out.print("减法:" + f + "-" + s + "=");
// 将字符串翻转并转换成字符数组
char[] a = new StringBuffer(f).reverse().toString().toCharArray();
char[] b = new StringBuffer(s).reverse().toString().toCharArray();
int lenA = a.length;
int lenB = b.length;
// 找到最大长度
int len = lenA > lenB ? lenA : lenB;
int[] result = new int[len];
// 表示结果的正负
char sign = '+';
// 判断最终结果的正负
if (lenA < lenB) {
sign = '-';
} else if (lenA == lenB) {
int i = lenA - 1;
while (i > 0 && a[i] == b[i]) {
i--;
}
if (a[i] < b[i]) {
sign = '-';
}
}
// 计算结果集,如果最终结果为正,那么就a-b否则的话就b-a
for (int i = 0; i < len; i++) {
int aint = i < lenA ? (a[i] - '0') : 0;
int bint = i < lenB ? (b[i] - '0') : 0;
if (sign == '+') {
result[i] = aint - bint;
} else {
result[i] = bint - aint;
}
}
// 如果结果集合中的某一位小于零,那么就向前一位借一,然后将本位加上10。其实就相当于借位做减法
for (int i = 0; i < result.length - 1; i++) {
if (result[i] < 0) {
result[i + 1] -= 1;
result[i] += 10;
}
}
StringBuffer sb = new StringBuffer();
// 如果最终结果为负值,就将负号放在最前面,正号则不需要
if (sign == '-') {
sb.append('-');
}
// 判断是否有前置0
boolean flag = true;
for (int i = len - 1; i >= 0; i--) {
if (result[i] == 0 && flag) {
continue;
} else {
flag = false;
}
sb.append(result[i]);
}
// 如果最终结果集合中没有值,就说明是两值相等,最终返回0
if (sb.toString().equals("")) {
sb.append("0");
}
// 返回值
// System.out.println(sb.toString());
return sb.toString();
}
}
计算结果:357845765253175880873143675 15
商为:357845765253175880873143675
余数为:15