怎样计算171!

看不懂也懒得看你这些高端算法,反正我给你算出来了。。。怎样计算171!

最后结果是:1241018070217667823424840524103103992616605577501693185388951803611996075221691752992751978120487585576464959501670387052809889858690710767331242032218484364310473577889968548278290754541561964852153468318044293239598173696899657235903947616152278558180061176365108428800000000000000000000000000000000000000000==================================================================不行,我要更新一下,就在我昨天在评论区回复了"方法嘛。。。有空再研究,哈哈哈",然后关了电脑睡觉时来了灵感。。。今天**的还要上课,不开心。我也自己实现了一个,我**的把toString方法写错了,然后最开始测试的数据有点小,然后,然后,然后,,,package cn.xinxi.test;import java.util.HashMap;import java.util.Map;/** * Created by xinxi on 2016/3/21. */public class Test {private enum NumOrLength {NUM, LENGTH }/** * 当put操作达到一定程度后需要整理一下 */ private static long total = 0; private static class MyNumber {/* 用于存放数,将数按照位拆分,key为位数,value为对应位上的数,比如 6952: key -\u0026gt; value 1 2 2 5 3 9 4 6 */ private Map\u0026lt;Integer, Long\u0026gt; nums = new HashMap\u0026lt;\u0026gt;(); /** * 使用给定数构造一个MyNumber * * @param num MyNumber对象代表的值 */ public MyNumber(int num) {this(num, NumOrLength.NUM); }/** * 使用给定数或长度构造一个MyNumber * * @param num 一个数 * @param nol 指定num参数值是MyNumber对象代表的值,还是MyNumber的长度 */ public MyNumber(int num, NumOrLength nol) { construct(String.valueOf(num), nol); }/** * 使用给定数构造一个MyNumber * * @param num 一个数 * @param nol 指定num参数值是MyNumber对象代表的值,还是MyNumber的长度 */ private void construct(String num, NumOrLength nol) {switch (nol) {case NUM:// ABCDE int length = num.length();// 5 for (int i = 0; i \u0026lt; length; i++) {int digit = Integer.parseInt(num.charAt(i) + "");// 取出第1位的数字 put(length - i, digit);// (5,A)(4,B)(3,C)(2,D)(3,E) }break; case LENGTH: ensureCapacity(Integer.parseInt(num)); break; } }//--------------------------------------------------------------------------------------- /** * 确保Map结构有足够多的位数 * * @param expectCapacity */ private void ensureCapacity(int expectCapacity) {// 当前Map结构中最多存放位数 int currentMaxLength = nums.size(); // 如果当前要放进去的位(pow)比Map中最多存放位数大,则需要扩展位 if (expectCapacity \u0026gt; currentMaxLength) {/* 这个地方感觉动态扩容会好点 数比较小的话,一次扩充10个位有点浪费啊 数太大,一次扩充10个又不是很给力 唉,什么玩意儿,说的好像要扩充很多次一样,就算2000位也才200次。。。 */ increaseCapacity(expectCapacity + 10); } }/** * 增加位数到指定值 * * @param capacity */ private void increaseCapacity(int capacity) {int currentMaxLength = nums.size(); for (int i = currentMaxLength + 1; i \u0026lt;= capacity; i++) {nums.put(i, 0L); } }/** * 对Map结构进行整理,使每一位上的数小于10 * 比如:第1位12,第2位5表示的数是12+50=65,整理后1位5,2位6 */ private void reorganize() {int currentMaxLength = nums.size(); for (int i = 1; i \u0026lt;= currentMaxLength; i++) { Long old = nums.get(i);// 整理前第i位存放的数 if (old \u0026gt;= 10) {nums.put(i, old % 10); // 如果第i位的数大于10,那么整理后第i+1位一定有数,先确保Map结构有i+1位这么长 ensureCapacity(i + 1); // 第i+1位的数 = 已经放在该位的数 + 第i位/10 nums.put(i + 1, nums.get(i + 1) + old / 10); }// 上面ensureCapacity(..)中可能使Map结构变长了。。。 currentMaxLength = nums.size(); } }/** * 取Map结构中某一位的数 * * @return */ public long get(int index) {return nums.get(index); }/** * 获取当前数实际长度 * * @return */ public int getSize() {int i = nums.size(); for (; i \u0026gt; 0; i--) {if (nums.get(i) != 0) {break; } }return i; }@Override public String toString() { reorganize(); // 从高位开始,从第一个非0位开始将后面的数全部取出 StringBuilder sb = new StringBuilder(); for (int i = getSize(); i \u0026gt;= 1; i--) { sb.append(nums.get(i)); }return sb.toString(); }/** * 将某一位添加到实际存放数的Map结构中 * * @param pow 第几位 * @param digit 第pow位上对应的数字,比如ABCDE第4(pow=4)位对应数字为B */ public void put(int pow, long digit) { ensureCapacity(pow); // pow位上的数 = 当前要放入的 + 已经存在的数 nums.put(pow, digit + nums.get(pow)); // 防止某一位上的数太大,超出了int范围最大值 total += digit; // 这个Long.MAX_VALUE \u0026gt;\u0026gt; 13可以自己弄一个顺眼的,不要太大了,否则待会儿累加会出问题,至于我这里为什么选Long最大值右移13位,你管我啊。。。 // 好吧,其实是经过几次测试,13表现还不错。。。。 if (total \u0026gt; Long.MAX_VALUE \u0026gt;\u0026gt; 13) { reorganize(); total = 0; } }/** * 与指定数相乘 * * @param target 指定一个数 * @return 相乘结果 */ public MyNumber multiply(MyNumber target) {int thisSize = this.getSize(); int targetSize = target.getSize(); //9999(4位) * 999(3位) \u0026lt; 100000 * 1000 = 5 + 4位 = 4+1 + 3+1位 = 4 + 3 +2位 MyNumber result = new MyNumber((thisSize + targetSize + 2), NumOrLength.LENGTH); /* 位 数1 数2 1 A D 2 B E 3 C F 数1:A + 10*B + 100*C 数2:D + 10*E + 100*F 结果:AD + 10*(AE+BD) + 100*(AF+CD+BE) + 1000*(BF+CE) + 10000*CF AD添加到第一位 AE、BD添加到第二位 AF、CD、BE添加到第三位 BF、CE添加到第四位 CF添加到第五位 第i位和第j位的结果应该被放入i+j-1位,比如: B在第二位,F在第三位,BF就应该被放在第2+3-1=4位 */ for (int i = 1; i \u0026lt;= thisSize; i++) {for (int j = 1; j \u0026lt;= targetSize; j++) { result.put(i + j - 1, this.get(i) * target.get(j)); } }return result; }/** * 计算阶乘 * * @return */ private static MyNumber factorial(int num) {if (num == 1) {return new MyNumber(1); } else {return new MyNumber(num).multiply(factorial(num - 1)); } } }public static void main(String args) { long start = System.currentTimeMillis(); MyNumber result = MyNumber.factorial(171); System.out.println("171的阶乘是:" + result.toString()); long end = System.currentTimeMillis(); System.out.println("耗时:" + (end - start)); }}


推荐阅读