简体   繁体   English

查找字符串中最小和最长的单词

[英]Finding the smallest and the longest word in a string

I used:我用了:

keep for recording where is the begin of the word. keep记录单词的开头在哪里。

position_max and position_min for recording position of final char's word. position_maxposition_min用于记录最终字符单词的位置。

max and min for compare every word and find the length of longest and the smallest. maxmin用于比较每个单词并找到最长和最小的长度。

lenght is the length of entire string. lenght是整个字符串的长度。

#include<limits.h>
#include<stdio.h>
#include<time.h>
#include<math.h>
#include<string.h>
#include<conio.h>
#include<ctype.h>
#include<stdlib.h>
#include<malloc.h>


int main(void)
{
char *stringa = "alex keep all money";
size_t x;
int keep;       
int min;            
int max;        
int position_max;   
int position_min;   
int lenght;     
keep = 1;
max = 0;
min = INT_MAX;
position_max = 0;
lenght = strlen(stringa);
while(x != lenght + 1)
{
    if(isalnum(stringa[x]) != 0)
    {
        keep += 1;
    }
    
    if(isspace(stringa[x]) != 0 || stringa[x] == '\0')
    {
        if(keep > max)
        {
            position_max = x;
            max = keep;
        }
        if(keep < min)
        {
            position_min = x;
            min = keep;
        }
        keep = 0;
    }
    x++;
}
puts("the longest word:");
for(x = position_max - max; x != position_max; x++)
{
    printf("%c",stringa[x]);
}
puts("\n\nthe smallest word:");
for(x = position_min - min; x != position_min; x++)
{
    printf("%c", stringa[x]);
}
return 0;
}

The program has undefined behavior at least because the variable x used in this while loop该程序具有未定义的行为,至少是因为此 while 循环中使用的变量 x

while(x != lenght + 1)

was not initialized未初始化

size_t x;

Another problem is the initial initializing of the variable keep by 1另一个问题是初始化变量keep by 1

keep = 1;

This can results for example that for the string like "A BB" the substring with the maximum length will be "A" instead of "BB" provided that initially the variable x was initialized by 0 Or if the string starts from space character ' ' like " A" then the maximum substring will be " " and using the expression x = position_max - max in this for loop例如,这可能导致对于像“A BB”这样的字符串,如果最初变量x初始化为0 ,则具有最大长度的子字符串将是"A"而不是"BB" ,或者如果字符串从空格字符' '开始像" A" ,那么最大子字符串将是" " ,并在这个 for 循环中使用表达式x = position_max - max

for(x = position_max - max; x != position_max; x++)

again results in undefined behavior.再次导致未定义的行为。

Also you have to take into account situations when a string contains adjacent white spaces.此外,您还必须考虑字符串包含相邻空格的情况。

I would write a separate function for example as shown in the demonstration program below.例如,我将编写一个单独的函数,如下面的演示程序所示。

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

struct SubString
{
    char *position;
    size_t length;
};

struct MinMax
{
    struct SubString min;
    struct SubString max;
};

struct MinMax minmax_string( const char *s, const char *delim )
{
    struct MinMax minmax = 
    { 
        .min = { .position = NULL, .length = 00 }, 
        .max = { .position = NULL, .length = 0 } 
    };

    for ( s += strspn( s, delim ); *s; s += strspn( s, delim )  )
    {
        const char *position = s;
        s += strcspn( s, delim );

        size_t length = s - position;

        if ( minmax.min.position == NULL )
        {
            minmax.min.position = ( char * )position;
            minmax.min.length = length;
            minmax.max.position = ( char * )position;
            minmax.max.length = length;
        }
        else if ( minmax.max.length < length )
        {
            minmax.max.position = ( char * )position;
            minmax.max.length = length;
        }
        else if ( length < minmax.min.length )
        {
            minmax.min.position = ( char * )position;
            minmax.min.length = length;
        }
    }

    return minmax;
}

int main(void) 
{
    const char *s = "alex keep all money";

    struct MinMax minmax = minmax_string( s, " \t" );

    printf( "The minimal string is \"%.*s\" at position %zu\n", 
        ( int )minmax.min.length, minmax.min.position, ( size_t )( minmax.min.position - s ) );
    printf( "The maximum string is \"%.*s\" at position %zu\n", 
        ( int )minmax.max.length, minmax.max.position, ( size_t )( minmax.max.position - s ) );
}

The program output is程序输出为

The minimal string is "all" at position 10
The maximum string is "money" at position 14

If you want to use the standard C function isspace then the function minmax_string can look the following way如果你想使用标准的 C 函数isspace那么函数minmax_string可以如下所示

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

struct SubString
{
    char *position;
    size_t length;
};

struct MinMax
{
    struct SubString min;
    struct SubString max;
};

struct MinMax minmax_string( const char *s )
{
    struct MinMax minmax = 
    { 
        .min = { .position = NULL, .length = 00 }, 
        .max = { .position = NULL, .length = 0 } 
    };

    do
    {
        while ( isspace( ( unsigned char )*s )) ++s;

        if ( *s )
        {
            const char *position = s;

            while ( *s && !isspace( ( unsigned char )*s ) ) ++s;

            size_t length = s - position;

            if ( minmax.min.position == NULL )
            {
                minmax.min.position = ( char * )position;
                minmax.min.length = length;
                minmax.max.position = ( char * )position;
                minmax.max.length = length;
            }
            else if ( minmax.max.length < length )
            {
                minmax.max.position = ( char * )position;
                minmax.max.length = length;
            }
            else if ( length < minmax.min.length )
            {
                minmax.min.position = ( char * )position;
                minmax.min.length = length;
            }
        }
    } while ( *s );
    

    return minmax;
}

int main(void) 
{
    const char *s = "alex keep all money";

    struct MinMax minmax = minmax_string( s );

    printf( "The minimal string is \"%.*s\" at position %zu\n", 
        ( int )minmax.min.length, minmax.min.position, ( size_t )( minmax.min.position - s ) );
    printf( "The maximum string is \"%.*s\" at position %zu\n", 
        ( int )minmax.max.length, minmax.max.position, ( size_t )( minmax.max.position - s ) );
}

The program output is the same as shown above that is程序输出与上图相同,即

The minimal string is "all" at position 10
The maximum string is "money" at position 14

as others already mentioned - you have problems with uninitialized variables ( x , position_min ), also there are couple edge cases missed: when you have spaces at the start/end or multiple consecutive ones, here is fixed version:正如其他人已经提到的 - 你有未初始化变量( xposition_min )的问题,也有几个边缘情况遗漏:当你在开始/结束或多个连续的空格时,这里是固定版本:

int main(void) {
    const char * const stringa = " alex keep   all money ";
    size_t x = 0; // keep declaration and definition in one place, so it is easy to spot mistakes
    unsigned int keep = 0;
    unsigned int min = 0; // initial min/max should be zero to work properly later during printing
    unsigned int max = 0;
    size_t position_max = 0;
    size_t position_min = 0;
    const size_t length = strlen(stringa);
    
    while (x <= length) {
        if (x == length || isspace(stringa[x])) { // first cover end of string case
            if (keep > 0) { // multiple spaces
                if (max == 0 || keep > max) {
                    position_max = x;
                    max = keep;
                }
                if (min == 0 || keep < min) {
                    position_min = x;
                    min = keep;
                }
                keep = 0;
            }
        } else if (isalnum(stringa[x]))
            keep++;
        x++;
    }

    puts("the longest word:");
    for(x = position_max - max; x < position_max; x++) printf("%c", stringa[x]);
    puts("\n\nthe smallest word:");
    for(x = position_min - min; x < position_min; x++) printf("%c", stringa[x]);
    return 0;
}

Iterate through the string using a pair of pointers.使用一对指针遍历字符串。
Use pointers to store the beginning of the longest and shortest words.使用指针存储最长和最短单词的开头。
Use counters to store the lengths of the words.使用计数器来存储单词的长度。 Updating longest and shortest as needed.根据需要更新最长和最短。
In case of duplicate lengths, this will use the first word found.如果长度重复,这将使用找到的第一个单词。

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

int main ( void) {
    char *str = "compare every word, find the length of longest and the smallest";
    char *begin = str;
    char *end = str;
    char *longest = str;
    char *shortest = str;
    int len = 0;
    int longlen = 0;
    int shortlen = INT_MAX;

    printf ( "%s\n", str);
    while ( *begin) {
        while ( ! isalnum ( (unsigned char)*begin)) {
            ++begin; //advance past non-alphanumeric
        }
        end = begin; //assign pointer to section to evaluate
        len = 0;
        while ( isalnum ( (unsigned char)*end)) {
            ++end; //advance past alphanumeric
            ++len; //count characters
        }
        printf ( "\tword '%.*s' length %d\n", len, begin, len);
        if ( len > longlen) { //found longer word
            longlen = len; //store length
            longest = begin; //store pointer
        }
        if ( len && len < shortlen) { //found shorter word
            shortlen = len; //store length
            shortest = begin; //store pointer
        }
        begin = end; //assign pointer to iterate next section
    }

    printf ( "\nlength of longest word '%.*s' is %d\n", longlen, longest, longlen);
    printf ( "length of shortest word '%.*s' is %d\n", shortlen, shortest, shortlen);

    return 1;
}

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

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