A B問題及擴充套件

2021-08-28 06:27:06 字數 4275 閱讀 4163

位運算加法

擴充套件減乘除

給出兩個整數ab,求它們的和

如果a=1並且b=2,返回3.

你可以直接使用return a+b,但是不使用+運算子

二進位制00000110(6),00001011(11) 按位與運算:

00000110

& 00001011

00000010

總結:同為1則為1,否則為0

按位或運算:

00000110

| 00001011

00001111

總結:只要有乙個為1則為1,否則為0

按位異或運算:

00000110

^ 00001011

00001101

總結:不相同則為1,否則為0

按位取反運算:

00000110

~ 11111001

總結:01,10

左邊消失,右邊補0

右邊消失,左邊補符號位

十進位制中:

13 + 9
操作步驟:

不考慮進製,sum = 13 + 9 = 12;

只考慮進製,carry= 13 + 9 = 10;

如果carry != 0,使用sumcarry重複1,2步,直至carry = 0為止,則結果為sum = 22;

步驟:

1. sum = 13 + 9 = 12;

2. carry = 13 + 9 = 10;

3. carry != 0;

4. sum = 12 + 10 = 22;

5. carry = 12 + 10 = 0;

6. carry = 0, sum = 22;

二進位制中:

13: 00001101    9: 00001001

1. sum = 00001101 + 00001001 = 00000100;

2. carry = 00001101 + 00001001 = 00010010;

3. carry != 0;

4. sum = 00000100 + 00010010 = 00010110;

5. carry = 00000100 + 00010010 = 00000000;

6. carry = 0, sum = 00010110 = 22;

第一步操作就是按位異或^操作;

第二步操作是按位與&操作,再左移<<1位.

所以,操作就可以使用遞迴或者迭代方式實現

遞迴**:

int

add(

int num1,

int num2)

int sum = num1 ^ num2;

int carry =

(num1 & num2)

<<1;

return

add(sum, carry)

;}

迭代**:

int

add(

int num1,

int num2)

return sum;

}

13 - 9可以轉換為13 + (-9),然後使用前面的加法方法實現減法

在計算機中,負數是以補碼形式存在的:

-9		原碼: 00001001

反碼: 11110110

補碼: 11110110 + 1 = 11110111

所以-9在計算機中的表現形式是:11110111.

~00001001 + 1就可以得到-9的表現形式.

總結:取反加一

所以:

int

subtract

(int num1,

int num2)

13 * 9轉換為加法就是913相加,符號最後判斷,同號為正,異號為負.

所以:

int

multiply

(int a,

int b)

//判斷正負號, 按位異或,最高位為1則為負數,最高位為0則為正數if(

(a ^ b)

<0)

return sum;

}

上面的方法,如果乘數很大,即9很大時,需要疊加的次數也就很多,運算起來就會很大,效率不高

可以參考十進位制的乘法:

1	3						

* 1 4

5 21 3

1 8 2

二進位制:

1	1	0	1

* 1 1 1 0

0 0 0 0

1 1 0 1

1 1 0 1

1 1 0 1

1 0 1 1 0 1 1 0 (182)

相當於b從低位開始取值,如果為1,則加入sum中,為0,則不需要相加

取b的下一位, 即右移一位,取最低位, a右移一位,相當於在十進位制中乘以10,重複上面.

直到最後b右移為0時,結束,判斷符號

所以優化結果為:

int

multiply

(int a,

int b)

absa = absa <<1;

//a 左移一位, 在十進位制中就是乘於10, 進一位,二進位制中同理

absb = absb >>1;

//b 右移一位, 在十進位制中就是除以10, 退一位, 二進位制中同理

}//判斷符號if(

(a ^ b)

<0)

return sum;

}

除法轉換為減法, 被除數減除數,直到被除數小於除數字置,減的次數就是商,此時被除數就是餘數.符號確認跟乘法一樣,餘數的符號和被除數一樣.

int

divide

(int a,

int b)

//判斷符號if(

(a ^ b)

<0)

//判斷餘數符號

rema = a >

0? absa :

add(

~absa,1)

;return count;

}

跟乘法類似a很大b很小 減的次數就很大,所以可以增加步數去減

在計算機中,所有數都可以使用 [20,21,22,…,231] 表示,所以可以從31開始,如果可以減31倍,就把31倍的次數,依次類推

int

divide

(int a,

int b)}if

((a ^ b)

<0)

rema = a >

0? absa :

add(

~absa,1)

;}

結束

a b擴充套件 C

oj的第一道題是經典的a b問題,輸入兩個數,並輸出這兩個數的和。但是你不能僅僅滿足於此,我們要增加需求,加需求!不僅僅是a b,還要繼續加上或者減去其他的數,比如1 2 3 2,輸出4。input 有多組測試資料,每組測試資料報含一行不含有空格的字串,字串長度不超過1000,字串僅包含數字 加號和...

A B 尾數不等a b問題

problem description 讀入兩個小於 10000 的正整數a和 b,計算 a b。需要注意的是 如果a和 b的末尾 k 不超過 8 位數字相同,請直接輸出 1。input 測試輸入包含若干測試用例,每個測試用例佔一行,格式為 a b k 相鄰兩數字有乙個空格間隔。當a和 b同時為 0...

A B 字串a b問題

problem description 讀入兩個小於100的正整數a和b,計算a b.需要注意的是 a和b的每一位數字由對應的英文單詞給出.input 測試輸入包含若干測試用例,每個測試用例佔一行,格式為 a b 相鄰兩字串有乙個空格間隔.當a和b同時為0時輸入結束,相應的結果不要輸出.output...