简体   繁体   English

如何反转字符串中的每个单词?

[英]How can I reverse each word in a string?

I'm constrained to not use anything from <string.h> .我被限制不能使用<string.h>任何内容。

I want to reverse each word in the passed string.我想反转传递的字符串中的每个单词。

This is what I have so far:这是我到目前为止:

#include <stdio.h>

char * reversepPrint( char *name )
{
    char *normal = name, *reverse = name;

    while ( *reverse ) ++reverse;

    if ( normal < reverse )
    {
        for ( ; normal < --reverse; ++normal  )
        {
            char c = *normal;
            *normal = *reverse;
            *reverse  = c;
        }
    }

    return name;
}

int main( void ) 
{
    char s[] = "Simon liebt Pizza!";

    printf("%s", reversepPrint(s));

    return 0;
}

My code is reversing the whole string, but I want individual words to be reversed - so the result for this example would be "nomiS tbeil !azziP" .我的代码正在反转整个字符串,但我希望反转单个单词 - 因此此示例的结果将是"nomiS tbeil !azziP"

We need to decompose into two problems.我们需要分解成两个问题。 We already have most of the solution to one problem (reversing a string);我们已经有了一个问题的大部分解决方案(反转字符串); we just need to make it work with a substring.我们只需要让它与子字符串一起工作。 We do this mainly by removing the code that finds the end of the string:我们主要通过删除找到字符串结尾的代码来做到这一点:

/* reverse substring [left, right) in-place */
void reverseSubstring(char *left, char *right)
{
    while (left < --right) {
        char c = *right;
        *right = *left;
        *left++ = c;
    }
}

The other half of the problem is finding the boundaries between words.问题的另一半是找到单词之间的界限。 We can use isspace() to position start and end pointers in the right places, and call our reverseSubstring with them:我们可以使用isspace()将开始和结束指针定位在正确的位置,并用它们调用我们的reverseSubstring

#include <ctype.h>
char *reversepPrint(char *const name)
{
    char *start = name;
    char *end;

    while (*start) {
        while (*start && isspace(*start)) {
            ++start;
        }
        end = start;
        while (*end && !isspace(*end)) {
            ++end;
        }
        reverseSubstring(start, end);
        start = end;
    }

    return name;
}

If you're also prohibited from using <ctype.h> , it isn't hard to write a simple isspace() of your own for this function.如果您也被禁止使用<ctype.h> ,那么为这个函数编写一个简单的isspace()并不难。


Full program完整程序

/* reverse substring [left, right) in-place */
void reverse_substring(char *left, char *right)
{
    while (left < --right) {
        char c = *right;
        *right = *left;
        *left++ = c;
    }
}
    
#include <ctype.h>
/* reverse individual words in string */
/* word boundaries determined by isspace() */
char *reverse_words(char *const name)
{
    for (char *start = name, *end;  *start;  start = end) {
        while (*start && isspace(*start)) { ++start; }
        end = start;
        while (*end && !isspace(*end)) { ++end; }
        reverse_substring(start, end);
    }

    return name;
}

#include <stdio.h>
int main(void)
{
    char s[] = "Simon liebt Pizza!";
    printf("%s", reverse_words(s));
}

Your function reversepPrint reverse a string.您的函数 reversepPrint 反转字符串。

Since you want to reverse by word, you have to parse your string in order to apply your function reversepPrint on each word.由于您想按单词反转,您必须解析您的字符串,以便在每个单词上应用您的函数 reversepPrint。 For doing so, you can use the space character as a delimiter.为此,您可以使用空格字符作为分隔符。

What I would do is the following:我会做的是以下内容:

  1. Create a function that reverse only n char of a string创建一个仅反转字符串的n字符的函数
  2. Use that to reverse words of the original array.使用它来反转原始数组的单词。
  3. Words can be easily identified because are blocks of non-null and non-space chars.由于是非空和非空格字符块,因此可以轻松识别单词。

Something like the following should work (note that I did not test the code) and produces the following output: nomiS tbeil !azziP像下面这样的东西应该可以工作(请注意,我没有测试代码)并产生以下输出: nomiS tbeil !azziP

//this is basically your original function
char * reverse_n( char *name, const int  len )
{
    char *normal = name, *reverse = name+len;

    if ( normal < reverse )
    {
        for ( ; normal < --reverse; ++normal  )
        {
            char c = *normal;
            *normal = *reverse;
            *reverse  = c;
        }
    }

    return name;
}

char * my_reverse( char *nname)
{
    char* name=nname;
    while(*name)
    {
        char* next = name;
        int l = 0;
        //find the next word and its length
        while(*next && *next!=' '){
            next++;
            l++;
        }
        //reverse it
        reverse_n(name, l);
        name=next;
        //skip the space
        if(*name)
            name++;
    }
    return nname;
}

Here's my little effort to the logic without using the string.h这是我在不使用string.h 的情况下对逻辑所做的一点努力

#include <stdio.h>

char * reversepPrint( char *name )
{

    char *normal = name, *reverse = name;

    while ( *reverse ) ++reverse;

    if ( normal < reverse )
    {
        for ( ; normal < --reverse; ++normal  )
        {
            char c = *normal;
            *normal = *reverse;
            *reverse  = c;
        }
    }

    return name;
}

int main( void ) 
{
    char s[] = "Simon liebt Pizza!";
    int i;
    int num_of_spaces = 0;

    int length = 0;

    char *temp = &s;

    while(*temp!='\0'){
        temp++;
    }
    length = temp - s;


    for (i = 0; i<length; i++)
    {

        if (s[i]==' ')
        {
            num_of_spaces++;
        }
    }

    char x[num_of_spaces+1][100];
    i = 0;
    int index = 0,index1 = 0, k = 0;
    for(i = 0; i < length; i++)
    {
        if(s[i]!=' ')
        {
            x[k][index] = s[index1];
            index++;

        }else{

            x[k][index] = '\0';
            index = 0;
            k++;

        }
        index1++;
    }

    i = 0;
    for(i = 0; i<=num_of_spaces; i++)
    {
        printf("%s\n",reversepPrint(x[i]));
    }



    return 0;
}

This is what the code does这就是代码的作用

  • Given any string it will find its length without using strlen给定任何字符串,它会在不使用strlen 的情况下找到它的长度
  • Then, the code will find the total numbers of strings (Spaces between them)然后,代码将找到字符串的总数(它们之间的空格)
  • After that, I am creating a 2d-array with the dimension [strings][100] (each string with length 100)之后,我创建了一个维度为 [strings][100] 的二维数组(每个字符串的长度为 100)
  • Copying the content separately to each string将内容分别复制到每个字符串
  • then looping over the 2d array and calling the method.然后循环遍历二维数组并调用该方法。

Here is a version using some nested loops:这是一个使用一些嵌套循环的版本:

#include <ctype.h>

char * reversepPrint( char *name )
{
    char *s = name;

    while (*s)
    {
        char *t = s;

        /* Find end of non-space character sequence. */
        while (*t && *t == (unsigned char)*t && !isspace(*t))
        {
            t++;
        }
        if (t - s > 1)
        {
            /* Got a non-space character sequence of length > 1. */
            char *e = t;

            /* Reverse the non-space character sequence. */
            do
            {
                char tmp = *s;

                *s++ = *--e;
                *e = tmp;
            } while (s < e);

            /* Start past non-space characters for next iteration. */
            s = t;
        }
        else
        {
            /* Skip space or singleton non-space. */
            s++;
        }
    }

    return name;
}

The variable s is used to advance through the name string in each iteration of the outer while loop.变量s用于在外部while循环的每次迭代中推进name字符串。 The variable t is initialized to s in each iteration of the outer loop and is then advanced past any non-space characters by the inner while (*t && ...) loop.变量t在外循环的每次迭代中都被初始化为s ,然后通过内while (*t && ...)循环前进超过任何非空格字符。 After advancing t past the any non-space characters, the length of the sequence of non-space characters is t - s .在将t推进到任何非空格字符之后,非空格字符序列的长度为t - s (If *s is a space character then this length will be 0.) If this length is greater than 1, it uses the inner do { ... } while loop to reverse the sequence of non-space characters, and then assigns s = t ready for the next iteration of the outer loop. (如果*s是空格字符,那么这个长度将为 0。)如果这个长度大于 1,它使用内部do { ... } while循环来反转非空格字符的序列,然后分配s = t准备好进行外循环的下一次迭代。 Otherwise, *s is either a space character or a singleton non-space character, so s is advanced by one character for the next iteration of the outer loop.否则, *s要么是一个空格字符,要么是一个单独的非空格字符,因此s在外循环的下一次迭代中前进一个字符。

try this logic instead,reverse the individual words of string one by one, for example if the string is "i like programming" after reversing the individual words the string should be "i ekil gnimmargorp".试试这个逻辑,一个一个地反转字符串的单个单词,例如,如果在反转单个单词后字符串是“我喜欢编程”,那么字符串应该是“i ekil gnimmargorp”。

i hope this code snippet helps我希望这个代码片段有帮助

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

// Function to reverse words 
void reverseWords(char* s) 
{ 
    char* begin = s; 

    char* temp = s;  
    while (*temp) { 
        temp++; 
        if (*temp == '\0') { 
            reverse(begin, temp - 1); 
        } 
        else if (*temp == ' ') { 
            reverse(begin, temp - 1); 
            begin = temp + 1; 
        } 
    } 
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM