2017-10-02 3 views
0

Ich lerne gerade SML funktionale Sprache und ich versuche, eine Funktion zu machen, die eine Liste von Zeichen nimmt, dann sucht es nach irgendwelchen Leerstellen in der Liste, wenn es einen Leerraum findet, den es verbindet Die Zeichen vor dem Leerraum, um eine Zeichenkette zu erstellen, danach gibt sie eine Liste von Zeichenketten zurück, die aus Zeichen bestehen, die durch Leerstellen getrennt sind.Geteilte Liste von Zeichen in Liste von Wörtern

Hier ist mein Code, aber es ist etwas falsch mit dem Compiler sagt, dass es einen Fehler bei eof gibt!

fun sepWords ([]) = [] 
    | sepWords (x :: xs) = 
    let 
     val word = "" 
     val list 
     sepWords (xs) 
    in 
     if (Char.isSpace (x)) then (word = "") 
     else (word^x) 
     word :: list 
    end; 

Antwort

0
  1. Sie haben einen Syntaxfehler um die Linien val list und sepWords (xs). Vielleicht wollten Sie schreiben val list = sepWords (xs)? Sie haben auch einen Syntaxfehler um die Zeilen if ... und word :: list. Ich bin mir nicht sicher, was die Absicht hier ist, aber vielleicht denken Sie, dass word :: list den Nebeneffekt hat, "Wort" zu "Liste" hinzuzufügen?

  2. Sie haben eine Art Fehler in Ihrem if ... da der ‚dann‘ Zweig hat den Ausdruck word = "" die Bool und das ‚else‘ Zweig hat den Ausdruck Typ hat word^x, die den Typ String hat. Ein if-then-else muss in jedem Zweig den gleichen Typ haben, damit der Typ-Checker das Programm akzeptiert.

  3. Statt eine Funktion mit Typ char Liste machen -> string Liste, warum nicht eine Funktion mit Typ String machen -> string Liste? Wenn Sie das tun, können Sie sogar den Zwischenschritt der Umwandlung Ihrer Zeichenfolge in eine Zeichenliste vermeiden, indem Sie Zeichenindizes in der ursprünglichen Zeichenfolge verfolgen (z. B. indem Sie den -Teilstring verwenden).

    Ein guter Name für diese Funktion könnte "Wörter" sein.

  4. Sie haben kein Verhalten definiert, wenn mehrere Whitespaces nacheinander auftreten. Sollte words "hello world"["hello", "world"] oder ["hello", "", "world"] produzieren?

  5. Es gibt tatsächlich integrierte Bibliothek Funktionen, die dies tun:

    - String.tokens Char.isSpace "hello world"; 
    > val it = ["hello", "world"] : string list 
    
    - String.fields Char.isSpace "hello world"; 
    > val it = ["hello", "", "world"] : string list 
    
  6. Die Alternative ersten Ihre Zeichenfolge auf eine char Liste Umwandlung ist eine feine Übung in der Liste Rekursion, auch wenn die Strategie ist nicht sehr effizient.Man könnte über diese geht durch das Problem zu lösen, ein einziges Wort aus Ihrer Eingabe zusammen mit dem Rest der Zeichenfolge extrahiert:

    fun firstWord [] = ([], []) 
        | firstWord (c::cs) = 
        if Char.isSpace c 
        then ([], cs) (* throw away the space c *) 
        else case firstWord cs of 
          (fw, remainder) => (c::fw, remainder) 
    

    Sie diese wie anrufen:

    - firstWord (explode "hello world"); 
    > val it = 
        ([#"h", #"e", #"l", #"l", #"o"], [#" ", #"w", #"o", #"r", #"l", #"d"]) 
         : char list * char list 
    

    Und Sie können es nennen rekursiv solange der Rest nicht leer ist:

    fun words [] = [] 
        | words cs = 
        let val (fw, remainder) = firstWord cs 
        in implode fw :: words remainder end 
    

    Und mit diesem:

    - allWords (explode "hello world"); 
    > val it = ["hello", "", "world"] : string list 
    
+0

Vielen Dank. Deine Antwort löste nicht nur meine Probleme, sondern brachte mir auch viele Dinge bei, die mir nicht bewusst waren. Du bist der beste ! – xx3z

Verwandte Themen