我有一串二进制值,例如“010010000110010101111001”。是否有一种简单的方法将此字符串转换为其ascii表示形式(在本例中)为“Hey”?
只找到了Integer的其他方式:
let binary = "11001"
if let number = Int(binary, radix: 2) {
print(number) // Output: 25
}
对于这种情况,有人知道一个好的,高效的解决方案吗?
答案 0 :(得分:6)
@OOPer's solution的变体是使用条件绑定while
循环和index(_:offsetBy:limitedBy:)
来迭代8个字符的子串,利用{{1}的事实当您尝试超越限制时,返回index(_:offsetBy:limitedBy:)
。
nil
请注意,我们在中间步骤中通过let binaryBits = "010010000110010101111001"
var result = ""
var index = binaryBits.startIndex
while let next = binaryBits.index(index, offsetBy: 8, limitedBy: binaryBits.endIndex) {
let asciiCode = UInt8(binaryBits[index..<next], radix: 2)!
result.append(Character(UnicodeScalar(asciiCode)))
index = next
}
print(result) // Hey
而不是Character
- 这只是为了利用String
is specially optimised这样的事实UTF-8表示适合63个字节,这就是这种情况。这节省了堆 - 为每个字符分配一个中间缓冲区。
纯粹为了它的乐趣,另一种方法可能是使用sequence(state:next:)
来创建每个子字符串的开始和结束索引的序列,然后Character
以便连接结果将字符组合成一个字符串:
reduce
从表面上看,这似乎比第一个解决方案效率低得多(由于let binaryBits = "010010000110010101111001"
// returns a lazily evaluated sequence of the start and end indices for each substring
// of 8 characters.
let indices = sequence(state: binaryBits.startIndex, next: {
index -> (index: String.Index, nextIndex: String.Index)? in
let previousIndex = index
// Advance the current index – if it didn't go past the limit, then return the
// current index along with the advanced index as a new element of the sequence.
return binaryBits.characters.formIndex(&index, offsetBy: 8, limitedBy: binaryBits.endIndex) ? (previousIndex, index) : nil
})
// iterate over the indices, concatenating the resultant characters together.
let result = indices.reduce("") {
$0 + String(UnicodeScalar(UInt8(binaryBits[$1.index..<$1.nextIndex], radix: 2)!))
}
print(result) // Hey
应该在每次迭代时复制字符串这一事实) - 但是看起来编译器能够执行一些优化使其不比第一个解决方案慢得多。
答案 1 :(得分:5)
您可能需要将输入的二进制数字拆分为8位块,然后将每个块转换为ASCII字符。我想不出一个超级简单的方法:
var binaryBits = "010010000110010101111001"
var index = binaryBits.startIndex
var result: String = ""
for _ in 0..<binaryBits.characters.count/8 {
let nextIndex = binaryBits.index(index, offsetBy: 8)
let charBits = binaryBits[index..<nextIndex]
result += String(UnicodeScalar(UInt8(charBits, radix: 2)!))
index = nextIndex
}
print(result) //->Hey
答案 2 :(得分:1)
与OOPer的解决方案基本相同,但他/她更快,并且有更短,更优雅的方法: - )
public class A extends AppCompatActivity {
List<String> items= null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a);
items = new ArrayList<String>();
items.add("AAAA");
items.add("BBB");
items.add("CCC");
items.add("DDD");
ArrayAdapter<String> itemsAdapter =
new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
ListView listView = (ListView) findViewById(R.id.listviewAttactivePlaces);
listView.setAdapter(itemsAdapter);
}
答案 3 :(得分:1)
一种不同的方法
let bytes_string: String = "010010000110010101111001"
var range_count: Int = 0
let characters_array: [String] = Array(bytes_string.characters).map({ String($0)})
var conversion: String = ""
repeat
{
let sub_range = characters_array[range_count ..< (range_count + 8)]
let sub_string: String = sub_range.reduce("") { $0 + $1 }
let character: String = String(UnicodeScalar(UInt8(sub_string, radix: 2)!))
conversion += character
range_count += 8
} while range_count < characters_array.count
print(conversion)