Program to discover repeated characters in strings and print backwards

Asked

Viewed 9,882 times

1

I need to find out how many and which repeat characters are in a string (after you inform it). And also print this string backwards. I’m having great difficulties. Here is part of the code I’ve made so far, but with several errors.

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

#define TAM 100

main () {       
    char palavra[TAM], c;
    int i = 0, aux = 0, contador = 0;

    printf("Digite uma palavra: \n" );
    while ((c=getchar())!= '\n'){
        palavra[i]=c;
        i++;        
    }

    palavra[i] = '\0';

    i = 0;

    while (palavra[i]!= '\0'){                  
        if(palavra[i]==palavra[i]){
            contador++;
        }                              

        printf ("%c = %d \n", palavra[i], contador);  
        i++;
    }
}   
  • It is obvious that: if(word[i]==word[i]){ will always be true. I believe that it is not this comparison that you wish to make.

  • Would you not want to check whether each character occurs at other srting positions?

  • Regex wouldn’t solve the problem?

  • When you say how many repeated elements is how many letters are repeated? Or how many times each is repeated ? Give some examples to be clearer

  • How often each element repeats. For example, the word arara. The letter a repeats three times and the letter r two times.

  • I edited your question to try to make the description of the problem clearer. Tell me what you thought, whether I got it right or not.

Show 1 more comment

4 answers

2


If what you want is to count how many letters repeat and how many times, we can use an auxiliary array as an occurrence counter to help. Here’s the code:

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

#define TAM 100
#define MAX_CHARS 256

int main() {       
    char palavra[TAM];
    int repeticoes[MAX_CHARS];
    int i, tamanho = 0;

    printf("Digite uma palavra: \n" );
    while (tamanho < TAM - 1 && (c = getchar()) != '\n') {
        palavra[tamanho] = c;
        tamanho++;
    }
    palavra[tamanho] = '\0';

    for (i = 0; i < tamanho; i++) {
        repeticoes[palavra[i]]++;
    }

    for (i = 0; i < MAX_CHARS; i++) {
        if (repeticoes[i] > 0) {
            printf("%c = %d\n", (char) i, repeticoes[i]);
        }
    }

    for (i = tamanho - 1; i >= 0; i--) {
         printf("%c", palavra[i]);
    }
    printf("\n");
}

That array repeticoes is the occurrence counter. The type char occupies one byte, and therefore allows 256 different combinations. So this will be the size of the array and there will be a position in the array for each possible value of char, each representing how many times this value of char appears in the word.

In the first for, the instruction repeticoes[palavra[i]]++; works first with the palavra[i] that will map the word character directly to one of the array positions repeticoes, position that will have its value increased. This loop will traverse the entire typed word (or phrase) and when counting the characters, will mount the occurrence counter.

The second for just scroll through the values of the occurrences counter, showing them on the screen. Positions with zeros are characters that do not exist in the word, which is why they are not shown.

The last for traverse the string palavra back-to-front and print the characters one at a time, then showing the string back-to-front.

Note also that I put one tamanho < TAM - 1 && in the while. The reason for this is to avoid being able to type more characters than it fits in the array palavra. Use only tamanho < TAM is not sufficient because space is still needed for the \0, and therefore is used tamanho < TAM - 1. That’s before the && because the size has to be checked before some more character is read.

  • I just didn’t understand "histogram" in "we can use an auxiliary array as a histogram to help"

  • @Jeffersonquesado The auxiliary array is used to count the frequencies of each letter.

  • This I understood, but the word "histogram" that is me Rcana

  • @Jeffersonquesado Replaces "histogram" with "occurrence counter" to avoid problems.

1

You can use a simple function capable of recording the frequency distribution of each character of a given string into an integer vector (see histogram), for example:

void strhist( const char * str, int hist[ 256 ] )
{
    memset( hist, 0, sizeof(int) * 256 );

    while( *str )
        hist[ *str++ ]++;
}

To display a string inversely, you can use a function containing a loop for able to iterate in the string back to front, printing character by character, see only:

void inverso( const char * str )
{
    int i = 0;

    for( i = strlen(str) - 1; i >= 0; i-- )
        printf("%c", str[i] );

    printf("\n");
}

Putting it all together:

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


#define STR_HISTOGRAM_MAX_TAM   (256)


void strhist( const char * str, int hist[ STR_HISTOGRAM_MAX_TAM ] )
{
    memset( hist, 0, sizeof(int) * STR_HISTOGRAM_MAX_TAM );

    while( *str )
        hist[ *str++ ]++;
}


void exibir_histograma( int hist[STR_HISTOGRAM_MAX_TAM], int min )
{
    int i = 0;
    int j = 0;

    for( i = 0; i < STR_HISTOGRAM_MAX_TAM; i++ )
    {
        if( (isprint(i)) && (hist[i] >= min) )
        {
            printf("[%c]: %d ", i, hist[i] );

            for( j = 0; j < hist[i]; j++ )
                printf("*");

            printf("\n");
        }
    }
}


void inverso( const char * str )
{
    int i = 0;

    for( i = strlen(str) - 1; i >= 0; i-- )
        printf("%c", str[i] );

    printf("\n");
}


int main( int argc, char ** argv )
{
    /* String original */
    char string[] = "Um pequeno jabuti xereta viu dez cegonhas felizes.";

    /* Histogama */
    int h[ STR_HISTOGRAM_MAX_TAM ];

    /* Exibe string original */
    printf("%s\n", string );

    /* Calcula histograma da string  */
    strhist( string, h );

    /* Exibe histograma das amostras com 2 ou mais ocorrencias */
    exibir_histograma( h, 2 );

    /* Exibe string invertida */
    inverso( string );

    return 0;
}

Exit:

Um pequeno jabuti xereta viu dez cegonhas felizes.
[ ]: 7 *******
[a]: 3 ***
[e]: 8 ********
[i]: 3 ***
[n]: 2 **
[o]: 2 **
[s]: 2 **
[t]: 2 **
[u]: 3 ***
[z]: 2 **
.sezilef sahnogec zed uiv aterex itubaj oneuqep mU

0

In the above case he would be taking the amount of times that this character repeats, I think that is not what French K meant, but how many elements repeat example: if we use the word "mathematically" we have 3 elements that repeat the (m) the (a) and the (t) in the above case the counter would return approximately 17, however it should return 3, so I understood the question. I’ll put an example code based on Gabriel Gomes' code but I didn’t test it.

int contador=0;
char encontrados[TAM];
for(int i=0;palavras[i]!='\0';i++){
    for(int j=0;palavras[j]!='\0';j++){
        for(int z=0;i<contador;z++){
            if(plavras[i]==palavras[j] && i!=j && palavras[i]==encontrados[z]){
                break;
            }
        }
        if(palavras[i]==palavras[j] && i!=j){
            contador++;
            break;
        }
    }
}

-1

I believe it can be done so... To each element it compares with each and, finding an equal, increases the counter.

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

#define TAM 100

main () {       
    char palavra[TAM];
    int contador = 0;

    printf("Digite uma palavra: \n" );
    scanf("%s", &palavra)

    for( i =0, palavra[i] != '\0'; i++ ){
        for( j =0, palavra[j] != '\0'; j++ ){
           if(palavra[i] == palavra[j])
             contador++;
         }
     }              

      printf ("%s = %d \n", &palavra, &contador);  
}
  • But the printf ("%s = %d n", &word, &counter) will not write only once, if placed in this form?

  • Actually to write the word would be printf ("%s = %d n", word,&counter)

  • This would be to read a word count the number of repeated. Then show the normal word and the amount of repeated characters

Browser other questions tagged

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