Ich habe diese Herausforderung gefunden:

Lassen Sie die Funktion LetterChanges (str) in Ihrer Sprache den übergebenen str-Parameter übernehmen und mit dem folgenden Algorithmus ändern. Ersetzen Sie jeden Buchstaben in der Zeichenfolge durch den darauf folgenden Buchstaben im Alphabet (dh c wird zu d, z wird zu a). Schreiben Sie dann jeden Vokal in dieser neuen Zeichenfolge (a, e, i, o, u) groß und geben Sie schließlich diese geänderte Zeichenfolge zurück.

Ich bin neu in Julia und habe mich dieser Herausforderung gestellt. Ich fand diese Herausforderung in Julia lang sehr schwierig und konnte keine Lösung finden.

Hier habe ich versucht, wie folgt zu lösen, aber ich habe einen Fehler erhalten: Der x-Wert ist nicht definiert

Wie würden Sie das lösen?

function LetterChanges(stringis::AbstractString)

alphabet = "abcdefghijklmnopqrstuvwxyz"

vohels = "aeiou"

for Char(x) in split(stringis, "")
    if x == 'z'
        x = 'a'
    elseif x in vohels
        uppercase(x)
        else 
        Int(x)+1
        Char(x)
        println(x)
    end
end
end

Vielen Dank

1
flavinsky 17 Apr. 2018 im 17:28

4 Antworten

Beste Antwort

Als Randnotiz: Die vorgeschlagene Lösung funktioniert ordnungsgemäß. Wenn Sie jedoch eine hohe Leistung benötigen (die Sie wahrscheinlich nicht als Ursache für Ihr Problem angegeben haben), ist es effizienter, den String Builder zu verwenden:

function LetterChanges2(str::AbstractString)
    v = Set("aeiou")
    #sprint(sizehint=sizeof(str)) do io # use on Julia 0.7 - new keyword argument
    sprint() do io # use on Julia 0.6.2
        for c in str
            c = c == 'z' ? 'a' : c+1 # we assume that we got only letters from 'a':'z'
            print(io, c in v ? uppercase(c) : c)
        end
    end
end

Es ist über 10x schneller als oben.

EDIT: für Julia 0.7 ist das etwas schneller:

function LetterChanges2(str::AbstractString)
    v = BitSet(collect(Int,"aeiouy"))
    sprint(sizehint=sizeof(str)) do io # use on Julia 0.7 - new keyword argument
        for c in str
            c = c == 'z' ? 'a' : c+1 # we assume that we got only letters from 'a':'z'
            write(io, Int(c) in v ? uppercase(c) : c)
        end
    end
end
3
Bogumił Kamiński 17 Apr. 2018 im 19:17

Es liegt ein logischer Fehler vor. Es heißt "Ersetzen Sie jeden Buchstaben in der Zeichenfolge durch den darauf folgenden Buchstaben im Alphabet. Großschreiben Sie dann jeden Vokal in dieser neuen Zeichenfolge". Ihr Code prüft, ob es sich um einen Vokal handelt. Dann wird es groß geschrieben oder ersetzt. Das ist ein anderes Verhalten. Sie müssen zuerst ersetzen und dann prüfen, ob es sich um einen Vokal handelt.

Sie ersetzen 'a' durch 'Z'. Sie sollten 'z' durch 'a' ersetzen.

Die Funktion split(stringis, "") gibt ein Array von Zeichenfolgen zurück. Sie können diese Zeichenfolgen nicht in Char(x) speichern. Sie müssen sie in x speichern und dann können Sie diese Zeichenfolge mit c = x[1] in char umwandeln.

Nachdem Sie ein Zeichen transformiert haben, müssen Sie es in der Variablen c = uppercase(c) speichern.

Sie müssen ein Zeichen nicht in int umwandeln. Sie können einem Zeichen eine Nummer hinzufügen: c = c + 1

Sie müssen die neuen Zeichen in einer Zeichenfolge speichern und zurückgeben.

function LetterChanges(stringis::AbstractString)

    # some code

    str = ""
    for x in split(stringis, "")
        c = x[1]

        # logic

        str = "$str$c"
    end
    return str
end
2
Thomas Sablik 17 Apr. 2018 im 16:09

Hier ist eine andere Version, die etwas schneller ist als die Antwort von @ BogumilKaminski in Version 0.6, aber in Version 0.7 könnte dies anders sein. Auf der anderen Seite könnte es etwas weniger einschüchternd sein als die do - Blockmagie;)

function changeletters(str::String)
    vowels = "aeiouy"
    carr = Vector{Char}(length(str))
    i = 0
    for c in str
        newchar = c == 'z' ? 'a' : c + 1
        carr[i+=1] = newchar in vowels ? uppercase(newchar) : newchar
    end
    return String(carr)
end
2
DNF 17 Apr. 2018 im 18:16

Dies ist ein wörterbuchbasierter Ansatz, bei dem die Gefahr besteht, dass er des Betrugs beschuldigt wird:

function change_letters(s::String)::String
    k = collect('a':'z')
    v = vcat(collect('b':'z'), 'A')
    d = Dict{Char, Char}(zip(k, v))
    for c in Set("eiou")
        d[c - 1] = uppercase(d[c - 1])
    end
    b = IOBuffer()
    for c in s
        print(b, d[c])
    end
    return String(take!(b))
end

Es scheint sich in Bezug auf die Geschwindigkeit gut mit den anderen Julia 0.6-Methoden für lange Zeichenfolgen (z. B. 100.000 Zeichen) vergleichen zu lassen. Es gibt ein bisschen unnötigen Aufwand beim Erstellen des Wörterbuchs, der sich bei kleinen Zeichenfolgen bemerkbar macht, aber ich bin viel zu faul, um die 'a'=>'b' -Konstruktion mit langer Hand zu tippen!

1
Mark Birtwistle 18 Apr. 2018 im 17:18