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)?
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"
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;
}
Not exactly in place, but anyway: Python:
>>> a = "These pretzels are making me thirsty"
>>> " ".join(a.split()[::-1])
'thirsty me making are pretzels These'
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.
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;
}
}
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];
}
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();
}
}
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;
}
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 #.
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);
}
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]
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();
}
}
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);
}
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();
}
}
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;
}
}
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]);
}
}
}
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(' ');
}
}
}
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");
}
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();
}
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;
}
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);
}
}
}
Voici l'algorithme:
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;
}
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
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
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);
}
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
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;
}
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.
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));
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
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);
}
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);
}}
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];
}
}
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]);
}
}
}
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;
}
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;
}
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"
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);
}
}
#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;
}
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! */
}
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 -
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);
}
}
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;
}
}
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 . .
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.
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)