Counter of a subsequence of repeated strings in C

Asked

Viewed 417 times

6

Consider a string composed of several subsequences.

for example: cccaaaabbbbxdddddddaaannn.

The smallest subsequence is the letter x, with only one element; the largest subsequence is the letter d, with 9 elements. Make an algorithm to read a string and show which letter occurs in the largest subsequence and its size, as well as the letter that occurs in the smallest subsequence and its size.

Ex.:

  • Input: aaabbbbaa;

  • Output: larger b, size 4; smaller a, size 2.

I managed to get the code to register and show correctly the largest subsequence but in the second if I can’t figure out the correct logic to register and show which least repeated character subsequence.

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

#define n 50

int main()
{
    setlocale(LC_ALL,"portuguese");

    char cmaior, cmenor;
    char v[n];
    int i, temp = 1, maior=temp, menor=temp;

    printf("\nDigite a string: ");
    gets(v);

    for(i = 0;i < (strlen(v)-1); i++)
    {
        if(v[i] == v[i+1])
        {
            temp++;
        }
        else
        {
            temp = 1;
        }

        if ( temp > maior )
        {
            maior = temp;
            cmaior = v[i];
        }

        if ( temp <= menor )
        {
            menor = temp;
            cmenor = v[i];
        }

    }

    printf("\n Maior: %c, tamanho %d; Menor: %c, tamanho %d\n",cmaior,maior, cmenor, menor);

    return 0;
}
  • Did any of the answers solve your question? Do you think you can accept one of them? Check out the [tour] how to do this, if you haven’t already. You would help the community by identifying what was the best solution for you. You can accept only one of them. But you can vote on any question or answer you find useful on the entire site

3 answers

5

The problem is that the menor starts already with a very low number, so it gets complicated. In the same way that initialized the maior with the lowest possible number, you have to initialize the menor with the highest possible number, so is the N. I improved some on the code:

#include <stdio.h>
#include <locale.h>

#define N 51

int main() {
    setlocale(LC_ALL,"portuguese");
    char cmaior, cmenor;
    char v[N];
    int contMaior = 1, contMenor = 1, maior = 1, menor = N;
    printf("\nDigite a string: ");
    scanf("%s", v);
    for (int i = 0; v[i] != '\0'; i++) {
        if (v[i] == v[i + 1]) {
            contMaior++;
            contMenor++;
        } else {
            contMaior = 1;
            contMenor = N;
        }
        if (contMaior > maior) {
            maior = contMaior;
            cmaior = v[i];
        }
        if (contMenor < menor) {
            menor = contMenor;
            cmenor = v[i];
        }
    }
    printf("\n Maior: %c, tamanho %d; Menor: %c, tamanho %d\n", cmaior, maior, cmenor, menor);
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

  • 1

    Cool, thanks for the help! Really the minor boot part with the smallest number was an error. But even so when I test the algorithm it doesn’t give the correct assign. Input: aaabbbbaa Output: Larger: b, size 4; Smaller: a, size 1

  • My biggest doubt is in the smallest subsequence

  • Inform the string aaaaaa, the output will be Maior: a, tamanho 6; Menor: a, tamanho 2. Enter any size 1 string, the output will display memory junk (because cmaior and cmenor are not initialized)

2

Your minor sequence problem is in the loop, if you haven’t modified it as Maniero suggested.

You use:

for(i = 0;i < (strlen(v)-1); i++)

In your input case the word has 9 letters. That way you did you ta going up i < 8, that is, it goes at most until i = 7.

If you want to keep the loop that way, you have to be:

for(i = 0;i < strlen(v); i++)

1


First, note that your code has some warnings:

main.c: In function ‘main’:
main.c:17:5: warning: implicit declaration of function ‘gets’; did you mean ‘fgets’? [-Wimplicit-function-declaration]
     gets(v);
     ^~~~
     fgets
main.c:19:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(i = 0;i < (strlen(v)-1); i++)
                 ^
/tmp/ccWK0gqI.o: In function `main':
main.c:(.text+0x5a): warning: the `gets' function is dangerous and should not be used.

In the condition of the loop for, you do i < (strlen(v)-1), actually should be i < strlen(v) or i <= strlen(v) - 1. You mixed the two possibilities.

With each iteration you apply the check of the smallest string size. This is a logic error. All counts start with 1, this causes your algorithm to incorrectly say that the smallest repetition is 1, even if it doesn’t exist. Take the test:

Digite a string: aaabbbbcccccc

Maior: c, tamanho 6; Menor: b, tamanho 1

Note that the algorithm said that the smallest sequence has size 1, and there is no sequence of size 1 in the string.

You must do these checks only when the sequence comes to an end, which is in the else of the first if.

for (i = 0; i < strlen(v); i++)
{
    if (v[i] == v[i+1])
    {
        temp++;
    }
    else
    {
        if (temp > maior)
        {
            maior = temp;
            cmaior = v[i];
        }

        if (temp < menor)
        {
            menor = temp;
            cmenor = v[i];
        }

        temp = 1;
    }
}

Finally, you must initialize the counter menor with as much value as possible, so you ensure that your logic will update you during the loop (otherwise the condition will always be false when the smallest sequence is greater than 1). The highest possible value is n, then use it to initialize the variable.

Follow the complete code, already with the warnings corrected:

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

#define n 50

int main()
{
    setlocale(LC_ALL,"portuguese");

    char cmaior, cmenor;
    char v[n];
    size_t maior = 1, menor = n, i, temp = 1;

    printf("\nDigite a string: ");
    fgets(v, n, stdin);
    v[strlen(v)-1] = '\0';

    cmaior = v[0];

    for (i = 0; i < strlen(v); i++)
    {
        if (v[i] == v[i+1])
        {
            temp++;
        }
        else
        {
            if (temp > maior)
            {
                maior = temp;
                cmaior = v[i];
            }

            if (temp < menor)
            {
                menor = temp;
                cmenor = v[i];
            }

            temp = 1;
        }
    }

    printf("\nMaior: %c, tamanho %zu; Menor: %c, tamanho %zu\n", cmaior, maior, cmenor, menor);

    return EXIT_SUCCESS;
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.