兩個二進位數相加

2021-02-19 編程牛人

陸小鳳原創

本文講解「兩個二進位數相加」的算法題。

小白:陸大俠,你想的題目?

際小鳳:leetcode的題(https://leetcode.com/),leetcode是可以挑戰算法設計的地方。

題目如下:

/* 
Given two binary strings, return their sum (also a binary string).

For example, 
a = 「11」 
b = 「1」 
Return 「100」. 
*/

如果是c語言,就是實現這樣的一個函數:

char* addBinary(char* a, char* b) {

}

小白:還好我的英文是4.5級。就是有兩個二進位數,求它們的和,並且也表示為二進位數了。很簡單啊,把這兩個數轉成int,再相加,再轉成二進位數就行啦!

陸小鳳:這個做法解決不了數值大小溢出的問題,在字符串很長的情況下是不可行的。故不考慮這個方向。

小白:… 我就知道你會這麼說的。

(1)一個不簡潔的迭代辦法

使用迭代的辦法,逐位相加。

如何迭代?

一個while循環。從低位開始,每次取兩個數字及進位相加(如果沒有兩個數字及進位,則迭代結束),記錄本次相加的結果及新的進位值。字符串向高位移動,開始新的一輪迭代。

* 如何相加?

如果按兩個數字跟進位的值來分情況判斷,會繁瑣一點。可以考慮都轉化為int,再三者相加,對結果再分類(比如3時,說明新的進位值為1,並且本次相加的結果為1)。

* 如何向高位移動?

先取得兩個字符串的最小長度為l,迭代時,每次取str[l_each_str-i-1],i=0 to (l-1),即可。

* 有哪些細節要注意?

在迭代結束後,還要看進位值是否為1。如果為1,則還需要再次迭代。每次拿剩下的數字,跟進位相加,在進位為0或沒有剩餘數字時結束。迭代結束後,判斷進位的值,如果進位的值為1,則說明產生一個新的數字1。如果進位為0,則需要把剩餘的數字直接作為返回的字符串的內容。

注意最終返回的字符串,在c語言中要以0結尾。

演示代碼

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

char* addBinary(char* a, char* b) {

int more = 0;

int la = strlen(a);

int lb = strlen(b);

int lmin = la > lb ? lb : la;

int lmax = la > lb ? la : lb;

int retl = lmax + 1;

char* retstr = (char*)malloc(retl);

int i = 0;

while (i < lmin) {

char ca = a[la - i - 1];

char cb = b[lb - i - 1];

int ia = ((ca == '1') ? 1 : 0);

int ib = ((cb == '1') ? 1 : 0);

int temp = ia + ib + more;

if (temp == 3) {

retstr[retl - i - 1] = '1';

more = 1;

}

else if (temp == 2) {

retstr[retl - i - 1] = '0';

more = 1;

}

else if (temp == 1) {

retstr[retl - i - 1] = '1';

more = 0;

}

else {

retstr[retl - i - 1] = '0';

more = 0;

}

i ++;

}

char* left = ((la > lb) ? a : b);

if (more == 1) {

while (i < lmax && more) {

char c = left[lmax - i - 1];

int ic = (c == '1') ? 1 : 0;

int temp = ic + more;

if (temp == 2) {

retstr[retl - i - 1] = '0';

more = 1;

}

else if (temp == 1) {

retstr[retl - i - 1] = '1';

more = 0;

}

i ++;

}

}

if (more == 1) {

retstr[0] = '1';

char* rettemp = (char*)malloc(retl + 1);

memmove(rettemp, retstr, retl);

rettemp[retl] = 0;

free(retstr);

retstr = rettemp;

}

else {

if (i <  lmax) {

while (i < lmax) {

char c = left[lmax - i - 1];

retstr[retl - i - 1] = c;

i ++;

}

}

memmove(retstr, retstr + 1, retl - 1);

retstr[retl - 1] = 0;

}

return retstr;

}

int main(int argc, char *argv[])

{

char a[] = "100";

char b[] = "110010";

char* ret = addBinary(a, b);

printf("ret = %s\n", ret);

free(ret);

return 0;

}

在leetcode上的運行時間:3ms。

(2)一個簡潔的c++實現

#include <iostream>

#include <algorithm>

using namespace std;

class Solution {

public:

    string addBinary(string a, string b) {

int c=0, i=a.size()-1, j=b.size()-1;

string ret;

while (c==1 || i>=0 || j>=0) {

c += i>=0 ? a[i--]-'0' : 0;

c += j>=0 ? b[j--]-'0' : 0;

ret += char(c&1) + '0';

c >>= 1;

}

reverse(ret.begin(), ret.end());

return ret;

    }

};

int main(int argc, const char *argv[])

{

string a="100";

string b="110010";

Solution so;

string ret = so.addBinary(a, b);

cout << "ret=" << ret << endl;

return 0;

}

在leetcode上的運行時間:3ms。

公眾號回復"1",拉你進程式設計師交流群

前端必看100本編程書籍

300本編程經典書籍下載 

83份A輪、天使輪融資計劃書等你下載

1000G編程教學視頻免費下載,部部經典

100套微信小程序源碼下載

程式設計師必備!!全套微信小程序開發教程

關注公眾號,叫小編發紅包

相關焦點

  • 二進位、八進位、十進位、十六進位數的轉換方法
    在計算機中:D7 D6 D5 D4 D3 D2 D1 D0 只有兩種0和18 4 2 1二)、數制轉換不同進位計數制之間的轉換原則:不同進位計數制之間的轉換是根據兩個有理數如相等,則兩數的整數和分數部分一定分別相等的原則進行的。也就是說,若轉換前兩數相等,轉換後仍必須相等。
  • 【S7-200】二進位、八進位、十進位、十六進位數的轉換方法
    在計算機中:D7 D6 D5 D4 D3 D2 D1 D0 只有兩種0和18 4 2 1二 、數制轉換 不同進位計數制之間的轉換原則:不同進位計數制之間的轉換是根據兩個有理數如相等,則兩數的整數和分數部分一定分別相等的原則進行的。也就是說,若轉換前兩數相等,轉換後仍必須相等。
  • 二進位、八進位、十進位和十六進位數之間的轉換方法
    然後,將各組的三位二進位數按權展開後相加,得到一位八進位數。②將八進位數轉換成二進數時,採用「一位拆三位」的方法進行。即 把八進位數每位上的數用相應的三位二進位數表示。然後,將各組的四位二進位數按權展開後相加,得到一位十六進位數。b、將十六進位數轉換成二進數時,採用「一位拆四位」的方法進行。即 把十六進位數每位上的數用相應的四位二進位數表示。
  • 十進位數的二進位編碼
    在人機互動過程中,為了既滿足系統中使用二進位數的要求,又適應人們使用十進位數的習慣,通常用4位二進位代碼對十進位數字符號進行編碼,簡稱為二-十進位代碼,或稱BCD(Binary Coded Decimal)碼。
  • 加法器電路原理_二進位加法器原理_與非門二進位加法器
    由於負數可用二的補數來表示,所以加減器也就不那麼必要。   加法器電路原理   在計數體制中,通常用的是十進位,它有0,1,2,3,…,9十個數碼,用它們來組成一個數。但在數字電路中,為了把電路的兩個狀態(1態和0態)和數碼對應起來,採用二進位較為方便,二進位只有0和1兩個數碼。   十進位是以10為底數的計數體制,例如
  • 計算機等級考試詳解:十進位數92轉換為二進位數!
    計算機等級考試詳解:十進位數92轉換為二進位數!本經驗由宗龍龍原創,全文共1000多字,閱讀需要14分鐘,如果文中存在錯誤,還請大家多多指點,我會積極改進的!14、十進位數92轉換為二進位數是()。A)01011100B)01101100C)10101011D)01011000(圖片來源於網絡)這一題主要考察的是十進位與二進位的相互轉換問題。
  • 二進位求和
    給你兩個二進位字符串,返回它們的和(用二進位表示)。輸入為非空字符串且只包含數字 1 和 0。,其實二進位求和與十進位求和是類似的,十進位求和是遇 10 進 1。二進位求和是遇 2 進 1。我們可以從右往左遍歷二進位數值,然後將每個遍歷到的數據進行相加。就算是十進位數據,我們是從右往左逐位相加。因為逢 2 需要進 1 位。所以 1 + 1 = 2,要轉換為 0。並且將前一位進 1。前一位數據進行相加操作的時候,需要再額外加 1。
  • 十進位數的編碼與運算
    修正規則是:  若兩個8421碼數相加之和等於或小於1001,即10進位的9,不需要修正;  若相加之和在10到15之間,一方面應向高位產生一進位,本位還要進行加6修正,進位是在進行加6修正時產生的;  若相加之和在16和18之間時,向高位的進位會在相加過程中自己產生,對本位還需進行加6修正。下面給出三種情況下的具體例子。
  • 【二進位】----十進位數轉換成二進位數
    除了我們常見的十進位的數,還有二進位、五進位、八進位、十六進位和六十進位的數。今天我們來說說二進位。二進位是由0和1兩個數字來表示的數,它的基數是2,進位規則是「逢二進一」,借位規則是「借一當二」,是由18世紀德國數理哲學大師萊布尼茲發現的。
  • 二進位、八進位、十進位與十六進位
    ,有兩個基本的概念:基數和運算規則。二進位是0和1; 八進位是0-7;十進位是0-9;十六進位是0-9,A-F(大小寫均可)。也可以這樣簡單記憶,假設是n進位的話,基數就是【0,n-1】的數字,基數的個數和進位值相同,二進位有兩個基數,十進位有十個基數,依次類推。
  • 考點 7 - 十六進位數
    十六進位數轉換成十進位數十六進位數轉換成二進位數二進位數轉換成十六進位數1.二進位數轉換成十六進位數2的4次方等於16,4位二進位數等於1位十六進位數或者1位十六進位數等於4位二進位數,二進位數轉換成十六進位數時二進位數的每4位分成一組然後每一組分別進行計算。
  • 關於二進位、十進位、八進位、十六進位數據轉換計算方法詳細總結
    ,但是二進位只有0和1兩個,於是就出現0舍1入。(2) 二進位轉換為十進位 不分整數和小數部分 方法:按權相加法,即將二進位每位上的數乘以權,然後相加之和即是十進位數。例 將二進位數101.101轉換為十進位數。
  • 6、計算機進位之二進位、十進位、十六進位之間的轉換
    4、進位之間的轉換4.1、正整數的十進位轉換二進位將一個十進位數除以二,得到的商再除以二,依此類推直到商等於一或零時為止,倒取除得的餘數,即換算為二進位數的結果只需記住要點:除二取餘,倒序排列。由於計算機內部表示數的字節單位都是定長的,以2的冪次展開,或者8位,或者16位,或者32位....。於是,一個二進位數用計算機表示時,位數不足2的冪次時,高位上要補足若干個0。本文都以8位為例。
  • 一文幫你詳細圖解二進位、八進位、十進位、十六進位之間的轉換
    讀數,把結果值相加,1+2+0+8+0+32=43,即(101011)B=(43)D。方法:八進位數從低位到高位(即從右往左)計算,第0位的權值是8的0次方,第1位的權值是8的1次方,第2位的權值是8的2次方,依次遞增下去,把最後的結果相加的值就是十進位的值了。八進位就是逢8進1,八進位數採用 0~7這八數來表達一個數。
  • 十進位數與二進位數的相互轉化
    最近,高二年級中有n多個同學問我:「老師,怎樣將十進位數轉化為二進位數呢?如果轉化為八進位數呢?」
  • Python零基礎入門——認識二進位數
    在上一節課,我們安排了一個課後練習,要求同學們繪製求兩數和算法的流程圖。求兩數和算法的步驟如下:(1)獲取用戶輸入的兩個加數,分別存儲到num1和num2兩個變量;(2)求num1和num2兩數的和,將和存儲到sum變量;(3)將sum變量輸出到電腦屏幕。
  • 二進位轉換為十進位和十進位轉換為二進位的方法
    各位小夥伴們大家好,在之前的文章中小編也介紹了關於二進位轉十進位的方法,這次小編知道了一個更簡單的方法,具體如下:比如我們要把28轉為二進位:28轉換為2進位先用2的n次方來表示28這個數,然後用2的n次方乘以1或者乘以0,相加來湊成與之相等的數,得到的1或者是0,根據這個表格,從左往右把二進位數字湊在一起,11100就是
  • 二進位、八進位、十進位、十六進位相互轉化
    三、基數    基數是數制中所用的進位的數    十進位 基數是10    二進位 基數是2    八進位 基數是8    十六進位 基數是16四、位權    就是一個數字所在數位的大小    1000 十進位 ==> 4位上數字1所在的位置大小是10的4-1次方乘1
  • 常用的二進位與八進位-十進位-十六進位之間的轉換
    8bits = 1Byte1024Bytes = 1k1024k = 1M1024M = 1G1024G = 1Tb(bit) = 比特B(byte) = 字節KB = 千字節MB = 兆字節GB = 吉字節TB = 太字節內存中以二進位形式存儲數據
  • 二進位、八進位、十進位、十六進位轉換計算方法
    進位也就是進位位,我們常用的進位包括:二進位、八進位、十進位與十六進位,它們之間區別在於數運算時是逢幾進一位。比如二進位是逢2進一位,十進位也就是我們常用的0-9是逢10進一位。