在自己的位置反转一个字符数组

时间:2012-08-29 13:15:40

标签: c string pointers

我在接受采访时被问到这个问题

我应该在自己的位置反转角色数组,而不是颠倒整个角色阵列。

如果

  char *ch="krishna is the best";

然后我应该以这样的方式反转,输出应该像

   anhsirk si eht tseb

我无法在面试中编写代码。任何人都可以建议我如何写这个。?

可以在指针的帮助下完成吗?

如果面试官没有告诉我将其转移到自己的位置,那么如果使用另一个数组字符数组很容易处理,那么在反转它之后会有新的字符串吗?

9 个答案:

答案 0 :(得分:7)

您的面试官都不能为此编写代码。

char *ch="krishna is the best"; 

您无法更改内存的只读部分中的数据,ch指向只读内存。

<强>更新: - 摘录自N1548(§6.7.9)

  

例8
  声明
  char s[] = "abc", t[3] = "abc";
  定义''plain''char数组对象s和t,其元素用字符串文字初始化   该声明与
相同   char s[] = { 'a', 'b', 'c', '\0' },   t[] = { 'a', 'b', 'c' };
  阵列的内容是可修改的。

另一方面,声明
  char *p = "abc";
  使用类型‘‘pointer to char’’定义p并将其初始化为指向类型为‘‘array of char’’的对象   长度为4,其元素用字符串文字初始化。如果尝试使用p   修改数组的内容,行为未定义

您可以看到应用此类数据类型的交换是危险的。

建议将代码编写为: -

char ch[]="krishna is the best"; 然后在每次遇到空格角色时应用XOR swap

答案 1 :(得分:4)

如果我理解得当,这听起来不太难。伪代码:

let p = ch
while *p != '\0'
  while *p is whitespace
    ++p
  let q = last word character starting from p
  reverse the bytes between p and q
  let p = q + 1

一旦你有指向开始和结束的指针,一个字节范围的反转是微不足道的。只需循环一半的距离,然后交换字节。

当然,正如其他地方所指出的,我假设ch中的缓冲区实际上是可修改的,这需要更改您显示的代码。

答案 2 :(得分:2)

 char *ch="krishna is the best";

不可以,这是一个指向只读字符串文字的指针。让我们想象一下,你的面试官知道C并写下了这个:

char str[]="krishna is the best";

然后你可以这样做:

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

char* str_reverse_word (char* str)
{
  char* begin;
  char* end;
  char* the_end;
  char  tmp;

  while(isspace(*str)) /* remove leading spaces from the string*/
  {
    str++;
  }

  begin = str;
  end = str;


  while(!isspace(*end) && *end != '\0') /* find the end of the sub string */
  {
    end++;
  }
  the_end = end; /* save this location and return it later */
  end--; /* move back 1 step to point at the last valid character */


  while(begin < end)
  {
    tmp = *begin;
    *begin = *end;
    *end = tmp;

    begin++;
    end--;
  }

  return the_end;
}

void str_reverse_sentence (char* str)
{
  do
  {
    str = str_reverse_word(str);
  } while (*str != '\0');
}

int main (void)
{
  char str[]="krishna is the best";
  str_reverse_sentence (str);
  puts(str);
}

答案 3 :(得分:1)

你可以逐字翻转。

只需读取字符串直到' '(space)即。你将得到krishna并反转这个字符串并继续读取原始字符串直到另一个' '(space)并继续反转该字符串。

答案 4 :(得分:1)

字符串是否真的是否必须在适当的位置反转,或者只是输出必须反转?

如果是前者,那你就有问题了。如果声明真的是

char *ch = "krishna is the best";

然后您尝试修改字符串文字,并且尝试修改字符串文字时的行为未定义。如果您正在使用字符串文字存储在只读内存中的平台,则会出现运行时错误。您需要将声明更改为

char ch[] = "krishna is the best";

或分配动态缓冲区并将字符串的内容复制到其中

char *ch = "krishna is the best";
char *buf = malloc(strlen(ch) + 1);
if (buf)
{
  strcpy(buf, ch);
  // reverse the contents of buf
}

为了完成的逆转

如果它只是需要反转的输出,那么存储并不重要,你只需要几个指针来跟踪每个子字符串的开头和结尾。例如:

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

int main(void)
{
  char *ch = "krishna is the best";
  char *start, *end;

  // point to the beginning of the string
  start = ch;

  // find the next space in the string
  end = strchr(start, ' ');

  // while there are more spaces in the string
  while (end != NULL)
  {
    // set up a temporary pointer, starting at the space following the
    // current word
    char *p = end;

    // while aren't at the beginning of the current word, decrement the
    // pointer and print the character it points to
    while (p-- != start)
      putchar(*p);

    putchar(' ');

    // find the next space character, starting at the character
    // following the previous space character.
    start = end + 1;
    end = strchr(start, ' ');
  }

  // We didn't find another space character, meaning we're at the start of
  // the last word in the string.  We find the end by adding the length of the
  // last word to the start pointer.
  end = start + strlen(start);

  // Work our way back to the start of the word, printing
  // each character.
  while (end-- != start)
    putchar(*end);

  putchar('\n');
  fflush(stdout);
  return 0;
}

可能有更好的方法,这只是我的头脑。

答案 5 :(得分:0)

现在不确定具体的代码,但这是我的方式(假设你能够写出原始变量)。

1)使用空格作为分隔符

将字符串拆分为单词数组

2)循环遍历数组并按相反顺序对单词进行排序

3)重建字符串并分配回变量。

答案 6 :(得分:0)

这是使用XOR的就地交换:

void reverseStr(char *string)
{
    char *start = string;
    char *end = string + strlen(string) - 1;

    while (end > start) {
        if (*start != *end)
        {
            *start = *start ^ *end;
            *end   = *start ^ *end;
            *start = *start ^ *end;
        }

        start++;
        end--;
    }
}

这当然假设string在可写内存中,所以不要抱怨它不是。

如果你需要先分开单词,那么给我几分钟时间,我会写一些东西。

编辑:

对于以空格分隔的单词(0x20),以下代码应该有效:

void reverseStr(char *string)
{
    // pointer to start of word
    char *wordStart = string;

    // pointer to end of word
    char *wordEnd = NULL;

    // whether we should stop or not
    char stop = 0;

    while (!stop)
    {
        // find the end of the first word
        wordEnd = strchr(wordStart, ' ');
        if (wordEnd == NULL) 
        {
            // if we didn't a word, then search for the end of the string, then stop after this iteration
            wordEnd = strchr(wordStart, '\0');
            stop = 1; // last word in string
        }

        // in place XOR swap
        char *start = wordStart;
        char *end   = wordEnd - 1; // -1 for the space

        while (end > start) {
            if (*start != *end)
            {
                *start = *start ^ *end;
                *end   = *start ^ *end;
                *start = *start ^ *end;
            }

            start++;
            end--;
        }

        wordStart = wordEnd + 1; // +1 for the space
    }
}

答案 7 :(得分:0)

Here is my working solution ->  
 #include<stdio.h>
    #include<ctype.h>
    #include<string.h>

    char * reverse(char *begin, char *end)
    {
      char temp;
      while (begin < end)
      {
        temp = *begin;
        *begin++ = *end;
        *end-- = temp;
      }
    }

    /*Function to reverse words*/
    char * reverseWords(char *s)
    {
      char *word_begin = s;
      char *temp = s; /* temp is for word boundry */

      while( *temp )
      {
        temp++;
        if (*temp == '\0')
        {
          reverse(word_begin, temp-1);
        }
        else if(*temp == ' ')
        {
          reverse(word_begin, temp-1);
          word_begin = temp+1;
        }
      } /* End of while */
      return s;
    }

    int main(void)
    {
        char str[]="This is the test";
        printf("\nOriginal String is -> %s",str);
        printf("\nReverse Words \t   -> %s",reverseWords(str));
      return 0;
    }

答案 8 :(得分:0)

Here is my working solution ->  
#include<stdio.h>
#include<ctype.h>
#include<string.h>

char * reverse(char *begin, char *end)
{
  char temp;
  while (begin < end)
  {
    temp = *begin;
    *begin++ = *end;
    *end-- = temp;
  }
}

/*Function to reverse words*/
char * reverseWords(char *s)
{
  char *word_begin = s;
  char *temp = s; /* temp is for word boundry */

  while( *temp )
  {
    temp++;
    if (*temp == '\0')
    {
      reverse(word_begin, temp-1);
    }
    else if(*temp == ' ')
    {
      reverse(word_begin, temp-1);
      word_begin = temp+1;
    }
  } /* End of while */
  return s;
}

int main(void)
{
    char str[]="This is the test";
    printf("\nOriginal String is -> %s",str);
    printf("\nReverse Words \t   -> %s",reverseWords(str));
  return 0;
}
相关问题