【问题标题】:Reverse the ordering of words in a string反转字符串中单词的顺序
【发布时间】:2010-11-03 19:05:24
【问题描述】:

我有这个string s1 = "My name is X Y Z",我想颠倒单词的顺序,以便s1 = "Z Y X is name My"

我可以使用一个额外的数组来做到这一点。我仔细考虑过,但是否可以就地完成(不使用额外的数据结构)并且时间复杂度为 O(n)?

【问题讨论】:

  • 附加数组是什么意思?除了您将用来存储“令牌”(即单词)的那个之外,或者除了您作为示例给出的字符串之外..?
  • string.split(' ').reverse().join(' ')
  • ^使用额外的内存
  • 正如 KodeSeeker 所说,zzzzBov 解决方案创建了几个中间缓冲区。此外,如果您选择的平台使用“不可变”字符串(如 .NET),那么您肯定也在创造额外的空间,这在采访中值得一提。

标签: algorithm data-structures string


【解决方案1】:

反转整个字符串,然后反转每个单词的字母。

第一次传递后,字符串将是

s1 = "Z Y X si eman yM"

第二遍之后就是

s1 = "Z Y X is name My"

【讨论】:

  • “name”,例如,在他的例子中没有颠倒。
  • 这就是为什么你要做第二遍来反转每个单词的字母。
  • @Miky,不,它是 O(n)。反转整个字符串在 O(n) 中很容易完成,反转字符串中的每个单词也很容易在 O(n) 中完成。 O(n)+O(n) = O(n)。
  • 请记住,对于任何涉及国际化的实际应用,反转字符串都是一场噩梦,而不仅仅是反转字符数组
  • 我想在Java中没有办法解决这个问题,因为Java中的String是不可变的。我说的对吗?
【解决方案2】:

反转字符串,然后在第二遍中反转每个单词...

在 c# 中,完全就地,无需额外的数组:

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

【讨论】:

  • 你认为这是一个 O(n) 操作吗?当我们在那个 for 循环中调用 ReverseString 时,我认为它不会在 O(n) 时间内发生。
  • @Pritam:ReverseString 不是每次都在 for 循环中运行。对字符串进行一次完整的反向遍历(第一次遍历),然后 for 循环找到划分单词边界的空格(另一次遍历)。在内部(重要的是,不是在每个索引处)调用的 ReverseString 是 O(m),其中 m 是单词的长度。它被称为每一个字。所有 O(m) 字长操作的总和等于 O(n)。因此,该算法是最坏情况 3 * O(n),仍然是 O(n)。如果在每个索引处都调用 ReverseString,我认为你是正确的......
  • 单词中连续的空格怎么办?
【解决方案3】:
Not exactly in place, but anyway: Python:

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

【讨论】:

  • 此版本将用单个空格替换多个空格、制表符和换行符。
  • 不@Shadow,这不是一个很好的答案。问题是关于解决问题的算法(注意使用的数据结构和复杂性顺序),而不是高级语言的实现。 (你的也不是——尽管两者都是“正确的”)
【解决方案4】:

在 Smalltalk 中:

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

我知道没有人关心 Smalltalk,但它对我来说太棒了。

【讨论】:

    【解决方案5】:

    如果没有至少一些额外的数据结构,您就无法进行反转。我认为在交换字母时,最小的结构将是单个字符作为缓冲区。它仍然可以被认为是“就地”,但它并不是完全“没有额外的数据结构”。

    下面是实现 Bill the Lizard 所描述的代码:

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

    【讨论】:

    • 如果你使用一些按位或算术技巧,你可以在没有额外字符的情况下做到这一点。例如:a ^= b;乙^=一;一个^= b;将交换 a 和 b。
    • 您可以存储len = strlen(words)。多次使用strlen(words) 会花费更多时间。
    • 可能有点晚了,但在最后一个 for 循环中不应该是 for(int j = wordstart ; j &lt;= (wordend + wordstart) / 2 ; ++j) 而不是减号吗?
    【解决方案6】:

    什么语言? 如果是 PHP,你可以在空间上爆炸,然后将结果传递给 array_reverse。

    如果不是 PHP,你将不得不做一些稍微复杂的事情,比如:

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

    【讨论】:

    • 我认为这行不通,因为对于 i > words.length / 2,单词将被复制回来。例如。 “这是一个测试”变成“测试一个测试”。同样,当 i 为 0 时, words[words.length-i] 将导致异常(越界)。
    • (你可以将循环的条件改为 i
    【解决方案7】:
    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# 代码。

    【讨论】:

      【解决方案8】:
      In Python...
      
      ip = "My name is X Y Z"
      words = ip.split()
      words.reverse()
      print ' '.join(words)
      

      无论如何,cookamunga 使用 python 提供了很好的内联解决方案!

      【讨论】:

      • 如果单词之间有多个空格,解决方法是不正确的。
      【解决方案9】:

      这是假设所有单词都用空格分隔:

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

      【讨论】:

        【解决方案10】:
        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();
        
            }
        }
        

        【讨论】:

          【解决方案11】:

          这并不完美,但它现在对我有用。我不知道它是否有 O(n) 运行时间顺便说一句(仍在研究它^^),但它使用一个额外的数组来完成任务。

          这可能不是您问题的最佳答案,因为我使用 dest 字符串来保存反转版本,而不是替换源字符串中的每个单词。问题是我使用了一个名为 buf 的本地堆栈变量来复制所有单词,我不能复制而是复制到源字符串中,因为如果源字符串是 const char * 类型,这将导致崩溃。

          但这是我第一次尝试写s.th。像这样 :) 好的 blablub。这是代码:

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

          【讨论】:

            【解决方案12】:

            我们可以将字符串插入堆栈中,当我们提取单词时,它们会以相反的顺序排列。

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

            【讨论】:

              【解决方案13】:

              这个快速程序有效..虽然不检查极端情况。

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

              【讨论】:

              • 我是您的答案,所以请尝试解释解决方案,而不仅仅是粘贴代码。代码很好,但只有代码不是。
              • 另外它也没有回答原始问题。我看到那里有大量额外的数据结构/缓冲区......
              【解决方案14】:

              这些答案中的大多数都没有考虑到输入字符串中的前导和/或尾随空格。考虑str=" Hello world" 的情况... 反转整个字符串和反转单个单词的简单算法最终会翻转分隔符导致f(str) == "world Hello "

              OP说“我想颠倒单词的顺序”并没有提到前导和尾随空格也应该翻转!所以,虽然已经有很多答案,但我会[希望]在 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);
              }
              

              【讨论】:

                【解决方案15】:

                我使用堆栈的版本:

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

                【讨论】:

                  【解决方案16】:

                  将每个单词存储为数组中的字符串,然后从末尾打印

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

                  【讨论】:

                    【解决方案17】:

                    在 Python 中,如果不能使用 [::-1] 或 reversed(),这里是简单的方法:

                    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]
                    

                    【讨论】:

                      【解决方案18】:

                      使用 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(' ');
                                  }
                              }
                          }
                      

                      【讨论】:

                        【解决方案19】:

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

                        【讨论】:

                          【解决方案20】:

                          其实第一个答案:

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

                          不起作用,因为它在循环的后半部分撤消了前半部分所做的工作。所以, i

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

                          注意:我对 PHP 语法不熟悉,我猜到了增量器和减量器的语法,因为它似乎类似于 Perl。

                          【讨论】:

                          • 顺便说一句,我的立场是正确的:如果交换了 words.length/2 修改,第一个答案将适用。就目前而言,它将清除数组中的信息。
                          • [你在谈论我的回应] 糟糕,在循环条件下。我只是想澄清一下,我的代码响应不是针对 PHP 的,它或多或少是伪代码。
                          【解决方案21】:

                          怎么样...

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

                          我猜这不是在线的。

                          【讨论】:

                          • 使用了额外的数据结构,这并没有回答他的问题。
                          • 他说他可以使用一个额外的数组......哦,我明白了,他在那里有一个额外的部分。
                          【解决方案22】:

                          在 c 中,你可以这样做,O(N) 并且仅使用 O(1) 数据结构(即 char)。

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

                          【讨论】:

                            【解决方案23】:

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

                            【讨论】:

                              【解决方案24】:
                              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]);
                                  }
                              }
                              

                              }

                              【讨论】:

                                【解决方案25】:

                                在 Java 中使用额外的字符串(使用 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();
                                }
                                

                                在 Java 中就地:

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

                                【讨论】:

                                  【解决方案26】:

                                  这是一个 C 实现,它正在执行单词 reversing inlace,它具有 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;
                                  }
                                  

                                  【讨论】:

                                    【解决方案27】:

                                    c#解决句子中的单词倒序

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

                                    输出: 人的心在于美 按任意键继续。 . .

                                    【讨论】:

                                      【解决方案28】:

                                      更好的版本
                                      查看我的博客http://bamaracoulibaly.blogspot.co.uk/2012/04/19-reverse-order-of-words-in-text.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;
                                      }
                                      

                                      【讨论】:

                                        【解决方案29】:
                                        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);
                                        }
                                        

                                        【讨论】:

                                          【解决方案30】:

                                          我知道有几个正确答案。这是我想出的C语言。 这是例外答案的实现。时间复杂度为 O(n),不使用额外的字符串。

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

                                          【讨论】:

                                          • 有一个错误..当反转字符串 Tejendra is good boy 时输出是 boy is good Tejnedra..
                                          猜你喜欢
                                          • 2011-11-07
                                          • 1970-01-01
                                          • 2021-12-09
                                          • 2023-03-05
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 2015-12-13
                                          相关资源
                                          最近更新 更多