6

インタビューでこんな質問をされました

文字の配列全体を逆にするのではなく、文字の配列を独自の場所で逆にすることになっていました。

もしも

  char *ch="krishna is the best";

次に、出力が次のようになるように逆にすることになっていました

   anhsirk si eht tseb

インタビューでコードを書くことができませんでした。これを行うための書き方を誰か教えてもらえますか?

ポインターの助けを借りてそれを行うことはできますか?

インタビュアーがそれを独自の場所に反転するように私に言わなかった場合、配列の文字の別の配列を使用して対処するのは簡単で、反転後に新しい文字列を持つでしょうか?

4

9 に答える 9

7
于 2012-08-29T13:18:03.357 に答える
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は実際には変更可能であると想定しています。これには、示したコードの変更が必要です。

于 2012-08-29T13:23:12.490 に答える
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);
}
于 2012-08-29T13:44:16.090 に答える
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;
}

おそらくそれを行うためのより良い方法があります。これは私の頭の上からです。

于 2012-08-29T14:06:34.437 に答える
1

単語ごとに逆にすることができます。

' '(space)ieまで文字列を読むだけです。この文字列を取得krishnaして反転し、元の文字列を別の文字列まで読み続け' '(space)、文字列を反転し続けます。

于 2012-08-29T13:24:53.800 に答える
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;
    }
于 2012-09-14T05:07:42.700 に答える
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;
}
于 2012-09-14T05:08:02.747 に答える
0

現在、特定のコードはわかりませんが、これが私が行う方法です(元の変数を上書きできたと仮定します)。

1)区切り文字として空白を使用して、文字列を単語の配列に分割します

2) 配列をループし、単語を逆順に並べ替えます

3) 文字列を再構築し、変数に代入します。

于 2012-08-29T13:19:37.563 に答える
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
    }
}
于 2012-08-29T13:24:58.093 に答える