[英]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
。 將得到的字符數組被轉換回一個String
與String()
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
比較)。 重要的是避免不必要的和/或重復的工作。
我建議:
進行初始遍歷以遍歷您的字符串以找出最大的長度。 然后將所有琴弦都墊到這個長度。 我會在一個小的結構中跟蹤每個字符串的原始長度:
struct BinaryNumber { var string: String // padded string var length: Int // original length before padding }
修改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
僅檢查重要的數字有助於提高效率。 如果原始字符串的長度為2
和3
,則即使將最后3
位數字填充為長度500
也將對其進行或運算。
循環比較所有的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
一個struct
中var 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.