面試常見題目:大數相加的Java實現(考慮負數情況)
前言:
在做面試題目時,我們經常看到有這樣的題目:將兩個很大的數相加,超過100位。
網上可以看到很多答案,但是這些答案大部分都是沒有考慮負數的情況。
首先我們已經不能直接用long型別進行表示了。一般輸入是兩個字串。最後輸出也得是一個字串。
思路:
對於字串是無法相加的,那就必須轉換成整形陣列。然後一位一位的相加。
當然我們得考慮進位的情況。ok,那麼負數怎麼解決的,這。裡想到了計算機組成裡面的運算方法。計算機是將整數以補碼的方式儲存的,這就很好的將減法變為了加法。最後只需要一個加法器就可以進行加減法了(負數相當於減法)。
我們知道計算機的整數二進位制儲存的,首位是符號位,0代表正,1代表負。求補碼是正數補碼等於原始碼,負數補碼等於除符號位外取反後加1.。
10進位制補碼
這裡我們的數是10進位制,我們也可以模擬其求補碼,具體方法是:我們符號位用0表示正,9表示負(必須是9)。正數和二進位制一樣,負數用9-i;最後整個數+1。模擬加法器
要保證加法器能執行,那麼兩個陣列的長度必須一致,類似於計算機的32位只能和32位相加,而不能相容64位。這也保證了首位是符號位。
這樣具體實現就很簡單了,從最右邊開始相加,若有進位就把進位記錄下來,下一位相加時把進位加上。- 其他內容
- 字串轉換為陣列
用‘-’代表負數,先處理好‘-’,然後取字串最大的長度+2(+2的原因是一位儲存符號位,一位是用來進位。)。然後就是字元轉換數字了。 - 結果輸出
加法器返回的是補碼的陣列,那麼要輸出字串,先求原碼(補碼的補碼是原碼),再處理正負,負顯示‘-’。去掉前面的0。
- 字串轉換為陣列
下面是原始碼
package com.suanfa;
/**
* @author 作者 E-mail: [email protected]
* @date 建立時間:2016-4-9 上午10:21:33
* @version 1.0
* @Description:
*/
public class LongAdd {
/**
* 加法器,a,b的位數必須相同,首位為符合位,0代表正,9代表負
* @param a
* @param b
* @return
*/
private static int[] add (int[] a, int[] b) {
if(a.length<b.length){
return null;
}
int size = a.length;
int t = 0;//進位
for (int i = 0; i < size; i++) {
int k = a[size - i - 1] + b[size - i - 1];
k+= t;//加進位
if (k >= 10) {
t = 1;
}else{
t = 0;
}
k %= 10;
a[size - i - 1] = k;
}
return a;
}
/**
* 大數相加
* @param a
* @param b
* @return
*/
public static String bigAdd(String a,String b){
if(a==null || b == null){
throw new NullPointerException();
}
boolean af = true,bf =true;
if(a.charAt(0)=='-'){
af = false;
a = a.substring(1);
}
if(b.charAt(0)=='-'){
bf = false;
b = b.substring(1);
}
int maxsize = a.length()>b.length()?a.length()+2:b.length()+2;
int[] m = new int[maxsize];
int[] n = new int[maxsize];
m[0] = af?0:9;
n[0] = bf?0:9;
for (int i = 0; i < a.length(); i++) {
m[maxsize-a.length()+i] = Integer.parseInt(""+a.charAt(i));
}
for (int i = 0; i < b.length(); i++) {
n[maxsize-b.length()+i] = Integer.parseInt(""+b.charAt(i));
}
int[] result = add(buma(m),buma(n));
return intToString(buma(result));
}
/**
* 標準輸出
* @param a
* @return
*/
public static String intToString(int[] a){
StringBuffer s = new StringBuffer();
if(a[0]==9){
s.append('-');
}else{
//s.append('0');
}
int tag = 0;
for (int i = 1; i < a.length; i++) {
if(a[i]==0){
tag++;
}else{
break;
}
}
for (int j = tag+1; j < a.length; j++) {
s.append(a[j]);
}
if(s.length()==0){
return "0";
}
return s.toString();
}
/**
* 10進位制求補碼
* @param a
* @return
*/
public static int[] buma(int[] a) {
if (a[0] == 9) {
for (int i = 1; i < a.length; i++) {
a[i] = 9 - a[i];
}
int[] tmp = new int[a.length];
tmp[a.length-1] = 1;
return add(a, tmp);
}else{
return a;
}
}
/**
* 測試
* @param args
*/
public static void main(String[] args) {
//用字串表示大數
String str1 = "-800000000000000000000000000000009";
String str2 = "-0091";
System.out.println(bigAdd(str1, str2));;
}
}
相關推薦
面試常見題目:大數相加的Java實現(考慮負數情況)
前言: 在做面試題目時,我們經常看到有這樣的題目:將兩個很大的數相加,超過100位。 網上可以看到很多答案,但是這些答案大部分都是沒有考慮負數的情況。 首先我們已經不能直接用long型別進行表示了
Jquery EasyUI Tree樹形結構的Java實現(實體轉換VO)
優勢 con control 項目 util turn ttr real org 前一陣做的OA項目,有一個是組織架構的樹,因為是分開做的,我做的是Controller和頁面,其他組做的Service和Dao,因為之前一直沒有商量頁面用什麽框架做比較好,導致,Dao層取出來
八大排序算法原理以及Java實現(直接插入排序)
不能 oat 設立 side 堆排 八大排序 算法 line load 概述 排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。 我們這裏說說八大排序就是內部排序。
歸併排序的java實現(超詳解)
歸併排序,見名知意,就是遞迴+合併 原理: 使用遞迴的手段,達到分割的目的,在分割後進行合併,合併也是遞迴的,這就是這裡的雙向過程都是遞迴進行的,結果如圖: 示例(例項): 以一下一串數字為例,首先進行拆分,然後合併,在合併的過程,進行排序,這裡需要說明的是,遞迴在整個過程中都
linux運維工程師面試常見問題整理8--預設埠篇(持續更新ing)
歡迎喜歡實施運維及資料的小夥伴加入群進行談論! 運維技術群:263859509 1.中介軟體類 中介軟體名稱 預設埠 tomcat 8080 wildfly
劍指Offer:面試題33——把陣列排成最小的數(java實現)(未完待續)
問題描述: 輸入一個正整數陣列,把數組裡所有數字拼接起來排成一個數,列印能拼接出的所有數字中最小的一個。例如輸入陣列{3,32,321},則打印出這三個數字能排成的最小數字為321323。
布隆過濾器Bloom Filter演算法的Java實現(用於去重)
在日常生活中,包括在設計計算機軟體時,我們經常要判斷一個元素是否在一個 集合中。比如在字處理軟體中,需要檢查一個英語單詞是否拼寫正確(也就是要判斷它是否在已知的字典中);在 FBI,一個嫌疑人的名字是否已經在嫌疑名單上;在網路爬蟲裡,一個網址是否被訪問過等等。最直接的方法就
C++面試常見題目1_C++與C,Java的區別
new/delete是C++的運算子,malloc/free是C/C++語言的標準庫函式。 new無需顯式地指出所需記憶體的尺寸,編譯器會根據型別資訊自行計算。而malloc則需要顯式地指出所需記憶體的尺寸。 new操作符記憶體分配成功時,返回的是物件型別的指標,型別嚴格與物件匹配,無須進行型別轉換。而m
mysql面試常見題目
arc delete upd replace eva 第三題 其中 signed 使用 第一題 某班學生和考試成績信息如下表Student所示: Student表 ID SName Mark 1 Jack 90 2 Marry 96 3 Rose 88 4 Bob 86 5
mysql面試常見題目2
4條 count student 插入 機考 mysq ID def arch Sutdent表的定義 字段名 字段描述 數據類型 主鍵 外鍵 非空 唯一 自增 Id 學號 INT(10) 是 否 是 是 是 sName 姓名 VARCHAR(20) 否 否 是 否 否 S
引用面試官文章 :如何準備Java初級和高階的技術面試
本人最近幾年一直在做java後端方面的技術面試官,而在最近兩週,又密集了面試了一些java初級和高階開發的候選人,在面試過程中,我自認為比較慎重,遇到問題回答不好的候選人,我總會再三從不同方面提問,只有當反覆確認能力不行才會下結論,相反,如果候選人給我的印象不錯,我也會從多個角度來衡量,以免招進會說但不會幹活
C++程式設計師面試常見題目
歡迎大家指正問題 1:請用簡單的語言告訴我C++ 是什麼? 答:C++是在C語言的基礎上開發的一種面向物件程式語言,應用廣泛。C++支援多種程式設計正規化 --面向物件程式設計、泛型程式設計和過程化程式設計。 其程式設計領域眾廣,常用於系統開發,引擎開發等應
大數相加演算法實現
所謂的大數相加就是,數字的長度超出了計算機int64的儲存範圍,需要使用字串儲存進行相加 相加的邏輯,類似與我們小學算加法,列等式進行相加,如果大於等於10則需要進位 下面將用不同語言來實現 Python實現(支援帶小數點大數) #!/usr/bin/env python3 # -*- cod
Java併發(二十一):執行緒池實現原理 Java併發(十八):阻塞佇列BlockingQueue Java併發(十八):阻塞佇列BlockingQueue Java併發程式設計:執行緒池的使用
一、總覽 執行緒池類ThreadPoolExecutor的相關類需要先了解: (圖片來自:https://javadoop.com/post/java-thread-pool#%E6%80%BB%E8%A7%88) Executor:位於最頂層,只有一個 execute(Runnab
Java併發(二十一):執行緒池實現原理
Java併發(二十一):執行緒池實現原理 一、總覽 執行緒池類ThreadPoolExecutor的相關類需要先了解: (圖片來自:https://javadoop.com/post/java-thread-pool#%E6%80%BB%E8%A7%88) E
《程式設計師程式碼面試指南》醜數問題——java實現
醜數問題 題目描述: 規定1是醜數,其他的數如果只含有2或3或5的因子,那麼這個 數也是醜數。 比如依次的醜數為:1,2,3,4,5,6,8,9,10,12,15… 求第n個醜數 題目難度: easy 題目思路: 思路一: 本題要求出第n個醜數,分為兩個步驟
面試常考的資料結構Java實現
1、線性表 2、線性連結串列 3、棧 4、佇列 5、串 6、陣列 7、廣義表 8、樹和二叉樹 二叉樹:每個結點至多隻有兩棵子樹(即二叉樹中不存在度大於2的結點),並且,二叉樹的子樹有左右之分,其次序不能任意顛倒。 二叉樹的性質: 性質1:在二叉樹的第
最小生成樹問題:演算法分析 & Java 實現
一、簡介 1. 什麼是最小生成樹 將一個有權圖中的 所以頂點 都連線起來,並保證連線的邊的 總權重最小,即最小生成樹(mini spanning tree)問題。 例如,電子電路設計中,將所有元件的針腳連線在一起,且希望所使用的連線長度最短。 2. 圖示 如上
大整數相加java實現
package test; public class MaxIntSum { public static void main(String[] args) { String a="1999999
201809-1 試題名稱: 賣菜 java實現
問題描述 在一條街上有n個賣菜的商店,按1至n的順序排成一排,這些商店都賣一種蔬菜。 第一天,每個商店都自己定了一個價格。店主們希望自己的菜價和其他商店的一致,第二天,每一家商店都會根據他自己和相鄰商店的價格調整自己的價格。具體的,每家商店都會將第二天的菜價