Home > Back-end >  Finding the smallest and the longest word in a string
Finding the smallest and the longest word in a string

Time:06-13

I used:

keep for recording where is the begin of the word.

position_max and position_min for recording position of final char's word.

max and min for compare every word and find the length of longest and the smallest.

lenght is the length of entire string.

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

CodePudding user response:

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:

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

CodePudding user response:

The program has undefined behavior at least because the variable x used in this while loop

while(x != lenght   1)

was not initialized

size_t x;

Another problem is the initial initializing of the variable 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

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

#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

CodePudding user response:

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