web-dev-qa-db-fra.com

Inverser l'ordre des mots dans une chaîne

J'ai ce string s1 = "My name is X Y Z" et je veux inverser l'ordre des mots pour que s1 = "Z Y X is name My"

Je peux le faire en utilisant un tableau supplémentaire. J'ai beaucoup réfléchi, mais est-il possible de le faire sur place (sans utiliser de structures de données supplémentaires) et avec la complexité temporelle étant O (n)?

68
Arnkrishn

Inverser la chaîne entière, puis inverser les lettres de chaque mot individuel.

Après la première passe, la chaîne sera

s1 = "Z Y X si eman yM"

et après le deuxième passage ce sera

s1 = "Z Y X is name My"
129
Bill the Lizard

inverse la chaîne puis, en une seconde passe, inverse chaque mot ...

en c #, complètement en place sans tableaux supplémentaires:

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;
}
33
Demi
Not exactly in place, but anyway: Python:

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

En Smalltalk:

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

Je sais que personne ne se soucie de Small Talk, mais c'est tellement beau pour moi.

13
Wrameerez

Vous ne pouvez pas effectuer l'inversion sans au moins une structure de données supplémentaire. Je pense que la plus petite structure serait un caractère unique servant de tampon pendant que vous échangez des lettres. Il peut toujours être considéré "en place", mais ce n'est pas complètement "extra libre de structure de données".

Ci-dessous, le code implémentant ce que Bill the Lizard décrit:

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;
  }
}
4
baumgart

Quelle langue? Si PHP, vous pouvez exploser sur l'espace, puis passez le résultat à array_reverse.

Si ce n'est pas PHP, vous devrez faire quelque chose de légèrement plus complexe, comme:

words = aString.split(" ");
for (i = 0; i < words.length; i++) {
    words[i] = words[words.length-i];
}
3
Alex S
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();

    }
}
2
Nikola Mitev

Ceci suppose que tous les mots sont séparés par des espaces:

#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
AbhinavChoudhury
In Python...

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

Quoi qu'il en soit, cookamunga a fourni une bonne solution en ligne utilisant python!

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;
}

C'est du code C #.

2
Johnny Kage

Ce n'est pas parfait, mais cela fonctionne pour moi en ce moment. Je ne sais pas s'il a O(n) le temps d'exécution btw (l'étudie toujours ^^), mais il utilise un tableau supplémentaire pour remplir la tâche.

Ce n'est probablement pas la meilleure réponse à votre problème parce que j'utilise une chaîne de caractères pour enregistrer la version inversée au lieu de remplacer chaque mot de la chaîne source. Le problème est que j'utilise une variable de pile locale nommée buf pour copier tous les mots et que je ne peux pas copier mais dans la chaîne source car cela entraînerait un blocage si la chaîne source est const char * type.

Mais c’était ma première tentative d’écrire comme ça :) Ok assez de blablub. voici le 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
markus_p

En Python, si vous ne pouvez pas utiliser [:: - 1] ou reverse (), voici le moyen simple:

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
Pyxis

Ma version de l'utilisation de la pile:

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
jg7933

La plupart de ces réponses ne prennent pas en compte les espaces de début et/ou de fin dans la chaîne d'entrée. Prenons le cas de str=" Hello world"... Le simple algo consistant à inverser toute la chaîne et à inverser des mots individuels aboutit à inverser des délimiteurs, ce qui entraîne un f(str) == "world Hello ".

Le PO a déclaré "Je veux inverser l'ordre des mots" et n'a pas mentionné que les espaces de début et de fin doivent également être inversés! Donc, bien qu'il y ait déjà une tonne de réponses, je vais en donner une plus correcte (espérons-le) en C++:

#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
cptstubing06

Nous pouvons insérer la chaîne dans une pile et lorsque nous extrayons les mots, ils seront dans l'ordre inverse.

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
sam

Voici l'implémentation Java:

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;
    }
}
1
Pratik Patil

Stocke chaque mot sous forme de chaîne dans un tableau puis imprime de la fin

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
Maneesh

Imprimer des mots dans l'ordre inverse d'une instruction donnée en utilisant 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
Nirbhay Singh

Ce programme rapide fonctionne..pas vérifier les cas de coin cependant. 

#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");
}
1
sathish

Une façon de faire est d’analyser chaque mot de notre chaîne d’entrée et de le placer dans une pile LIFO. 

Une fois la chaîne entière traitée, nous extrayons chaque mot de la pile un par un et nous l'ajoutons à un objet de la classe StringBuffer, qui contient enfin la chaîne d'entrée inversée.

Ceci est une solution possible en Java en utilisant StringTokenizer et la classe Stack. Nous devons importer Java.util.Stack.

public String revString(String input)
{
   StringTokenizer words=new StringTokenizer(input); //Split the string into words
   Stack<String> stack= new Stack<String>();
   while(words.hasMoreTokens())
   {
      stack.Push(words.nextElement().toString()); // Push each Word of the string onto stack. 
   }
   StringBuilder revString=new StringBuilder();
   while(!stack.empty())
   {
       revString.append(stack.pop()+" ");// pop the top item and append it to revString 
   }
   return revString.toString();
}
0
Glad Born

Cela peut être fait plus simplement en utilisant sscanf:

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
user648992
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ReverseString
{
    class Program
    {
        static void Main(string[] args)
        {
            string StringReverse = "";
            int StringLength;
            do
            {
                Console.WriteLine("Enter the String : ");
                string InputString = Console.ReadLine();

                Console.WriteLine("Enter the length : ");
                int InputLength = Convert.ToInt32(Console.ReadLine());

                int NewLength = InputLength;
                InputLength = InputLength - 1;
                int LengthString = InputString.Length;
                int l = LengthString - NewLength;
                StringReverse = "";

                while (InputLength >= 0)
                {
                    StringReverse = StringReverse + InputString[InputLength];
                    InputLength--;
                }

                String substr = InputString.Substring(NewLength, l);

                Console.WriteLine("Reverse  String  Is  {0}", StringReverse + substr);

                Console.WriteLine("\tDo you Want to CONTINUE?\n\t1.YES\n\t2.NO");
                StringLength = Convert.ToInt32(Console.ReadLine());
            } 
            while (StringLength == 1);
        }
    }
}
0
Mayur Narula

Voici l'algorithme:

  1. Exploser la chaîne avec un espace et faire un tableau de mots.
  2. Inverser le tableau.
  3. Implode le tableau par espace.
0
Majid.r

En c, voici comment vous pouvez le faire, O(N) et en utilisant seulement O(1) structures de données (c'est-à-dire un caractère).

#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
Alex Brown
public class reversewords {

public static void main(String args[])

{

String s="my name is nimit goyal";

    char a[]=s.toCharArray();
    int x=s.length();
    int count=0;
    for(int i=s.length()-1 ;i>-1;i--)
    { 
        if(a[i]==' ' ||i==0)
        { //System.out.print("hello");
            if(i==0)
            {System.out.print(" ");}
            for(int k=i;k<x;k++)
            {
                System.out.print(a[k]);
                count++;
            }
            x=i;

        }count++;

    }
    System.out.println("");
    System.out.println("total run =="+count);
}

}

sortie: goyal nimit est mon nom

course totale == 46

0
NImit

Le moyen le plus simple de le faire ..

          string inputStr = "My name is X Y Z";
          string outputStr = string.Empty;
          List<string> templist1 = new List<string>();
          templist1 = inputStr.Split(' ').ToList();
           for (int i = templist1.Count- 1 ; i >= 0; i--)
          {
              if (outputStr != string.Empty)
              {
                  outputStr = outputStr + " " + templist1[i];
              }
              else
              {
                  outputStr = templist1[i];
              }
          }

           Console.WriteLine("Reverse of a String is", outputStr);

        Output:
        Z Y X is name My
0
Sneha Rathi
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
Gopalakrishnan SA

Voici comment le faire dans Excel comme UDF et dans VBA:

Public Function ReverseMe(textToReverse As String, _
          Optional delim As String = " ") As String

    Dim test    As String
    Dim arr     As Variant
    Dim arr2    As Variant
    Dim arrPart As Variant
    Dim cnt     As Long

    arr = Split(textToReverse, ".")
    ReDim arr2(UBound(arr))

    For Each arrPart In arr
        arr2(cnt) = StrReverse(arrPart)
        cnt = cnt + 1
    Next arrPart

    ReverseMe = StrReverse(Join(arr2, "."))

End Function

Public Sub TestMe()

    Debug.Print ReverseMe("veso.dosev.diri.rid", ".")
    Debug.Print ReverseMe("VBA is the best language")

End Sub
0
Vityata

Je sais qu'il y a plusieurs bonnes réponses. Voici celui en C que je suis arrivé avec . Ceci est une implémentation de la réponse exceptée. La complexité temporelle est de O(n) et aucune chaîne supplémentaire n'est utilisée.

#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;
}
0
cTapan

En fait, la première réponse:

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

ne fonctionne pas car il annule dans la seconde moitié de la boucle le travail effectué au cours de la première moitié. Donc, je <mots.longueur/2 fonctionnerait, mais voici un exemple plus clair:

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--;
}

Note: Je ne connais pas bien la syntaxe PHP, et j'ai deviné la syntaxe incrémenter et décrémenter car elle semble être similaire à Perl.

0
S K
string = "hello world";
strrev = ""
list = [];
def splitstring(string):
    j = 0;
    for i in range(0,len(string)):
        if(string[i] == " "):
           list.append(string[j:i]);
           j = i+1;
        Elif (i+1 == len(string)):
            list.append(string[j:i+1]);

splitstring(string);
for i in list:
    for j in range(len(i)-1,-1,-1):
        strrev += i[j];
    if (i != list[-1]):
        strrev+= " ";
print(list);

print(":%s:" %(strrev));
0
jsk

En java

package Test;

public class test2 {

    public static void main(String[] args){

        String str = "my name is fawad X Y Z";

        String strf = "";
        String strfinal="";

        if (str != ""){

        for (int i=0 ; i<=str.length()-1; i++){

            strf += str.charAt(str.length() - (i+1));

        }
        System.out.println(strf);
        }
        else System.out.println("String is Null");

            if (strf != ""){
                String[] temp = strf.split(" ");    

                String temp1 = "";

                System.out.println(temp.length);

                for (int j=0; j<=temp.length-1; j++){

                    temp1 = temp[j];

                    if(temp1.length()>1){

                    for (int k=0; k<=temp1.length()-1; k++){

                        strfinal += temp1.charAt(temp1.length()-(1+k));

                    }
                    strfinal += " ";
                    }
                    else strfinal += temp1 + " ";

                }
                System.out.println(strfinal);

            }
            else System.out.println("String Final is Null");
        }
    }

Sortie:

Z Y X dawaf si eman ym

Z Y X fawad is name my 
0
Fawad Ali Khan
public static void main(String args[]) {
    String str = "My name is X Y Z"; // out put "Z Y X is name My"

    // split
    String[] arr = str.split(" ");
    // reverse Word
    String reverse = "";
    for (int i = arr.length - 1; i >= 0; i--) {
        if(i!=0){
            reverse += arr[i]+" ";
        }else{
            reverse += arr[i];
        }
    }

    System.out.println(reverse);

}
0
Manish Singla

Cette question est posée dans l'interview de Paytm pour le poste Java. Je viens avec la solution suivante.

class ReverseStringWord{
public static void main(String[] args) {
    String s="My name is X Y Z";
    StringBuilder result=new StringBuilder();
    StringBuilder str=new StringBuilder();
    for(int i=0;i<s.length();i++){
        if(s.charAt(i)==' '){
            result.insert(0,str+" ");
            str.setLength(0);
        }
        else{
            str.append(s.charAt(i));
            if(i==s.length()-1){
                result.insert(0,str+" ");
            }
        }
    }
    System.out.println(result);
}}
0
imsaiful

En Java en utilisant une chaîne supplémentaire (avec 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();
}

En Java sur place:

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
Justin
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
Jon Polaski

Meilleure version
Consultez mon blog http://bamaracoulibaly.blogspot.co.uk/2012/04/19-reverse-order-of-words-in-text-fr.html

public string reverseTheWords(string description)
{
    if(!(string.IsNullOrEmpty(description)) && (description.IndexOf(" ") > 1))
    {
        string[] words= description.Split(' ');
        Array.Reverse(words);
        foreach (string Word in words)
        {
            string phrase = string.Join(" ", words);
            Console.WriteLine(phrase);
        }
        return phrase;
    }
    return description;
}
0
Bamara Coulibaly

Voici une implémentation en C qui effectue l'inversion de mot dans Word, et qui a la complexité 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
sorin

Voici comment vous le résolvez dans TCL, quel que soit le nombre d'espaces, de tabulations ou de nouvelles lignes (\ n) de caractères existant dans votre chaîne. C'est une solution de la vie réelle et la façon de penser humaine. Il ne considère pas qu'un seul et unique espace est la marque d'un nouveau mot. 

Et je pense qu'en C/C++ et en Java, vous pouvez le traduire de la même manière.

J'y ai travaillé pendant deux jours avant cette publication, car je n'acceptais pas qu'il existe des fonctions fournies par la bibliothèque du langage qui sont également conçues pour nous, et nous ne les utilisons pas.

<!-- language: lang-php -->
# 1- Reverse the orignial text
set reversed [ string reverse  $all_original_text] 

# 2- split the reversed string $reversed into a list of words then loop over them
set list_of_reversed_words [split $reversed  ]

foreach reversed_words $list_of_reversed_words {

# 3- find the indices of the extremes of each reversed Word in the $reversed

set Word_start [ string first $reversed_words $reversed $Word_start]
set Word_end [ expr $Word_start -1 + [string length $letter] ]

# 4- reverse the current-in-the-loop reversed Word back to its normal state, e.g: 
# if i have a Word "loohcs" then convert it by reversing it to "school"

set original_Word [string reverse [ string range $reversed $Word_start $Word_end] ]

# 5- replace  the reversed Word (loohcs) with the correcte one (school)

set reversed [ string replace $reversed $Word_start $Word_end $original_Word]

# 6- set the start-of-search index to the index 
# directly after the ending of the current Word

set Word_start [expr $Word_end +1]

# 7-continue to the next loop  
}

#print the result
puts "finally: $reversed"
0
superlinux
public class StringReverse {

  public static void main(String[] args) {

    StringReverse sr =new StringReverse();
    String output=sr.reverse("reverse this string");

    String substring="";
    for(int i=0;i<=output.length();i++)
        {
        if(i==output.length()){
            System.out.print(sr.reverse(substring));
            substring="";
        }else if(output.charAt(i)==' ' ){
            System.out.print(sr.reverse(substring+" "));
            substring="";

        }
        if(i<output.length())
        {
        substring+=output.charAt(i);}
        }

}

public String reverse(String str){
    char[] value=str.toCharArray();
    int count=str.length();
    int n = count - 1;
    for (int j = (n-1) >> 1; j >= 0; --j) {
        char temp = value[j];
        value[j] = value[n - j];
        value[n - j] = temp;
    }
    return new String(value);
  }
}
0
Som
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

void reverse(char *data, int len) {
    int counter = 0;
    int end = len - 1;
    char temp;

    for (counter = 0; counter < len / 2; counter++, end--) {
        temp = data[counter];
        data[counter] = data[end];
        data[end] = temp;
    }
}

int main(void) {
    char data[] = "This is a line and needs to be reverse by words!";
    int c = 0;
    int len = strlen(data);
    int wl = 0;
    int start = 0;
    printf("\n    data =  %s", data);
    reverse(data, len);

    for (c = 0; c < len; c++) {
        if (!wl) {
            start = c;
        }
        if (data[c] != ' ') {
            wl++;
        } else {
            reverse(data + start, wl);
            wl = 0;
        }

    }

    printf("\nnow data =  %s", data);
    return EXIT_SUCCESS;
}
0
Pratik

Voici un joli tweak pour ceux qui ont aimé la question ... que se passe-t-il si l'alphabet contenant les mots échangés est inférieur à 16 caractères (16, y compris "espace")? il existe de nombreux exemples pour de tels alphabets: les caractères numériques [01234567890 .- +], les lettres du génome [GATC], l'alphabet hawaïen [aeiouhklmnpv?], le code morse [-.], les notes de musique [ABCDEFG # m], etc. Cela permet d’encoder les caractères sous forme de nœuds (4 bits) et de stocker deux caractères codés dans un caractère de 8 bits.

Il n’est toujours pas trivial d’échanger les mots en une seule boucle avec un curseur déplacé de gauche à droite et l’autre de droite à gauche. Il existe actuellement 4 types de copie de Word: copier un mot du côté gauche vers la droite, du côté droit vers la gauche et les deux copies équivalentes impliquant un chevauchement en lecture/écriture: position X-> X + y et X-> Xy, où y est inférieur à la longueur de X.

L'optimisation de Nice consiste à coder dans la gauche les mots du côté droit de la boucle pendant la première moitié de la boucle (en conservant les valeurs d'origine de gauche), mais sur la seconde moitié, les mots de la gauche peuvent être copiés directement à droite, puis à gauche. les caractères sont réécrits avec leurs valeurs finales ...

Voici le code C, qui prend n'importe quel alphabet comme paramètre:

#define WORDS_DELIMITER  ' '
#define UNMAPPED         0xFF

#define BITS_IN_NIBBLE   4
#define BITS_IN_BYTE     8
#define CHARS_IN_NIBBLE  (1 << BITS_IN_NIBBLE)
#define CHARS_IN_BYTE    (1 << BITS_IN_BYTE)

typedef union flip_char_ {
    unsigned char clear;
    struct {
        unsigned char org:4;
        unsigned char new:4;
    } encoded;
} flip_char_t;

typedef struct codec_ {
    unsigned char nibble2ascii[CHARS_IN_NIBBLE];
    unsigned char ascii2nibble[CHARS_IN_BYTE];
} codec_t;

static int 
codec_init (const unsigned char *alphabet, codec_t *codec)
{
size_t len = strlen(alphabet), i;

if (len > CHARS_IN_NIBBLE) {
    fprintf(stderr, "alphabet is too long!\n");
    return -1;
}
if (strchr(alphabet, WORDS_DELIMITER) == NULL) {
    fprintf(stderr, "missing space in the alphabet\n");
    return -1;
}
strcpy(codec->nibble2ascii, alphabet);
memset(codec->ascii2nibble , UNMAPPED, CHARS_IN_BYTE);
for (i=0; i<len; i++) {
    codec->ascii2nibble[ alphabet[i] ] = i;
}
return 0;
}

static inline int
is_legal_char (const codec_t *codec, const unsigned char ch)
{
return codec->ascii2nibble[ch] != UNMAPPED;
}

static inline unsigned char 
encode_char (const codec_t *codec, unsigned char org, unsigned char new)
{
flip_char_t flip;
flip.encoded.org = codec->ascii2nibble[org];
flip.encoded.new = codec->ascii2nibble[new];
return flip.clear;
} 

static inline unsigned char 
decode_org (const codec_t *codec, unsigned char ch)
{
flip_char_t flip = { .clear = ch };
return codec->nibble2ascii[flip.encoded.org];
}

static inline unsigned char 
decode_new (const codec_t *codec, unsigned char ch)
{
flip_char_t flip = { .clear = ch };
return codec->nibble2ascii[flip.encoded.new];
}

// static void inline
// encode_char (const char *alphabet, const char *
static int 
flip_words (const unsigned char *alphabet, unsigned char *a, size_t len)
{
codec_t codec;     /* mappings of the 16char-alphabet to a nibble */
int r=len-1;       /* right/reader cursor: moves from right to left scanning for words */
int l=0;           /* left/writer cursor: moves from left to right */
int i=0;                      /* Word iterator */
int start_Word=-1,end_Word=-1; /* Word boundaries */
unsigned char org_r=0;        /* original value pointed by the right cursor */
int encode=0, rewrite=0;      /* writing states */

if (codec_init(alphabet, &codec) < 0) return -1;

/* parse the buffer from its end backward */
while (r>=0) {
    if (r>=l && !is_legal_char(&codec, a[r])) {
        fprintf(stderr, "illegal char %c in string\n", a[r]);
        return -1;
    }
    /* read the next charachter looking for Word boundaries */
    org_r = (r<l) ? decode_org(&codec, a[r]) : a[r];
    /* handle Word boundaries */
    if (org_r == WORDS_DELIMITER) {
        /* mark start of Word: next char after space after non-space  */ 
        if (end_Word>0 && start_Word<0) start_Word = r/*skip this space*/+1;
        /* rewrite this space if necessary (2nd half) */
        if (r<l) a[r] = decode_new(&codec,a[r]);
    } else {
        /* mark end of Word: 1st non-space char after spaces */ 
        if (end_Word<0) end_Word = r;
        /* left boundary is a Word boundary as well */
        if (!r) start_Word = r;
    }
    /* Do we have a complete Word to process? */
    if (start_Word<0 || end_Word<0) {
        r--;
        continue;
    }
    /* copy the Word into its new location */
    for(i=start_Word; i<=end_Word; i++, l++) {
        if (i>=l && !is_legal_char(&codec, a[l])) {
            fprintf(stderr, "illegal char %c in string\n", a[l]);
            return -1;
        }
        /* reading phase: value could be encoded or not according to writer's position */
        org_r= (i<l) ? decode_org(&codec, a[i]) : a[i];
        /* overlapping words in shift right: encode and rewrite */
        encode=rewrite=(l>=start_Word && l<=end_Word && i<l);
        /* 1st half - encode both org and new vals */
        encode|=(start_Word-1>l);
        /* 2nd half - decode and rewrite final values */
        rewrite|=(i<l);
        /* writing phase */
        a[l]= encode ? encode_char(&codec, a[l], org_r) : org_r;
        if (rewrite) {
            a[i]=decode_new(&codec, a[i]);
        }
    }
    /* done with this Word! */
    start_Word=end_Word=-1;
    /* write a space delimiter, unless we're at the end */
    if (r) {
        a[l] = l<r ? encode_char(&codec, a[l], WORDS_DELIMITER) : WORDS_DELIMITER;
        l++;
    }
    r--;
}
a[l]=0;
return 0; /* All Done! */
}
0
shauli

J'ai résolu le problème sans utiliser d'espace supplémentaire et utilisé uniquement la chaîne d'origine, mais je n'ai pas pu résoudre le problème dans O (n), le moins que je puisse obtenir est O (n carré), ce qui est pire scénario. 

La façon dont j'ai mis en œuvre -

  1. Inverser la phrase entière, caractère par caractère. 
  2. Plus tard, répétez la phrase en entier, mais cette fois, inversez chaque mot.

ET C’EST POURQUOI J’AI LA PIRE COMPLEXITÉ DE TEMPS COMME O (n m²)

Veuillez trouver le code ci-dessous en Java, en espérant que cela aide quelqu'un. 

class MainClass {
    public static void main(String args[]) {

        String str = "reverse me! also lets check";
        System.out.println("The initial string is  --->> " + str);

        for (int i = 0; i < str.length(); i++) {
            //Keep iterating each letter from one end to another.
            str = str.substring(1, str.length() - i)
                + str.substring(0, 1)
                + str.substring(str.length() - i, str.length());
        }
        System.out.println("The reversed string is ---->> " + str);

        for (int i = 0, j = 0; i < str.length(); i++) {
            if(str.charAt(i) == ' ' || i == (str.length() - 1)) {
                //Just to know the start of each Word
                int k = j;

                //the below if condition is for considering the last Word.
                if(i == (str.length() - 1)) i++;

                while(j < i) {
                    j++;
                    str = str.substring(0, k)
                        //(i-j) is the length of each Word
                        + str.substring(k + 1, (k + 1) + i - j)
                        + str.substring(k, k + 1)
                        + str.substring((k + 1) + i - j, i)
                        + str.substring(i);
                    if(j == i) {
                        //Extra j++ for considering the empty white space
                        j++;
                    }
                }
            }
        }
        System.out.println("The reversed string but not the reversed words is ---->> " + str);

    }
}
0
Sreekhar

Utilisation

char str[50] = {0};
strcpy(str, (char*)"My name is Khan");
reverseWords(str);

Méthode

void reverseWords(char* pString){
    if(NULL ==pString){
        return;
    }
    int nLen     = strlen(pString);
    reverseString(pString,nLen);
    char* start  = pString;
    char* end    = pString;
    nLen         = 0;
    while (*end) {
        if(*end == ' ' ){
            reverseString(start,nLen);
            end++;
            start = end;
            nLen  = 0;
            continue;
        }
        nLen++;
        end++;
    }
    reverseString(start,nLen);
    printf("\n Reversed: %s",pString);

}


void reverseString(char* start,int nLen){
    char* end = start+ nLen-1;
    while(nLen > 0){
        char temp = *start;
        *start    = *end;
        *end      = temp;
        end--;
        start++;
        nLen-=2;
    }
}
0
Madhu S. Kapoor

c # solution pour inverser les mots d'une phrase

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);
    }
}

sortie: personnes le cœur la beauté est dans la beauté Appuyez sur une touche pour continuer . .

0
kishan

Que diriez-vous ...

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

Je suppose que ce n'est pas en ligne tho.

0
JP Alioto

Utilisation de Java:

String newString = "";
String a = "My name is X Y Z";
    int n = a.length();
    int k = n-1;
    int j=0;

    for (int i=n-1; i>=0; i--)
    {
        if (a.charAt(i) == ' ' || i==0)
        {

            j= (i!=0)?i+1:i;

            while(j<=k)
            {
                newString = newString + a.charAt(j);
                j=j+1;
            }
            newString = newString + " ";
            k=i-1;
        }

    }
    System.out.println(newString);

La complexité est O(n) [parcourant tout un tableau] + O(n) [traversant chaque mot à nouveau] = O (n)

0
jags