堆栈集合做大数字运算

来源:互联网 发布:电子版世界名画淘宝店 编辑:程序博客网 时间:2024/05/22 06:57

做大数字运算有操作类BigDi什么的这个操作类,为什么还使用堆栈集合做?1:运用堆栈到代码,熟悉堆栈,2:怎么用生活和代码结合解决问题。



使用堆栈集合,就把数字进行一个一个的进栈,一个一个的出栈,拿着一个一个的出栈数值,进行加法运算,由于堆栈集合的特点,先进的在下面,于是取值的时候,是取得高位(后面)的数,进行加法运算,小学做的数学加法,也是这种结构,一个一个加,从后往前加。


咋们运用小学做加法的办法:一个一个加,从后往前加,虽然小学做加法是有运算结构的,不过,不要这种结构大乱数字,其内核就是这个口诀:一个一个加,从后往前加。


所以咋们程序中,可以运用到生活的一些解决办法来解决问题。虽然形式上不一样,但是本质上大同小异,思路很重要,借助于生活也许会事半功倍,会剖析生活的人做程序也牛啊。


运用熟悉堆栈集合是小,往大处,运用生活解决问题的本质来关联从程序解决生活的问题,这可不好搞,我没有丰富的生活体验经验,剖析生活也没那么灵活的思路,不过我有基本的逻辑,需要开拓视野即可,这叫经验。丰富丰富。


代码如下:

String num1 = "9999";
String num2 = "1";


char[] fenjie1 = num1.toCharArray(); // 9999
char[] fenjie2 = num2.toCharArray(); // 1


@SuppressWarnings("rawtypes")
Stack duizhan1 = new Stack();
Stack duizhan2 = new Stack();


for (char object : fenjie1) {
duizhan1.push(object);// 9999
}


for (char object : fenjie2) {
duizhan2.push(object);// 1
}


// 取值放入栈中


// 4
int max = Math.max(fenjie1.length, fenjie2.length);


int jinwei = 0;
StringBuffer buffer = new StringBuffer();


// int cuncushuzi1 = 0;
// int cuncushuzi2 = 0;
// 注意变量的申请范围,此刻的cuncushuzi1与cuncushuzi2,
// 如果申请为全局变量,每一次进行栈中取值,这一次栈中取值为1,如果下一次没有取得了,进入了catch中,既不会刷新cuncushuzu2的值。即依然用的是上一次的1
//所以申请为局部,或是在局部进行值的刷新即可,不然没值可取的时候,全局变量就会引导着走向错误。


for (int i = 0; i < max; i++) { // while(max-->0){ //按照最长的那个数组进行栈中取值
int cuncushuzi1 = 0;
try {
String cuncu1 = duizhan1.pop().toString();
cuncushuzi1 = Integer.parseInt(cuncu1);
} catch (Exception e) {
}


int cuncushuzi2 = 0;
try {
String cuncu2 = duizhan2.pop().toString();
cuncushuzi2 = Integer.parseInt(cuncu2);
} catch (Exception e) {
}


System.out.print(cuncushuzi1 + " ");
System.out.print(cuncushuzi2 + " ");
// 取值,有值可取为值,没值可取为0
int sum = cuncushuzi1 + cuncushuzi2 + jinwei;


if (sum >= 10) {
buffer.append(sum % 10);
jinwei = 1;
} else {
buffer.append(sum);
jinwei = 0;
}
// 加载一起的和是否大于10,判断是否进位。进位%10,比如17%10为进位7,进位=1,供下一次进位+1
}
if (jinwei == 1) {
buffer.append(jinwei);
}
// 前面的9999+1,为0000已经进位成功,在循环完毕后,再次询问进位是否为一,判断最高位是否还需要进位
// 因为出栈是按照最长的数字的长度进行运算。最高位如果需要进位就多了一位,所以即需要这一次if


System.out.println(buffer.reverse());


代码很多,没有小学做加法那么结构化简单,如果和小学一样简单,哪里来的工资?是吧,不过解决问题时:本质是和小学做加法一样,代码思路如下:


首先,这个大数字,int不能接收,long也接收不了,有范围,我这里的小数字是为了看结果。大数字,就是应该解决很大的数字。所以接收大数字靠String操作类。


String接收到值后,程序百解,这里只讨论堆栈怎么解决问题哈,把值转换为char,在进行一个个压栈,为什么转换为char?难道你打算直接把大数字压栈吗?那怎么走到:一个个出栈在运算,这种加法结构呢?


压栈后,就该出栈了,此刻是char,还的toString,转换为字符串,在调用Integer转换为int,也就是把char转换为int,转换这里用了try,catch,转换之前的循环是通过max做结束的,为啥这样做?


首先,为什么循环按照max的值来循环?做加法时,是按照最长的数字进行加法,在数学中结构中,上面的数有,下面的数有,就加,下面的数没有,上面的数就不用加了,可以直接写结果了。


在程序中,如果按照短的数字进行循环,那和短的数组一样的位数加完了,好,循环退出了,那么那长数组剩余的数怎么办?循环都退出了,那你也就没有追加上,没了。所以需要按照长数字循环,这样都能加上。


按照长数字循环也有弊端,就是和短数字一样的位数加完后,怎么办?长数字还剩了一节,短数字已经没了,怎么出栈加法呢?于是tay,catch。


短的出栈出完了是吧?出完了就该报错,报错catch接收一下,不做处理,那么接收出栈的那个变量也就还是0,因为没有数组出栈给你刷新值了,结构就是这样的


短的值没有了,用0来补位给你继续加,当然这样写起来代码少一些,不然在做判断也麻烦,看情况于效率咯。然后做加法运算还存在一个问题,就是进位。


这个的这样做,一来进申请全局变量进位,第一次就开始加进位,虽然第一次有点多余。不过后面的就不显得多余,第一次就问大于10?大于下一次加法的时候就该进位了。所以进位徘徊在0,1之间。


然后大于10,比如8+7=15,追加不应该是追加15,详见数学加法,应该是追加5,那个1给下一次做加法进位去了,所以取余%10,追加一个数进去,小于0可以直接追加。


最后出了循环,还的询问进位是否的等于1,因为按照最长的数字的长度进行加法运算,一个个的加完了,栈中最低位一次的加法,数学中最前面的一次加法,是存在进位的,如果进位也就是会多一位数。


往前进位,所以循环完毕,一个个加完了,小于10,上一次就是0,不管,>=1,就是上一次大于等于10,这一次追加一个1,适用场景9999+1=10000,这个1就是追加的进位1,如果是1111+1=1112,就不用在追加1了。


最后在把StringBuffer倒着打印即可,因为栈中取值是先加高位,追加的时候就是把高位先放入了StrungBuffer中,所以StringBuffer是放着倒着的结果,所以想要正着看,还的倒数输出即可。


从这个例题,就能深刻的认识到,解决生活的办法能解决生活(程序反哺生活),也能从补位0,使用tay,catch发现,生活和程序也是有区别的,也能深刻的认识到,计算机就是一步步的执行操作。


不像人一样,瞅瞅就算了,计算机计算还的一个个拿到值,进行计算,也能反应出计算机运用广阔,脱不了它速度之快,一个速度快可以容忍它的笨,甚至发明一门语言发挥它的优势。


程序源于生活,所以也印证了一句话:学好一门语言其他的就没啥了。一法通万法通,不过是语言与语言之间,走的路子不同,导致这个看起来不同,不过大的解决思路也就是那么回事。

原创粉丝点击