2016-07-12 8 views
1

Dies ist eine LeetCode-Frage. Ich habe 4 Antworten in verschiedenen Versionen dieser Frage geschrieben. Als ich versuchte "Bitmanipulation" zu benutzen, bekam ich den Fehler. Da niemand in LeetCode meine Frage beantworten kann, kann ich keinen Swift-Dokument darüber finden. Ich dachte, ich würde versuchen, hier zu fragen.Warum kann ich in Swift keine negative Nummer mit Bit-Manipulation erhalten?

Die Frage ist, das Mehrheitselement (> n/2) in einem gegebenen Array zu erhalten. Der folgende Code funktioniert in anderen Sprachen wie Java, also ich denke, es könnte eine allgemeine Frage in Swift sein.

func majorityElement(nums: [Int]) -> Int { 
    var bit = Array(count: 32, repeatedValue: 0) 
    for num in nums { 
     for i in 0..<32 { 
      if (num>>(31-i) & 1) == 1 { 
       bit[i] += 1 
      } 
     } 
    } 
    var ret = 0 
    for i in 0..<32 { 
     bit[i] = bit[i]>nums.count/2 ? 1 : 0 
     ret += bit[i] * (1<<(31-i)) 
    } 
    return ret 
} 

Wenn der Eingang [-2147483648] ist, ist der Ausgang 2147483648. Aber in Java, kann es erfolgreich Ausgang der richtige negative Zahl.

Swift doc sagt:

Selbst auf einem 32-Bit-Plattformen, Int beliebigen Wert zwischen -2147483648 speichern und 2147483647, und ist groß genug für viele Integer-Bereiche.

Nun, es ist , der Eingang 1 größer ist als diese Zahl. Als ich pow(2.0, 31.0) in Spielplatz lief, zeigt es . Ich bin verwirrt. Was ist falsch mit meinem Code oder was habe ich vermisst? Swift Int?

+3

weil 2147483648 ist eigentlich eine 33-Bit-Zahl zu verwenden wäre. es ist '1000 ... 00000 [32 Nullen]', während 2,147,483,648 ist '011 .... 111 [31 Einsen] ' –

Antwort

2

Ein Java int ist eine 32-Bit-Ganzzahl. Der Swift Int ist je nach Plattform 32-Bit oder 64-Bit . Insbesondere ist es 64-Bit auf allen OS X Plattformen, wo Swift verfügbar ist.

Ihr Code nur die unteren 32 Bits der gegebenen Zahlen behandelt, so dass

-2147483648 = 0xffffffff80000000 

wird

2147483648 = 0x0000000080000000 

das Problem so lösen, können Sie entweder die Funktion ändern 32-Bit nehmen ganze Zahlen als Argumente:

func majorityElement(nums: [Int32]) -> Int32 { ... } 

oder mit beliebig großen ganzen Zahlen durch die Berechnung th funktionieren e tatsächliche Größe und Verwendung, die anstelle der konstanten 32:

func majorityElement(nums: [Int]) -> Int { 
    let numBits = sizeof(Int) * 8 
    var bit = Array(count: numBits, repeatedValue: 0) 
    for num in nums { 
     for i in 0..<numBits { 
      if (num>>(numBits-1-i) & 1) == 1 { 
       bit[i] += 1 
      } 
     } 
    } 
    var ret = 0 
    for i in 0..<numBits { 
     bit[i] = bit[i]>nums.count/2 ? 1 : 0 
     ret += bit[i] * (1<<(numBits-1-i)) 
    } 
    return ret 
} 

Eine Swifty Weise map() und reduce()

func majorityElement(nums: [Int]) -> Int { 
    let numBits = sizeof(Int) * 8 
    let bitCounts = (0 ..< numBits).map { i in 
     nums.reduce(0) { $0 + ($1 >> i) & 1 } 
    } 
    let major = (0 ..< numBits).reduce(0) { 
     $0 | (bitCounts[$1] > nums.count/2 ? 1 << $1 : 0) 
    } 
    return major 
} 
+0

Ich versuchte Int32, aber von Ihrer Antwort jetzt weiß ich, dass ich es falsch versuchte. Vielen Dank. –

+0

Beantwortet das deine Frage? Bitte lassen Sie mich wissen, wenn Sie weitere Informationen benötigen. –

+0

Ja, Ihre Antwort beantwortet meine Frage. Vielen Dank! Und ich mag Swifty way 'map()' und 'reduce()' sehr! :) –