只用位運算實現比較兩整數大小,有沒有簡短優雅的O 1 的解法?

時間 2021-06-02 10:09:02

1樓:

這不就是datalab……提供兩種解法

/* * isGreater - if x > y then return 1, else return 0

* Example: isGreater(4,5) = 0, isGreater(5,4) = 1

* Legal ops: ! ~ & ^ | + << >>* Max ops: 24

* Rating: 3

*/int isGreater(int x, int y)int isGreater(int x, int y)

2樓:

位移也算位運算的。

兩個數字相減然後右移(原來的位數﹣1)位。

得到1表示結果是負的,得到0表示結果是正的。

然後套乙個四則式就出來較大或者較小的乙個了,你隨意。

比如返回較大的乙個,偽程式碼

uint16 Max(uint16 a, uint16 b)當然,return這句話也可以再寫成位運算,自己搞搞就是了。

3樓:蘇學斌

用位運算的方法,沒有常數時間演算法,因為在兩數相等的情況,做出判斷需要檢查所有的對應位,因此是線性時間的。但是由於本題輸入規模不大,在某些特定情況下可以使用查表的方法,將所有可能的組合硬編碼,可以達到常數時間複雜度。

4樓:

為啥我覺得怎麼寫都是O(1)的。64位長整數就64次異或運算,然後判斷自己為1還是0。除非你用字串輸入位數不限的整數。那樣的話,你就擼不出常數次了。

大O符號(英語:Big O notation)是用於描述函式

漸近行為的數學符號。更確切地說,它是用另乙個(通常更簡單的)函式來描述乙個函式數量級的漸近上界

以上摘自網際網路。

重點是漸近上界,以及大O符號的具體意義吧。

5樓:枕水

用電路做,以32位數為例,一共是二乘二的32次方個點,a數接通乙個觸點,b數接通另乙個觸點,測量兩個點的電勢或電流方向,O1複雜度。

改進一下,以32位數為例,共64個觸點,一邊32個,接通為1,斷開為0,然後做異或後測量哪一側電位高

6樓:

好像要求只用位運算和unsigned int...好吧,我醬油了...

#include

using

namespace

std;

intmain

(int

argc

,char

const

*argv)

7樓:莫等閒

如果把整數以二進位制表示,其實就是比較兩個二進位制數的大小,位運算的左右移動相當於乘除法,奇偶測試就是看某一位是0是1,這很容易給出O(1)解

8樓:白喵黑咪

不清楚你說的無符號整數,是系統中已經存在的資料結構呢,還是自建的資料結構。如果是前者,因為資料結構長度固定,那麼肯定存在常數演算法O(1),但如果是後者,由於資料長度都不固定,不可能存在常數演算法。

9樓:

#include

"stdafx.h"

intmain

()temp

=in_1

&bit

?in_1

:in_2

;printf("

\n%u\n"

,temp

);return0;}

10樓:

給點資料以前貌似看過相關的東西 :

1. 在"演算法心得hacker's delight"裡有一堆關於這個的)

2. c++ - Comparing two integers without any comparison

Subtract them and check the sign using nasty bit twiddling hacks

Bit Twiddling Hacks #裡面有個MSB

Don't do this in production code if the other programmers know where you live.

11樓:李白

沒乙個人答在點子上。

O(1)就是常數次的操作。

大O表示法表示的是漸進時間複雜度啊。

「時間複雜度常用大O符號表述,不包括這個函式的低階項和首項係數。使用這種方式時,時間複雜度可被稱為是漸近的,它考察當輸入值大小趨近無窮時的情況。」

12樓:

這就是要設計乙個數字比較器電路啊,只用基本邏輯門的似乎只有樹型串聯,延遲是O(log2(N)),併聯也做不到O(1)。放個八位的感受下。

13樓:

intcmp(

unsigned

inta

,unsigned

intb

)// a>b?1:0

利用遞迴與短路求和進行逐位判斷

14樓:柯煦

if ((a & 0x80000000) && !(b & 0x80000000)) return 1;

if (!(a & 0x80000000) && (b & 0x80000000)) return -1;

if ((a & 0x40000000) && !(b & 0x40000000)) return 1;

if (!(a & 0x40000000) && (b & 0x40000000)) return -1;

// ...

return 0;

比較醜,逐位比較,unsigned int 是定長的所以可以O(1),有錯誤敬請斧正。

想到乙個不知道能不能快一點的版本:

unsigned int temp=a^b;

if (temp&0x80000000)

if (a&0x80000000)

return 1;

else

return -1;

//後面一樣

return 0;

15樓:楓北居士

這個問題本質上相當於求MSB

可MSB也只能做到O(log n),如夏洋的答案

如果可以用其他位運算指令的話(題目說不能用CMP比較運算子)。。。所有支援O(1)計算MSB的硬體都可以做到

比如ARM, X86, MIPS都是支援CLZ指令的(Count Leading Zeros),等於變相支援算MSB

但估計在面試領域這應該就不是位運算的範疇了……

王軒的答案裡用的是BSR位操作符,和CLZ基本上是同樣的功能,只不過BSR的適用範圍更窄,只有x86架構支援,而CLZ基本上是業界標準,常用的ARM,X86,MIPS架構都會支援,IBM/Oracle的伺服器架構也支援,建議用CLZ會更好一點

另外,如果想用assembly裡的位操作指令,不需要全部使用assembly語言,只需要在C裡面呼叫_asm_巨集就可以了(depends on compiler also)

另補充說明:如果像Felix Qiu的答案裡用數位電路比較器,這些屬於組合邏輯(combinational logic),如果邏輯層數不多,比如32bit或者64bit,是全部可以在乙個cycle之內完成的

事實上如果用assembly的CMP指令,在硬體內部就是這麼implement然後乙個cycle搞定的

16樓:梁少聰

這個定義有點奇葩,無符號整數是定長的4個位元組,所以勉強可以成為,不過如果題目給出乙個大整數,那麼幾乎不可能做到

思路如下:

明顯有:

則只需要找出第乙個從最高位開始找出第乙個不同的Bitdiff = numa ^ numb

然後,你們就看 @夏洋的答案吧。

程式設計之美有一道求二進位制中1的個數,和這個類似。要想做到,只有乙個最暴力的方法。打個所有資料的表,不過針對無符號整數這個有種排列,同時你題目也要求了不能用比較語句。

所以,以上都是廢話。

17樓:Alvin Chen

用bitwise實現減法,然後用bitwise判斷結果正負0。但是這樣的話貌似不是O(1)啊

為什麼64位機指標只用48個位?

rhett 高位沒用上最主要的原因是用不到,畢竟多乙個bit 位址空間就翻倍,當年推出X64的時候記憶體位址從32 48已經增大太多了。當然了,到了今天再來看,48bit 看起來也不是那麼遠在天邊了,所以 intel 搞出了57bit 位址空間,頁表翻譯到了L5,也就是說,最多要查表5次來完成位址翻...

如何程式設計實現虛數(複數)以及各種運算?

大鈾子 首先,很多語言的基本運算裡包含虛數的運算。我們來看看C語言的複數運算 include include intmain 執行結果為 a 1.000000 1.000000ic 1.000000 3.000000ic 0.600000 0.200000iC語言提供了關鍵字 Complex,該關鍵...

python如何實現左側的運算子過載?

Kittyhawk 先從myob 1說起,假設myob屬於Myob類,這裡我們過載了 mul class Myob def mul self val print mul 過載了 mul 後我們就可以順利實現myob 1,結果是列印出 mul 但如果把兩者換一下位,1 myob,就會報錯了。這是因為1...