3

我正在练习一些编程问题,并尝试编写流行的“字符串中的反向单词”问题。

我试图用 C 编写我自己的代码。我能够部分正确。也就是说,“hello world”变成了“world olleh”。我想知道这里的错误是什么。我想在某个地方我正在创建一个 1 错误。

尽可能地,我想在不使用库函数的情况下做到这一点。我在这里搜索了这个问题并找到了很多解决方案,但我想知道为什么我的解决方案不起作用。

这是代码:

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

void reverse(char*, int);

int main(int argc, char **argv)
{
    char st[]= "hello world";
    int len = strlen(st);
    int i=0,j=0;

    reverse(st,len-1); // Reverse the entire string. hello world => dlrow olleh

    while(st[j]){ //Loop till end of the string
        if ( *(st+j) == ' ' || *(st+j) == '\0' ) { //if you hit a blank space or the end of the string
            reverse(st+i,j-1); // reverse the string starting at position i till position before the blank space i.e j-1
            i=++j; //new i & j are 1 position to the right of old j
        }
        else {
            j++; //if a chacacter is found, move to next position
        }               
    }       

    printf("%s",st);
    return 0;
}

void reverse(char *s, int n)
{
    char *end = s+n; //end is a pointer to an address which is n addresses from the starting address
    char tmp;
    while (end>s)  //perform swap
    {
        tmp = *end;
        *end = *s;
        *s = tmp;
        end--;
        s++;
    }
}

谢谢!

更新:根据@Daniel Fischer 的回答,这里是正确的实现:http: //ideone.com/TYw1k

4

4 回答 4

3

问题是

while(st[j]){ //Loop till end of the string
    if ( *(st+j) == ' ' || *(st+j) == '\0' )

while条件防止在字符串末尾输入循环,因此最后一个单词不会再次反转。

你可以让它成为一个无限循环,然后添加一个

if (st[j] == '\0') break;

在反转之后,或者在 while 循环离开后反转最后一个单词。

于 2012-07-01T00:35:36.387 回答
3

你确实有一个错误:调用

reverse(st+i,j-1);

应该

reverse(st+i,j-i-1);

您的代码传递j-1的是从字符串开头到最后一个空格位置的长度;它应该是最后一个单词的长度,因此您需要减去第一个字符的索引(即i)。

您也没有颠倒最后一个词(有关详细信息,请参见其他答案)。

于 2012-07-01T00:40:23.810 回答
0

我认为您想反转字符串中的单词,而不是反转整个字符串然后反转单个单词。因此,首先删除反向,然后应用上面建议的更改。

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

void reverse(char*, int);

int main(int argc, char **argv)
{
  char st[]= "hello world";
  int i=0, j=0;

  while(st[j]){ //Loop till end of the string
    if ( st[j] == ' ') { //if you hit a blank space or the end of the string
      reverse(&st[i], j - i - 1); // reverse the string starting at position i till position before the blank space i.e j-1
      i = ++j; //new i & j are 1 position to the right of old j
    }
    else {
      j++; //if a chacacter is found, move to next position
    }               
  }
  reverse(&st[i], j - i - 1);


  printf("%s\n",st);
  return 0;
}

void reverse(char *s, int n)
{
  char *end = s + n; //end is a pointer to an address which is n addresses from the    starting address
  char tmp;

  while (end > s)  //perform swap
  {
    tmp = *end;
    *end = *s;
    *s = tmp;
    end--;
    s++;
  }
}

当输入字符串是 '\0' 或类似 'Hello world' 时要小心。上面的代码没有处理这种情况。想想吧!

于 2012-07-01T01:07:54.277 回答
0

@RBK:您首先取一个字符串,将其反转,然后根据特定单词再次反转它们。我采用了稍微不同的方法来做到这一点。如果需要,我取字符串然后反转,否则我复制相同的单词。

int main(int argc, char*argv[])
{
    char *p,st[]= "hello world";
    char buf[12]={0};
    char fstr[12]={0};
    int i=0,j=0,k=0,l=0;

    for(p=st;*p!='\0';p++){

        //Get the Word
        buf[i++] = *p;

        //Parse the Word    
        if(*p == ' ' || *(p+1) == '\0'){

            buf[i]='\0';
            j=i-1;
            i=0;        //reset counter

            if(k){      //reverse word and copy

                while(j>=i){

                    fstr[l++]=buf[j--];

                }               

                k=0;        

            }
            else{       //copy same word

                while(i<=j){

                    fstr[l++]=buf[i++];                     

                }

                i=0;    //reset counter
                k=1;

            }

        }

    }   

    fstr[l]='\0';
    printf("%s\n",fstr);
    return 0;
}
于 2012-10-10T05:44:46.323 回答