美团的笔试题中的一种大数除法的方法
2015-09-12 21:42
316 查看
大数是算法语言中的数据类型无法表示的数,其位数超过最大数据类型所能表示的范围,所以,在处理大数问题时首先要考虑的是怎样存储大数,然后是在这种存储方式下其处理的实现方法。
一般情况下大数的存储是采用字符数组来存储,即将大数当作一个字符串来存储,而对其处理是按其处理规则在数组中模拟实现。
大数除法,应该算是四则运算里面最难的一种了。不同于一般的模拟,除法操作步数模仿手工除法,而是利用减法操作实现的。
其基本思想是反复做除法,看从被除数里面最多能减去多少个除数,商就是多少。
我做的思路是先将待除的数后面补零到长度跟被除数一样
循环计算可以被减几次后值为负数,如果为负后,将除数的值去掉一个零,然后将之前不是负数的余数做重复计算,
最后将每次计算的值做大数加和计算,同时最后一次得的余数即为最终的余数
具体的代码如下:
计算结果:357845765253175880873143675 15
商为:357845765253175880873143675
余数为:15
一般情况下大数的存储是采用字符数组来存储,即将大数当作一个字符串来存储,而对其处理是按其处理规则在数组中模拟实现。
大数除法,应该算是四则运算里面最难的一种了。不同于一般的模拟,除法操作步数模仿手工除法,而是利用减法操作实现的。
其基本思想是反复做除法,看从被除数里面最多能减去多少个除数,商就是多少。
我做的思路是先将待除的数后面补零到长度跟被除数一样
循环计算可以被减几次后值为负数,如果为负后,将除数的值去掉一个零,然后将之前不是负数的余数做重复计算,
最后将每次计算的值做大数加和计算,同时最后一次得的余数即为最终的余数
具体的代码如下:
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
相关文章推荐
- Android 动画深入分析
- 用eclipse做的一个短信发送器,编译通过但是部署到模拟器上面出错
- SCOI2009 windy数
- HDU 5432 BC - Pyramid Split(二分 + 模拟)
- i++ i-- 问题小记
- 2015-09-09 [一点资讯]--数据抓取和处理工程师--5面
- 1.Objective-C基础学习
- Jq将页面值传至模态框的用法
- 网络性能测试工具iperf详细使用图文教程
- php添加mysql扩展
- 11.tftp和nfs服务器
- 窗口-CCF测试往届题
- 如何在Android模拟器上安装apk文件
- Hadoop/spark安装实战(系列篇3) Hadoop 伪分布模式安装
- 一个简单的jsp+servlet实例,实现简单的登录
- java练习:打印 数字1、2、3、4的组合,不能以4开头,1和3不能相邻,且数字不能重复
- shell script
- [vb.net]最简单的邮件发送
- php环境的搭建
- 样式表单位