簡體   English   中英

如何快速從用戶那里獲取二進制字符串輸入

[英]how to take binary string input from user in swift

我想以二進制形式從用戶那里獲取輸入,我想要的是:10101 11110

然后我需要對此執行按位或。 我知道如何輸入以及如何執行按位或,我只想知道如何轉換,因為我目前使用的沒有給出正確的結果。 我試過的內容如下:

let aBits: Int16 = Int16(a)! //a is String "10101"
let bBits: Int16 = Int16(b)! //b is String "11110"
let combinedbits = aBits | bBits

編輯:我不需要小數與基數二進制轉換,我串已經只有0和1串可具有高達500個字符,如:10011011111010110111001011001001101110111110110001001111001111101111010110110111 00111001100011111010這超出詮釋限度,如何處理,在斯威夫特?

Edit2 :根據 vacawama 的回答,下面的代碼效果很好:

let maxAB = max(a.count, b.count)
let paddedA = String(repeating: "0", count: maxAB - a.count) + a
let paddedB = String(repeating: "0", count: maxAB - b.count) + b

let Str = String(zip(paddedA, paddedB).map({ $0 == ("0", "0") ? "0" : "1" }))

我最多可以有 500 個字符串的數組,每個字符串最多可以有 500 個字符。 然后我必須得到所有可能的對並執行按位 OR 並計算 1 的最大數量。 有什么想法可以使上述解決方案更有效嗎? 謝謝

由於您需要任意長的二進制數,因此請使用字符串進行所有操作。

此函數首先將兩個輸入的內容填充為相同的長度,然后使用zip對數字進行配對並map以計算每對字符的OR 將得到的字符數組被轉換回一個StringString()

func binaryOR(_ a: String, _ b: String) -> String {
    let maxAB = max(a.count, b.count)
    let paddedA = String(repeating: "0", count: maxAB - a.count) + a
    let paddedB = String(repeating: "0", count: maxAB - b.count) + b

    return String(zip(paddedA, paddedB).map({ $0 == ("0", "0") ? "0" : "1" }))
}

print(binaryOR("11", "1100"))    // "1111"
print(binaryOR("1000", "0001"))  // "1001"

我最多可以有500個字符串的數組,每個字符串最多可以有500個字符。 然后,我必須獲取所有可能的對,並執行按位“或”運算並計算最大數目為1。 有什么想法可以使上述解決方案更有效嗎?

您將必須執行500 * 499 / 2 124,750 (即124,750比較)。 重要的是避免不必要的和/或重復的工作。

我建議:

  1. 進行初始遍歷以遍歷您的字符串以找出最大的長度。 然后將所有琴弦都墊到這個長度。 我會在一個小的結構中跟蹤每個字符串的原始長度:

     struct BinaryNumber { var string: String // padded string var length: Int // original length before padding } 
  2. 修改binaryOR功能采取BinaryNumbers並返回Int ,在OR“1”的個數。

     func binaryORcountOnes(_ a: BinaryNumber, _ b: BinaryNumber) -> Int { let maxAB = max(a.length, b.length) return zip(a.string.suffix(maxAB), b.string.suffix(maxAB)).reduce(0) { total, pair in return total + (pair == ("0", "0") ? 0 : 1) } } 

    注意:使用suffix僅檢查重要的數字有助於提高效率。 如果原始字符串的長度為23 ,則即使將最后3位數字填充為長度500也將對其進行或運算。

  3. 循環比較所有的BinaryNumber對,以找到最大的對:

     var numbers: [BinaryNumber] // This array was created in step 1 maxOnes = 0 for i in 0 ..< (numbers.count - 1) { for j in (i + 1) ..< numbers.count { let ones = binaryORcountOnes(numbers[i], numbers[j]) if ones > maxOnes { maxOnes = ones } } } print("maxOnes = \\(maxOnes)") 

加速的其他想法

或創建的數字不能超過原始兩個數字的總和,並且復制數量不能超過原始兩個數字中的任何一個的最大長度。 因此,如果您在填充每個數字時將它們計算在內,並將其存儲在var ones: Int一個structvar ones: Int屬性,則可以使用它來查看是否還要打擾binaryORcountOnes

maxOnes = 0
for i in 0 ..< (numbers.count - 1) {
    for j in (i + 1) ..< numbers.count {
        if maxOnes < min(numbers[i].ones + numbers[j].ones, numbers[i].length, numbers[j].length) {
            let ones = binaryORcountOnes(numbers[i], numbers[j])
            if ones > maxOnes {
                maxOnes = ones
            }
        }
    }
}

順便說一句,原始字符串的length實際上應該只是包含最高順序1的最小長度。 因此,如果原始字符串為"00101" ,則length應為3因為這就是存儲"101"所需的全部。

let number = Int(a, radix: 2)

基數有助於使用二進制而不是小數的值

您可以使用基數來轉換您的字符串。 轉換后,您可以按位進行“或”運算,然后檢查nonzeroBitCount以計算1的個數

let a = Int("10101", radix: 2)!
let b = Int("11110", radix: 2)!

let bitwiseOR = a | b
let nonZero = bitwiseOR.nonzeroBitCount

正如我上面已經評論過的,“ 10101”實際上是String而不是Binary因此"10101" | "11110" "10101" | "11110"不會計算您實際需要的內容。

因此,您需要做的是將兩個值都轉換為decimal然后使用bitwiseOR並將結果轉換回Binary String (in which format you have the data "11111" not 11111)

let a1 = Int("10101", radix: 2)!
let b1 = Int("11110", radix: 2)!
var result = 21 | 30
print(result)

輸出: 31

現在將其轉換回binary string

let binaryString = String(result, radix: 2)
print(binaryString)

輸出: 11111

-:編輯:-

我將回答一個有關如何計算bitwiseOR的基本示例,因為該問題是特定於不使用內置函數的,因為字符串很大,可以轉換為Int

算法: 1 | 0 = 1,1 | 1 = 1,0 | 0 = 0,0 | 1 = 1

因此,我們要做的是從String一個接一個地獲取所有字符,然后將執行| 操作並將其附加到另一個String

var str1 = "100101" // 37
var str2 = "10111" // 23
/// Result should be "110111" -> "55"

// #1. Make both string equal
let length1 = str1.characters.count
let length2 = str2.characters.count
if length1 != length2 {
    let maxLength = max(length1, length2)
    for index in 0..<maxLength {
        if str1.characters.count < maxLength {
            str1 = "0" + str1
        }
        if str2.characters.count < maxLength {
            str2 = "0" + str2
        }
    }
}

// #2. Get the index and compare one by one in bitwise OR
// a) 1 - 0 = 1,
// b) 0 - 1 = 1,
// c) 1 - 1 = 1,
// d) 0 - 0 = 0
let length = max(str1.characters.count, str2.characters.count)
var newStr = ""
for index in 0..<length {
    let charOf1 = Int(String(str1[str1.index(str1.startIndex, offsetBy: index)]))!
    let charOf2 = Int(String(str2[str2.index(str2.startIndex, offsetBy: index)]))!
    let orResult = charOf1 | charOf2
    newStr.append("\(orResult)")
}

print(newStr)

輸出: 110111 // 55

我想參考了解位運算符了解更多信息。

func addBinary(_ a: String, _ b: String) {


var result = ""
let arrA = Array(a)
let arrB = Array(b)

var lengthA = arrA.count - 1
var lengthB = arrB.count - 1
var sum = 0

while lengthA >= 0 || lengthB >= 0 || sum == 1 {

    sum += (lengthA >= 0) ? Int(String(arrA[lengthA]))! : 0

    sum += (lengthB >= 0) ? Int(String(arrB[lengthB]))! : 0

    result = String((sum % 2)) + result

    sum /=  2
    lengthA -= 1
    lengthB -= 1
}

print(result) }

addBinary("11", "1")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM