2015-07-15 14 views
11

Ich bereite mich auf eine Interviewfrage vor. Eine der Fragen ist, einen Satz umzukehren. Wie "es ist ein toller Tag" bis "Tag genial". Danach fragte sie, ob es Doppelarbeit gibt, können Sie die Verdoppelung wie "Ich bin gut, ist es gut" zu "gut ist er, bin ich" entfernen? . Umkehrung und Entfernen von Duplikaten in einem Satz

für Satz der Umkehrung i

public static string reversesentence(string one) 
{ 
    StringBuilder builder = new StringBuilder(); 

    string[] split = one.Split(' '); 
    for (int i = split.Length-1; i >= 0; i--) 
    { 

     builder.Append(split[i]); 
     builder.Append(" "); 
    } 
    return builder.ToString(); 

} 

folgende Methode geschrieben haben, aber ich Ideen bin nicht auf die Beseitigung von duplication.Can bekomme ich hier

.

+0

Sie können String-Manipulationen verwenden – dada

+1

Nun, eine naive Vorgehensweise könnte sein, zu überprüfen, ob 'split [i]' aufgetreten ist oder nicht zwischen 'split [i + 1]' zu 'split.Length -1]' I vermuten! – user007

+1

Die Verwendung eines Hashes ist ebenfalls hilfreich. Verwenden Sie das Wort als Schlüssel und weisen Sie ihm den Wert 1 zu. Das gleiche Wort, das mehr als einmal auftaucht, wird einfach einem vorhandenen Wert 1 zuweisen. Ich weiß nicht, wie man das in C# macht, aber ich mache es die ganze Zeit in Perl. – Anthony

Antwort

9

Dies funktioniert:

public static string reversesentence(string one) 
{ 
    Regex reg = new Regex("\\w+"); 
    bool isFirst = true; 
    var usedWords = new HashSet<String>(StringComparer.InvariantCultureIgnoreCase); 
    return String.Join("", one.Split(' ').Reverse().Select((w => { 
     var trimmedWord = reg.Match(w).Value; 
     if (trimmedWord != null) { 
      var wasFirst = isFirst; 
      isFirst = false; 

      if (usedWords.Contains(trimmedWord)) //Is it duplicate? 
       return w.Replace(trimmedWord, ""); //Remove the duplicate phrase but keep punctuation 

      usedWords.Add(trimmedWord); 

      if (!wasFirst) //If it's the first word, don't add a leading space 
       return " " + w; 
      return w; 
     } 
     return null; 
    }))); 
} 

Grundsätzlich entscheiden wir, wenn sie unterscheidbar ist, bezogen auf das Wort ohne Interpunktion. Wenn es bereits existiert, geben Sie einfach die Interpunktion zurück. Wenn es nicht vorhanden ist, drucken Sie das gesamte Wort inklusive Satzzeichen aus.

Interpunktion entfernt auch den Raum in Ihrem Beispiel, weshalb wir nicht nur String.Join(" ", ...) tun (sonst ist das Ergebnis good he Is , am I wäre statt good he Is, am I

Test:

reversesentence("I am good, Is he good").Dump();

Ergebnis:

good he Is, am I

+1

'" (\\ b)? \\ w + (\\ b)? "' Optionale Grenzkontrolle sieht fischig aus. Es ist so, als würdest du es überhaupt nicht überprüfen. – nhahtdh

+0

@nhahtdh Wörter * brauchen * Grenzen nicht als Wörter definiert werden, aber sie * können Grenzen haben. Zum Beispiel hat "A B" - A eine Grenze am Ende, B hat keine Grenzen. 'A' hat keine Grenzen,' A' hat eine Grenze am Anfang, aber nicht am Ende. Es überprüft es definitiv, aber es erfordert es nicht. – Rob

+0

@nhahtdh Nevermind, ich denke heute nicht gerade .. du hast Recht - in allen Fällen muss es nicht die Grenze aufheben. Ich werde den Code aktualisieren – Rob

3

die andere Antwort Punkte etwas Hilfe zu verwenden Abstraktionen, aber die Interviewer wollen normalerweise die Implementierung sehen

F oder die Umkehrung, der übliche Trick besteht darin, den Satz zuerst umzukehren und dann jedes Wort umzukehren, während Sie von links nach rechts reisen. Ein Leerzeichen wird dir sagen, dass du das Ende eines Wortes erreicht hast. (Siehe Programming Interviews Exposed für eine Lösung oder einfach googeln. Dies war eine sehr beliebte Interviewfrage). Ihr Ansatz funktioniert, ist aber verpönt, weil Sie zusätzlichen Raum (O (n)) verwenden.

Für Duplikate zu entfernen, wenn Sie mit ASCII nur arbeiten, können Sie wie folgt vorgehen:

bool[] seenChars = new bool[128]; 
    var sb = new StringBuilder(); 

    foreach(char c in stringOne) 
    { 
     if(!seenChars[c]){ 
      seenChars[c] = true; 
      sb.Append(c); 
     } 
    } 

    return sb.ToString(); 

Die Idee, den Wert des char als Index im Array zu verwenden ist, Ihnen zu sagen, ob Du hast diesen Charakter schon einmal gesehen oder nicht. Mit diesem Ansatz verwenden Sie O (1) -Raum!

Bearbeiten: Wenn Sie Wörter duplizieren möchten, möchten Sie wahrscheinlich ein HashSet verwenden und überspringen Sie es hinzufügen, wenn es bereits vorhanden ist.

+0

Dies entfernt doppelte Zeichen, keine Wörter .. – Rob

3

versucht, diesen

string sentence = "I am good, Is he good"; 


     var words = sentence.Split(new char[]{' ',','}).Distinct(StringComparer.CurrentCultureIgnoreCase); 

     var stringBuilder = new StringBuilder(); 

     foreach(var item in words) 
     { 
      stringBuilder.Append(item); 
      stringBuilder.Append(" "); 
     } 
     Console.Write(stringBuilder); 
     Console.ReadLine(); 
+0

1) 'string.Join' ist dein Freund. 2) Das erzeugt ein nachstehendes Leerzeichen 3) Es kehrt nicht um. – CodesInChaos

9

Für Normal Umkehrung:

String.Join(" ", text.Split(' ').Reverse()) 

Für Umkehrung mit doppelter Entfernung:

String.Join(" ", text.Split(' ').Reverse().Distinct()) 

Beide arbeiten gut für Strings nur Leerzeichen als Trennzeichen enthalten. Wenn Sie die , vorstellen, dann wird das Problem schwieriger. So sehr, dass Sie angeben müssen, wie es gehandhabt werden soll.Zum Beispiel, sollte "I am good, Is he good""good he Is am I" oder "good he Is , am I" werden? Ihr Beispiel in der Frage ändert den Fall von "Is" und gruppiert damit auch die ",". Das scheint mir falsch zu sein.

+0

Ist garantiert, dass 'Distinct' die Reihenfolge nicht ändert? – raznagul

+0

@raznagul - Ja, es ist garantiert. Der Algorithmus durchläuft den Aufzählungswert in der Reihenfolge und liefert nur Werte, wenn er sie das erste Mal sieht. – Enigmativity

Verwandte Themen