我想从二进制文件中获取用户的输入,我想要的是: 10101 11110
然后我需要对此执行按位OR。我知道如何获取输入以及如何执行按位OR,只是我想知道如何转换因为我当前使用的是没有给出正确的结果。我尝试的内容如下:
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 这超出了Int限制,如何在Swift中处理它?</ p>
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的最大数量。是否有任何想法使上述解决方案更有效?谢谢
答案 0 :(得分:3)
由于你需要任意长的二进制数,所以用字符串做所有事情。
此函数首先将两个输入填充到相同的长度,然后使用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
比较)。重要的是避免不必要的和/或重复的工作。
我建议:
执行初始传递以循环查找字符串以查找最大字符串的长度。然后将所有字符串填充到此长度。我会跟踪每个字符串的原始长度:
struct BinaryNumber {
var string: String // padded string
var length: Int // original length before padding
}
修改binaryOR
函数以取BinaryNumbers
并返回Int
,即&#34; 1&#34; s中的数量。
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
长度。< / p>
循环并比较所有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)")
加速的其他想法
或者不能创建比原始两个数字更多的那些,并且1的数量不能超过原始两个数字中任何一个的最大长度。因此,如果您在填充每个数字时计算每个数字并将其存储在struct
var ones: Int
属性中的binaryORcountOnes
中,则可以使用它来查看是否应该打扰{{1} }:
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"
所需的全部内容。
答案 1 :(得分:0)
let number = Int(a, radix: 2)
Radix帮助使用二进制而不是分数值
答案 2 :(得分:0)
您可以使用radix转换字符串。转换后,您可以执行按位OR,然后检查nonzeroBitCount以计算1的数量
let a = Int("10101", radix: 2)!
let b = Int("11110", radix: 2)!
let bitwiseOR = a | b
let nonZero = bitwiseOR.nonzeroBitCount
答案 3 :(得分:0)
正如我上面已经评论的那样,“10101”实际上是String
而不是Binary
,因此"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
我想提及Understanding Bitwise Operators了解更多细节。