2017-12-17 3 views
0

ein bestimmtes Zeichen aus dem Index einer Zeichenfolge erhalten Ich versuche, ein Binary zu Dezimal Rechner für die Apple-Uhr Swift Mühe 4.Wie in schnellen

Der Code, den ich mit Verwendung bauen will, ist dies:

var i = 0 
var labelInputInt = 0 
let labelOutputString = "10010" // Random number in binary 
let reverse = String(labelOutputString.reversed()) // Reversing the original string 

while i <= reverse.count { 
    let indexOfString = reverse.index(reverse.startIndex, offsetBy: i) 

    if reverse[indexOfString] == "1" { 
     labelInputInt += 2^i * 1 
    } 

    i += 1 
} 

Ich verwende eine while-Schleife, um den Index indexOfString zu erhalten und zu überprüfen, ob in der Zeichenfolge reverse am spezifischen Index ist es gleich "1".

Das Problem ist, dass ich einen Laufzeitfehler bekomme, wenn die if-Anweisung ausgeführt wird.

Der Fehler sieht wie folgt aus:

2 libpthread.so.0 0x00007fc22f163390 
3 libswiftCore.so 0x00007fc22afa88a0 _T0s18_fatalErrorMessages5NeverOs12Stati 
cStringV_A2E4fileSu4lines6UInt32V5flagstFTfq4nnddn_n + 96 
4 libswiftCore.so 0x00007fc22afb3323 
5 libswiftCore.so 0x00007fc22afdf9a2 
6 libswiftCore.so 0x00007fc22aedca19 _T0SS9subscripts9CharacterVSS5IndexVcfg 
+ 9 
7 libswiftCore.so 0x00007fc22f591294 _T0SS9subscripts9CharacterVSS5IndexVcfg 
+ 74139780 
8 swift   0x0000000000f2925f 
9 swift   0x0000000000f2d402 
10 swift   0x00000000004bf516 
11 swift   0x00000000004ae461 
12 swift   0x00000000004aa411 
13 swift   0x0000000000465424 
14 libc.so.6  0x00007fc22d88d830 __libc_start_main + 240 
15 swift   0x0000000000462ce9 
Stack dump: 
0. Program arguments: /home/drkameleon/swift4/usr/bin/swift -frontend -inte 
rpret tmp/XfwP0oM7FJ.swift -disable-objc-interop -suppress-warnings -module-na 
me XfwP0oM7FJ 
Illegal instruction (core dumped) 

Also, wie kann ich einen bestimmten Charakter eines String bekommen und es mit einem anderen Charakter vergleichen, ohne diesen Absturz zu bekommen?

Antwort

4

Ihr Ansatz ein bestimmtes Zeichen aus einer Zeichenfolge erhalten tatsächlich richtig ist, gibt es zwei weitere Probleme im Code:

  • Der Index i sollte laufen und ohnereverse.count. Dies geschieht bequem mit dem Operator "halboffener Bereich" (..<).
  • ^ ist der Bitwise-Xor-Operator, keine Potenzierung. Potenzierung mit der pow() Funktion getan, in Ihrem Fall

    labelInputInt += Int(pow(2.0, Double(i))) 
    

    oder mit dem "shift-links" Operator <<, wenn die Basis 2.

ist so wäre dies eine Arbeits Variante sein:

for i in 0 ..< reverse.count { 
    let indexOfString = reverse.index(reverse.startIndex, offsetBy: i) 
    if reverse[indexOfString] == "1" { 
     labelInputInt += 1 << i 
    } 
    i += 1 
} 

Aber man kann einfach die Zeichen einer Zeichenkette in umgekehrter Reihenfolge aufzählen statt Indizierung (WHI ch ist auch effizienter):

let binaryString = "10010" 
var result = 0 
for (i, char) in binaryString.reversed().enumerated() { 
    if char == "1" { 
     result += 1 << i 
    } 
} 
print(result) 

Noch einfacher mit Vorwärts-Iteration keine reversed() oder << benötigt:

let binaryString = "10010" 
var result = 0 
for char in binaryString { 
    result = 2 * result 
    if char == "1" { 
     result += 1 
    } 
} 
print(result) 

was darauf hindeutet, reduce() zu verwenden:

let binaryString = "10010" 
let result = binaryString.reduce(0) { 2 * $0 + ($1 == "1" ? 1 : 0) } 
print(result) 

Aber warum neu erfinden die Rad? Verwenden Sie einfach init?(_:radix:) aus der Swift-Standardbibliothek (mit Fehlerprüfung kostenlos):

let binaryString = "10010" 
if let result = Int(binaryString, radix: 2) { 
    print(result) 
} else { 
    print("invalid input") 
} 
+0

'(1 << i)' statt 'Int (pow (2.0, Double (i)))' vielleicht? – vacawama

+0

@vacawama: Sie haben völlig Recht. Ich wollte die "richtige" Version der Potenzierung bereitstellen, beide Versionen jetzt hinzugefügt. –

+0

Große Antwort. Ich würde es zweimal abstimmen, wenn ich könnte. – vacawama