簡體   English   中英

查找字符串中最小和最長的單詞

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

我用了:

keep記錄單詞的開頭在哪里。

position_maxposition_min用於記錄最終字符單詞的位置。

maxmin用於比較每個單詞並找到最長和最小的長度。

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;
}

該程序具有未定義的行為,至少是因為此 while 循環中使用的變量 x

while(x != lenght + 1)

未初始化

size_t x;

另一個問題是初始化變量keep by 1

keep = 1;

例如,這可能導致對於像“A BB”這樣的字符串,如果最初變量x初始化為0 ,則具有最大長度的子字符串將是"A"而不是"BB" ,或者如果字符串從空格字符' '開始像" A" ,那么最大子字符串將是" " ,並在這個 for 循環中使用表達式x = position_max - max

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

再次導致未定義的行為。

此外,您還必須考慮字符串包含相鄰空格的情況。

例如,我將編寫一個單獨的函數,如下面的演示程序所示。

#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 minimal string is "all" at position 10
The maximum string is "money" at position 14

如果你想使用標准的 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 minimal string is "all" at position 10
The maximum string is "money" at position 14

正如其他人已經提到的 - 你有未初始化變量( 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;
}

使用一對指針遍歷字符串。
使用指針存儲最長和最短單詞的開頭。
使用計數器來存儲單詞的長度。 根據需要更新最長和最短。
如果長度重復,這將使用找到的第一個單詞。

#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