Kehren Sie die Reihenfolge der Wörter in einer Zeichenfolge um


68

Ich habe dies string s1 = "My name is X Y Z"und ich möchte die Reihenfolge der Wörter so umkehren s1 = "Z Y X is name My".

Ich kann es mit einem zusätzlichen Array tun. Ich habe mir überlegt, aber ist es möglich, dies an Ort und Stelle (ohne Verwendung zusätzlicher Datenstrukturen) und mit einer zeitlichen Komplexität von O (n) zu tun?


Was meinst du mit zusätzlichem Array? Zusätzlich zu dem, den Sie zum Speichern der "Token" (dh Wörter) verwenden würden, oder zusätzlich zu der Zeichenfolge, die Sie als Beispiel angegeben haben.
Mike Dinescu


21
string.split(' ').reverse().join(' ')
zzzzBov

6
^ verwendet zusätzlichen Speicher
Sucher

Wie KodeSeeker sagt, erstellt die zzzzBov-Lösung mehrere Zwischenpuffer. Wenn Ihre Plattform Ihrer Wahl "unveränderliche" Zeichenfolgen (wie .NET) verwendet, schaffen Sie definitiv auch zusätzlichen Speicherplatz, was im Interview erwähnenswert ist.
Vtortola

Antworten:


128

Kehren Sie die gesamte Zeichenfolge um und kehren Sie dann die Buchstaben jedes einzelnen Wortes um.

Nach dem ersten Durchgang wird die Zeichenfolge sein

s1 = "Z Y X si eman yM"

und nach dem zweiten Durchgang wird es sein

s1 = "Z Y X is name My"

2
"name" zum Beispiel wird in seinem Beispiel nicht umgekehrt.
Sev

15
Deshalb machen Sie den zweiten Durchgang, um die Buchstaben jedes Wortes umzukehren.
Bill the Lizard

31
@Miky, nein, es ist O (n). Das Umkehren der gesamten Zeichenfolge ist in O (n) einfach, und das Umkehren jedes Wortes in einer Zeichenfolge ist auch in O (n) einfach. O (n) + O (n) = O (n).
Triptychon

4
Denken Sie daran, dass sich das Umkehren einer Zeichenfolge für alle praktischen Anwendungen im Zusammenhang mit der Internationalisierung als Albtraum herausstellt und nicht nur das Umkehren einer Reihe von Zeichen
Grozz

2
Ich denke, es gibt keine Möglichkeit, dieses Problem in Java zu lösen, da String in Java unveränderlich ist. Hab ich recht?
JohnnyHuo

33

Kehren Sie die Zeichenfolge um und kehren Sie dann in einem zweiten Durchgang jedes Wort um ...

in c # vollständig an Ort und Stelle ohne zusätzliche Arrays:

static char[] ReverseAllWords(char[] in_text)
{
    int lindex = 0;
    int rindex = in_text.Length - 1;
    if (rindex > 1)
    {
        //reverse complete phrase
        in_text = ReverseString(in_text, 0, rindex);

        //reverse each word in resultant reversed phrase
        for (rindex = 0; rindex <= in_text.Length; rindex++)
        {
            if (rindex == in_text.Length || in_text[rindex] == ' ')
            {
                in_text = ReverseString(in_text, lindex, rindex - 1);
                lindex = rindex + 1;
            }
        }
    }
    return in_text;
}

static char[] ReverseString(char[] intext, int lindex, int rindex)
{
    char tempc;
    while (lindex < rindex)
    {
        tempc = intext[lindex];
        intext[lindex++] = intext[rindex];
        intext[rindex--] = tempc;
    }
    return intext;
}

1
Glaubst du, es ist eine O (n) -Operation? Wenn wir ReverseString innerhalb dieser for-Schleife aufrufen, geschieht dies meiner Meinung nach nicht innerhalb der O (n) -Zeit.
Pritam Karmakar

3
@Pritam: ReverseString wird nicht jedes Mal in der for-Schleife ausgeführt. Es gibt einen vollständigen Rückwärtsdurchlauf für die Zeichenfolge (erster Durchgang), dann findet die for-Schleife die Leerzeichen, die die Wortgrenzen abgrenzen (ein weiterer Durchgang). Der innerhalb (und vor allem nicht an jedem Index) aufgerufene ReverseString ist O (m), wobei m die Länge des Wortes ist. Es wird für jedes Wort aufgerufen. Die Summe aller O (m) -Wortlängenoperationen entspricht O (n). Somit ist dieser Algorithmus der schlechteste Fall 3 * O (n), der immer noch O (n) ist. Wenn ReverseString bei jedem Index aufgerufen würde, denke ich, dass Sie richtig wären ...
Demi

Was ist mit aufeinanderfolgenden Leerzeichen in Worten?
user2441441

15
Not exactly in place, but anyway: Python:

>>> a = "These pretzels are making me thirsty"
>>> " ".join(a.split()[::-1])
'thirsty me making are pretzels These'

1
Diese Version ersetzt mehrere Leerzeichen, Tabulatoren und Zeilenumbrüche durch einzelne Leerzeichen.
Triptychon

12
Nein @Shadow, es ist keine wirklich gute Antwort. Die Frage betraf einen Algorithmus zur Lösung des Problems (unter Berücksichtigung der verwendeten Datenstrukturen und der Reihenfolge der Komplexität) und keine Implementierung in einer Hochsprache. (Und auch nicht deins - obwohl beide "korrekt" waren)
Mike Dinescu

13

In Smalltalk:

'These pretzels are making me thirsty' subStrings reduce: [:a :b| b, ' ', a]

Ich weiß, niemand kümmert sich um Smalltalk, aber es ist so schön für mich.


4

Sie können die Umkehrung nicht ohne mindestens eine zusätzliche Datenstruktur durchführen. Ich denke, die kleinste Struktur wäre ein einzelnes Zeichen als Puffer, während Sie Buchstaben tauschen. Es kann immer noch als "an Ort und Stelle" betrachtet werden, ist jedoch nicht vollständig "frei von zusätzlichen Datenstrukturen".

Unten finden Sie Code, der implementiert, was Bill the Lizard beschreibt:

string words = "this is a test";

// Reverse the entire string
for(int i = 0; i < strlen(words) / 2; ++i) {
  char temp = words[i];
  words[i] = words[strlen(words) - i];
  words[strlen(words) - i] = temp;
}

// Reverse each word
for(int i = 0; i < strlen(words); ++i) {
  int wordstart = -1;
  int wordend = -1;
  if(words[i] != ' ') {
    wordstart = i;
    for(int j = wordstart; j < strlen(words); ++j) {
      if(words[j] == ' ') {
        wordend = j - 1;
        break;
      }
    }
    if(wordend == -1)
      wordend = strlen(words);
    for(int j = wordstart ; j <= (wordend + wordstart) / 2 ; ++j) {
      char temp = words[j];
      words[j] = words[wordend - (j - wordstart)];
      words[wordend - (j - wordstart)] = temp;
    }
    i = wordend;
  }
}

5
Sie können dies ohne ein zusätzliches Zeichen tun, wenn Sie bitweise oder arithmetische Tricks anwenden. Zum Beispiel: a ^ = b; b ^ = a; a ^ = b; wird a und b tauschen.
Niki Yoshiuchi

Du hättest speichern können len = strlen(words). Die mehrmalige Verwendung strlen(words)dauert länger.
Sunny

1
Möglicherweise etwas spät, aber sollte es nicht for(int j = wordstart ; j <= (wordend + wordstart) / 2 ; ++j)in der letzten for-Schleife statt minus sein?
CLD

3

Welche Sprache? Bei PHP können Sie im Weltraum explodieren und das Ergebnis an array_reverse übergeben.

Wenn es nicht PHP ist, müssen Sie etwas etwas komplexeres tun wie:

words = aString.split(" ");
for (i = 0; i < words.length; i++) {
    words[i] = words[words.length-i];
}

1
Ich glaube nicht, dass dies funktionieren würde, da für i> words.length / 2 die Wörter zurückkopiert werden. Beispiel: "Dies ist ein Test" wird zu "Test aa Test". Auch wenn i 0 ist, verursachen Wörter [words.length-i] eine Ausnahme (außerhalb der Grenzen).
Chaos

1
(Sie können einfach den Zustand der Schleife ändern, um i <words.length / 2 zu sein)
Chaos

2
public static String ReverseString(String str)
{
    int word_length = 0;
    String result = "";
    for (int i=0; i<str.Length; i++)
    {
        if (str[i] == ' ')
        {
            result = " " + result;
            word_length = 0;
        } else 
        {
            result = result.Insert(word_length, str[i].ToString());
            word_length++;
        }
    }
    return result;
}

Dies ist C # -Code.


2
In Python...

ip = "My name is X Y Z"
words = ip.split()
words.reverse()
print ' '.join(words)

Wie auch immer, Cookamunga lieferte eine gute Inline-Lösung mit Python!


Die Lösung ist nicht korrekt, wenn zwischen Wörtern mehrere Leerzeichen stehen.
Wei Qiu

2

Dies setzt voraus, dass alle Wörter durch Leerzeichen getrennt sind:

#include <stdio.h>
#include <string.h>

int main()
{
    char string[] = "What are you looking at";
    int i, n = strlen(string);

    int tail = n-1;
    for(i=n-1;i>=0;i--)
    {
        if(string[i] == ' ' || i == 0)
        {
            int cursor = (i==0? i: i+1);
            while(cursor <= tail)
                printf("%c", string[cursor++]);
            printf(" ");
            tail = i-1;
        }
    }
    return 0;
}

2
class Program
{
    static void Main(string[] args)
    {
        string s1 =" My Name varma:;
        string[] arr = s1.Split(' ');
        Array.Reverse(arr);
        string str = string.Join(" ", arr);
        Console.WriteLine(str);
        Console.ReadLine();

    }
}

1

Das ist nicht perfekt, aber es funktioniert gerade für mich. Ich weiß nicht, ob es übrigens O (n) Laufzeit hat (studiert es noch ^^), aber es verwendet ein zusätzliches Array, um die Aufgabe zu erfüllen.

Es ist wahrscheinlich nicht die beste Antwort auf Ihr Problem, da ich eine Zielzeichenfolge verwende, um die umgekehrte Version zu speichern, anstatt jedes Wort in der Quellzeichenfolge zu ersetzen. Das Problem ist, dass ich eine lokale Stapelvariable namens buf verwende, um alle Wörter zu kopieren, und ich kann nicht kopieren, sondern in die Quellzeichenfolge, da dies zu einem Absturz führen würde, wenn die Quellzeichenfolge vom Typ const char * ist.

Aber es war mein erster Versuch, s.th. so :) Ok genug blablub. Hier ist Code:

#include <iostream>
using namespace std;

void reverse(char *des, char * const s);
int main (int argc, const char * argv[])
{    
    char* s = (char*)"reservered. rights All Saints. The 2011 (c) Copyright 11/10/11 on Pfundstein Markus by Created";
    char *x = (char*)"Dogfish! White-spotted Shark, Bullhead";

    printf("Before: |%s|\n", x);
    printf("Before: |%s|\n", s);

    char *d = (char*)malloc((strlen(s)+1)*sizeof(char));  
    char *i = (char*)malloc((strlen(x)+1)*sizeof(char));

    reverse(d,s);
    reverse(i,x);

    printf("After: |%s|\n", i);
    printf("After: |%s|\n", d);

    free (i);
    free (d);

    return 0;
}

void reverse(char *dest, char *const s) {
    // create a temporary pointer
    if (strlen(s)==0) return;
    unsigned long offset = strlen(s)+1;

    char *buf = (char*)malloc((offset)*sizeof(char));
    memset(buf, 0, offset);

    char *p;
    // iterate from end to begin and count how much words we have
    for (unsigned long i = offset; i != 0; i--) {
        p = s+i;
        // if we discover a whitespace we know that we have a whole word
        if (*p == ' ' || *p == '\0') {
            // we increment the counter
            if (*p != '\0') {
                // we write the word into the buffer
                ++p;
                int d = (int)(strlen(p)-strlen(buf));
                strncat(buf, p, d);
                strcat(buf, " ");
            }
        }
    }

    // copy the last word
    p -= 1;
    int d = (int)(strlen(p)-strlen(buf));
    strncat(buf, p, d);
    strcat(buf, "\0");

    // copy stuff to destination string
    for (int i = 0; i < offset; ++i) {
        *(dest+i)=*(buf+i);
    }

    free(buf);
}

1

Wir können die Zeichenfolge in einen Stapel einfügen, und wenn wir die Wörter extrahieren, werden sie in umgekehrter Reihenfolge angezeigt.

void ReverseWords(char Arr[])
{
    std::stack<std::string> s;
    char *str;
    int length = strlen(Arr);
    str = new char[length+1];
    std::string ReversedArr;
    str = strtok(Arr," ");
    while(str!= NULL)
    {
        s.push(str);
        str = strtok(NULL," ");
    }
    while(!s.empty())
    {
        ReversedArr = s.top();
        cout << " " << ReversedArr;
        s.pop();
    }
}

1

Dieses schnelle Programm funktioniert. Es werden jedoch keine Eckfälle überprüft.

#include <stdio.h>
#include <stdlib.h>
struct node
{
    char word[50];
    struct node *next;
};
struct stack
{
    struct node *top;
};
void print (struct stack *stk);
void func (struct stack **stk, char *str);
main()
{
    struct stack *stk = NULL;
    char string[500] = "the sun is yellow and the sky is blue";
    printf("\n%s\n", string);
    func (&stk, string);
    print (stk);
}
void func (struct stack **stk, char *str)
{
    char *p1 = str;
    struct node *new = NULL, *list = NULL;
    int i, j;
    if (*stk == NULL)
    {
        *stk = (struct stack*)malloc(sizeof(struct stack));
        if (*stk == NULL)
            printf("\n####### stack is not allocated #####\n");
        (*stk)->top = NULL;
    }
    i = 0;
    while (*(p1+i) != '\0')
    {
        if (*(p1+i) != ' ')
        {
            new = (struct node*)malloc(sizeof(struct node));
            if (new == NULL)
                printf("\n####### new is not allocated #####\n");
            j = 0;
            while (*(p1+i) != ' ' && *(p1+i) != '\0')
            {
                new->word[j] = *(p1 + i);
                i++;
                j++;
            }
            new->word[j++] = ' ';
            new->word[j] = '\0';
            new->next = (*stk)->top;
            (*stk)->top = new;
        }
        i++;
   }
}
void print (struct stack *stk)
{
    struct node *tmp = stk->top;
    int i;
    while (tmp != NULL)
    {
        i = 0;
        while (tmp->word[i] != '\0')
        {
            printf ("%c" , tmp->word[i]);
            i++;
        }
        tmp = tmp->next;
    }
    printf("\n");
}

Ich, Ihre Antwort, versuche also, die Lösung zu erklären, anstatt nur den Code einzufügen. Code ist gut, aber nur Code nicht.
Angainor

Es beantwortet auch nicht die ursprüngliche Frage. Ich sehe dort eine Menge zusätzlicher Datenstrukturen / Puffer ...
Ahans

1

Die meisten dieser Antworten berücksichtigen keine führenden und / oder nachfolgenden Leerzeichen in der Eingabezeichenfolge. Betrachten Sie den Fall von str=" Hello world"... Das einfache Algo, die gesamte Zeichenfolge umzukehren und einzelne Wörter umzukehren, führt dazu, dass Trennzeichen umgedreht werden f(str) == "world Hello ".

Das OP sagte "Ich möchte die Reihenfolge der Wörter umkehren" und erwähnte nicht, dass führende und nachfolgende Leerzeichen ebenfalls umgedreht werden sollten! Obwohl es bereits eine Menge Antworten gibt, werde ich in C ++ eine [hoffentlich] korrektere bereitstellen:

#include <string>
#include <algorithm>

void strReverseWords_inPlace(std::string &str)
{
  const char delim = ' ';
  std::string::iterator w_begin, w_end;
  if (str.size() == 0)
    return;

  w_begin = str.begin();
  w_end   = str.begin();

  while (w_begin != str.end()) {
    if (w_end == str.end() || *w_end == delim) {
      if (w_begin != w_end)
        std::reverse(w_begin, w_end);
      if (w_end == str.end())
        break;
      else
        w_begin = ++w_end;
    } else {
      ++w_end;
    }
  }

  // instead of reversing str.begin() to str.end(), use two iterators that
  // ...represent the *logical* begin and end, ignoring leading/traling delims
  std::string::iterator str_begin = str.begin(), str_end = str.end();
  while (str_begin != str_end && *str_begin == delim)
    ++str_begin;
  --str_end;
  while (str_end != str_begin && *str_end == delim)
    --str_end;
  ++str_end;
  std::reverse(str_begin, str_end);
}

1

Meine Version der Verwendung von Stack:

public class Solution {
    public String reverseWords(String s) {
        StringBuilder sb = new StringBuilder();
        String ns= s.trim();
        Stack<Character> reverse = new Stack<Character>();
        boolean hadspace=false;

        //first pass
        for (int i=0; i< ns.length();i++){
            char c = ns.charAt(i);
            if (c==' '){
                if (!hadspace){
                    reverse.push(c);
                    hadspace=true;
                }
            }else{
                hadspace=false;
                reverse.push(c);
            }
        }
        Stack<Character> t = new Stack<Character>();
        while (!reverse.empty()){
            char temp =reverse.pop();
            if(temp==' '){
                //get the stack content out append to StringBuilder
                while (!t.empty()){
                    char c =t.pop();
                    sb.append(c);
                }
                sb.append(' ');
            }else{
                //push to stack
                t.push(temp);
            }
        }
        while (!t.empty()){
            char c =t.pop();
            sb.append(c);
        }
        return sb.toString();
    }
}

1

Speichern Sie jedes Wort als Zeichenfolge im Array und drucken Sie es dann von Ende

public void rev2() {
    String str = "my name is ABCD";
    String A[] = str.split(" ");

    for (int i = A.length - 1; i >= 0; i--) {
        if (i != 0) {
            System.out.print(A[i] + " ");
        } else {
            System.out.print(A[i]);
        }
    }

}

1

Wenn Sie in Python nicht [:: - 1] oder reverse () verwenden können, haben Sie folgende einfache Möglichkeit:

def reverse(text):

  r_text = text.split(" ")
  res = []
  for word in range(len(r_text) - 1, -1, -1): 
    res.append(r_text[word])

  return " ".join(res)

print (reverse("Hello World"))

>> World Hello
[Finished in 0.1s]

1

Drucken von Wörtern in umgekehrter Reihenfolge einer bestimmten Anweisung mit C #:

    void ReverseWords(string str)
    {
        int j = 0;
        for (int i = (str.Length - 1); i >= 0; i--)
        {
            if (str[i] == ' ' || i == 0)
            {
                j = i == 0 ? i : i + 1;

                while (j < str.Length && str[j] != ' ')
                    Console.Write(str[j++]);
                Console.Write(' ');
            }
        }
    }

1

Hier ist die Java-Implementierung:

public static String reverseAllWords(String given_string)
{
    if(given_string == null || given_string.isBlank())
        return given_string;

    char[] str = given_string.toCharArray();
    int start = 0;

    // Reverse the entire string
    reverseString(str, start, given_string.length() - 1);

    // Reverse the letters of each individual word
    for(int end = 0; end <= given_string.length(); end++)
    {
        if(end == given_string.length() || str[end] == ' ')
        {
            reverseString(str, start, end-1);
            start = end + 1;
        }
    }
    return new String(str);
}

// In-place reverse string method
public static void reverseString(char[] str, int start, int end)
{
    while(start < end)
    {
        char temp = str[start];
        str[start++] = str[end];
        str[end--] = temp;
    }
}

0

Eigentlich die erste Antwort:

words = aString.split(" ");
for (i = 0; i < words.length; i++) {
    words[i] = words[words.length-i];
}

funktioniert nicht, weil es in der zweiten Hälfte der Schleife die Arbeit in der ersten Hälfte rückgängig macht. Also, i <words.length / 2 würde funktionieren, aber ein klareres Beispiel ist folgendes:

words = aString.split(" "); // make up a list
i = 0; j = words.length - 1; // find the first and last elements
while (i < j) {
    temp = words[i]; words[i] = words[j]; words[j] = temp; //i.e. swap the elements
    i++; 
    j--;
}

Hinweis: Ich bin mit der PHP-Syntax nicht vertraut und habe die Inkrementierungs- und Dekrementierungssyntax erraten, da sie Perl ähnlich zu sein scheint.


Übrigens, ich stehe korrigiert da: Die erste Antwort hätte für die Modifikation words.length / 2 funktioniert, wenn sie getauscht worden wäre. In der jetzigen Form werden Informationen aus dem Array gelöscht.

[Sie sprechen über meine Antwort] Ups, unter den Loop-Bedingungen. Ich möchte nur klarstellen, dass meine Code-Antwort nicht für PHP ist, sondern mehr oder weniger Pseudocode.
Alex S

0

Wie wäre es mit ...

var words = "My name is X Y Z";
var wr = String.Join( " ", words.Split(' ').Reverse().ToArray() );

Ich denke, das stimmt nicht.


verwendet zusätzliche Datenstrukturen, die seine Frage nicht beantworten.
Demi

Er sagte, er könnte ein zusätzliches Array verwenden ... oh, ich verstehe, er hat dort einen Bonus-Teil.
JP Alioto

0

In c können Sie dies so tun, O (N) und nur O (1) -Datenstrukturen (dh ein Zeichen) verwenden.

#include<stdio.h>
#include<stdlib.h>
main(){
  char* a = malloc(1000);
  fscanf(stdin, "%[^\0\n]", a);
  int x = 0, y;
  while(a[x]!='\0')
  {
    if (a[x]==' ' || a[x]=='\n')
    {
      x++;
    }
    else
    {
      y=x;
      while(a[y]!='\0' && a[y]!=' ' && a[y]!='\n')
      { 
        y++;
      }
      int z=y;
      while(x<y)
      {
        y--;
        char c=a[x];a[x]=a[y];a[y]=c; 
        x++;
      }
      x=z;
    }
  }

  fprintf(stdout,a);
  return 0;
}

0

Mit sscanf geht es einfacher:

void revertWords(char *s);
void revertString(char *s, int start, int n);
void revertWordsInString(char *s);

void revertString(char *s, int start, int end)
{
     while(start<end)
     {
         char temp = s[start];
         s[start] = s[end];
         s[end]=temp;
         start++;
         end --;
     }
}


void revertWords(char *s)
{
  int start = 0;

  char *temp = (char *)malloc(strlen(s) + 1);
  int numCharacters = 0;
  while(sscanf(&s[start], "%s", temp) !=EOF)
  {
      numCharacters = strlen(temp);

      revertString(s, start, start+numCharacters -1);
      start = start+numCharacters + 1;
      if(s[start-1] == 0)
      return;

  }
  free (temp);

}

void revertWordsInString(char *s)
{
   revertString(s,0, strlen(s)-1);
   revertWords(s);
}

int main()
{
   char *s= new char [strlen("abc deff gh1 jkl")+1];
   strcpy(s,"abc deff gh1 jkl");
   revertWordsInString(s);
   printf("%s",s);
   return 0;
}

0
import java.util.Scanner;

public class revString {
   static char[] str;

   public static void main(String[] args) {
    //Initialize string
    //str = new char[] { 'h', 'e', 'l', 'l', 'o', ' ', 'a', ' ', 'w', 'o',
    //'r', 'l', 'd' };
    getInput();

    // reverse entire string
    reverse(0, str.length - 1);

    // reverse the words (delimeted by space) back to normal
    int i = 0, j = 0;
    while (j < str.length) {

        if (str[j] == ' ' || j == str.length - 1) {

            int m = i;
            int n;

            //dont include space in the swap. 
            //(special case is end of line)
            if (j == str.length - 1)
                n = j;
            else
                n = j -1;


            //reuse reverse
            reverse(m, n);

            i = j + 1;

        }
        j++;
    }

    displayArray();
}

private static void reverse(int i, int j) {

    while (i < j) {

        char temp;
        temp = str[i];
        str[i] = str[j];
        str[j] = temp;

        i++;
        j--;
    }
}
private static void getInput() {
    System.out.print("Enter string to reverse: ");
    Scanner scan = new Scanner(System.in);
    str = scan.nextLine().trim().toCharArray(); 
}

private static void displayArray() {
    //Print the array
    for (int i = 0; i < str.length; i++) {
        System.out.print(str[i]);
    }
}

}}


0

In Java mit einem zusätzlichen String (mit StringBuilder):

public static final String reverseWordsWithAdditionalStorage(String string) {
    StringBuilder builder = new StringBuilder();

    char c = 0;
    int index = 0;
    int last = string.length();
    int length = string.length()-1;
    StringBuilder temp = new StringBuilder();
    for (int i=length; i>=0; i--) {
        c = string.charAt(i);
        if (c == SPACE || i==0) {
            index = (i==0)?0:i+1;
            temp.append(string.substring(index, last));
            if (index!=0) temp.append(c);
            builder.append(temp);
            temp.delete(0, temp.length());
            last = i;
        }
    }

    return builder.toString();
}

In Java an Ort und Stelle:

public static final String reverseWordsInPlace(String string) {
    char[] chars = string.toCharArray();

    int lengthI = 0;
    int lastI = 0;
    int lengthJ = 0;
    int lastJ = chars.length-1;

    int i = 0;
    char iChar = 0;
    char jChar = 0;
    while (i<chars.length && i<=lastJ) {
        iChar = chars[i];
        if (iChar == SPACE) {
            lengthI = i-lastI;
            for (int j=lastJ; j>=i; j--) {
                jChar = chars[j];
                if (jChar == SPACE) {
                    lengthJ = lastJ-j;
                    swapWords(lastI, i-1, j+1, lastJ, chars);
                    lastJ = lastJ-lengthI-1;
                    break;
                }
            }
            lastI = lastI+lengthJ+1;
            i = lastI;
        } else {
            i++;
        }
    }

    return String.valueOf(chars);
}

private static final void swapWords(int startA, int endA, int startB, int endB, char[] array) {
    int lengthA = endA-startA+1;
    int lengthB = endB-startB+1;

    int length = lengthA;
    if (lengthA>lengthB) length = lengthB;

    int indexA = 0;
    int indexB = 0;
    char c = 0;
    for (int i=0; i<length; i++) {
        indexA = startA+i;
        indexB = startB+i;

        c = array[indexB];
        array[indexB] = array[indexA];
        array[indexA] = c;
    }

    if (lengthB>lengthA) {
        length = lengthB-lengthA;
        int end = 0;
        for (int i=0; i<length; i++) {
            end = endB-((length-1)-i);
            c = array[end];
            shiftRight(endA+i,end,array);
            array[endA+1+i] = c;
        }
    } else if (lengthA>lengthB) {
        length = lengthA-lengthB;
        for (int i=0; i<length; i++) {
            c = array[endA];
            shiftLeft(endA,endB,array);
            array[endB+i] = c;
        }
    }
}

private static final void shiftRight(int start, int end, char[] array) {
    for (int i=end; i>start; i--) {
        array[i] = array[i-1];
    }
}

private static final void shiftLeft(int start, int end, char[] array) {
    for (int i=start; i<end; i++) {
        array[i] = array[i+1];
    }
}

0

Hier ist eine C-Implementierung, die das Wort inlace umkehrt und komplex ist O(n).

char* reverse(char *str, char wordend=0)
{
    char c;
    size_t len = 0;
    if (wordend==0) {
        len = strlen(str);
    }
    else {
        for(size_t i=0;str[i]!=wordend && str[i]!=0;i++)
            len = i+1;
    }
            for(size_t i=0;i<len/2;i++) {
                c = str[i];
                str[i] = str[len-i-1];
                str[len-i-1] = c;
            }
    return str;
}

char* inplace_reverse_words(char *w)
{
    reverse(w); // reverse all letters first
    bool is_word_start = (w[0]!=0x20);

    for(size_t i=0;i<strlen(w);i++){
        if(w[i]!=0x20 && is_word_start) {
            reverse(&w[i], 0x20); // reverse one word only
            is_word_start = false;
        }
        if (!is_word_start && w[i]==0x20) // found new word
            is_word_start = true;
    }
    return w;
}

0

c # Lösung zum Umkehren von Wörtern in einem Satz

using System;
class helloworld {
    public void ReverseString(String[] words) {
        int end = words.Length-1;
        for (int start = 0; start < end; start++) {
            String tempc;
            if (start < end ) {
                tempc = words[start];
                words[start] = words[end];
                words[end--] = tempc;
            }
        }
        foreach (String s1 in words) {
            Console.Write("{0} ",s1);
        }
    }
}
class reverse {
    static void Main() {
        string s= "beauty lies in the heart of the peaople";
        String[] sent_char=s.Split(' ');
        helloworld h1 = new helloworld();
        h1.ReverseString(sent_char);
    }
}

Ausgabe: peaople the of heart the in lies beauty Drücken Sie eine beliebige Taste, um fortzufahren. . .



0
public class manip{

public static char[] rev(char[] a,int left,int right) {
    char temp;
    for (int i=0;i<(right - left)/2;i++)    {
        temp = a[i + left];
        a[i + left] = a[right -i -1];
        a[right -i -1] = temp;
    }

    return a;
}
public static void main(String[] args) throws IOException {

    String s= "i think this works";
    char[] str = s.toCharArray();       
    int i=0;
    rev(str,i,s.length());
    int j=0;
    while(j < str.length) {
        if (str[j] != ' ' && j != str.length -1) {
            j++;
        } else
        {
            if (j == (str.length -1))   {
                j++;
            }
            rev(str,i,j);
            i=j+1;
            j=i;
        }
    }
    System.out.println(str);
}

0

Ich weiß, dass es mehrere richtige Antworten gibt. Hier ist die in C, die ich mir ausgedacht habe. Dies ist eine Implementierung der ausgenommenen Antwort. Die Zeitkomplexität ist O (n) und es wird keine zusätzliche Zeichenfolge verwendet.

#include<stdio.h>

char * strRev(char *str, char tok)
{
   int len = 0, i;
   char *temp = str;
   char swap;

   while(*temp != tok && *temp != '\0') {
      len++; temp++;
   }   
   len--;

   for(i = 0; i < len/2; i++) {
      swap = str[i];
      str[i] = str[len - i]; 
      str[len - i] = swap;
   }   

   // Return pointer to the next token.
   return str + len + 1;
}

int main(void)
{
   char a[] = "Reverse this string.";
   char *temp = a;

   if (a == NULL)
      return -1; 

   // Reverse whole string character by character.
   strRev(a, '\0');

   // Reverse every word in the string again.
   while(1) {
      temp = strRev(temp, ' ');
      if (*temp == '\0')
         break;

      temp++;
   }   
   printf("Reversed string: %s\n", a); 
   return 0;
}

Haben Sie einen Fehler. Während Sie die Zeichenfolge umkehren, ist Tejendra ein guter Junge. Die Ausgabe ist ein Junge. Tejnedra.
Tejendra
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.