Optimization of several ifs in something more practical

3

I have a string of alphabetic characters:

char string[] = "aouihuiahsudasduihqmdoiqjnduiamsdoqnwuidamodkjwodkaposdj";

I want to go through it and for each character of it, say how many times it repeats itself in string .

Example:

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

struct Quantidade{
   int qtd;
};

char string = 
"aouihuiahsudasduihqmdoiqjnduiamsdoqnwuidamodkjwodkaposdj";


int main(){
     struct Quantidade vetor[];

     for(i=0; i<strlen(string); i++{
        if(string[i] == 'a'){
            vetor[0].qtd++; 
        } 
        else if(string[i] == 'b'){
            vetor[1].qtd++;
        }
        ...
        else if(string[i] == 'z'){
             vetor[25].qtd++;
        }
     }

   return 0;
 }

Instead of using 26 if s within the code, how can I do it more optimally?

    
asked by anonymous 04.07.2017 / 02:07

2 answers

9

If you can only lower case letters you can do an array with 26 positions and save them according to what you think.

In *string - 'a' is a calculation to find the position of array . You can almost always use math to help simplify algorithms. Then I get the content pointed to by the string pointer that is the character of that step, it will be evaluated according to the ASCII table . So the a is code 97, we do not want this, we want 0, then it's simple, we subtract 97, but to be more readable we subtract the a itself that is 97. And if the character is d , not 100 - 97 gives 3, so the element used will be how much of the array . It's all right.

At the time of use to restore the character has to add 97 again.

So:

#include <stdio.h>

int main() {
    char *string = "aouihuiahsudasduihqmdoiqjnduiamsdoqnwuidamodkjwodkaposdj";
    int quantidade[26] = { 0 }; //inicializa todos elementos zerados
    for (; *string != '
#include <stdio.h>

int main() {
    char *string = "aouihuiahsudasduihqmdoiqjnduiamsdoqnwuidamodkjwodkaposdj";
    int quantidade[26] = { 0 }; //inicializa todos elementos zerados
    for (; *string != '%pre%'; string++) { //termina quando chegar no nulo que é fim de string
        quantidade[*string - 'a']++; //incrementa conteúdo apontado por string - código 'a'
    }
    for (int i = 0; i < 26; i++) {
        printf("%c => %d\n", i + 'a', quantidade[i]); //soma 'a' pra ter o caractere correto
    }
}
'; string++) { //termina quando chegar no nulo que é fim de string quantidade[*string - 'a']++; //incrementa conteúdo apontado por string - código 'a' } for (int i = 0; i < 26; i++) { printf("%c => %d\n", i + 'a', quantidade[i]); //soma 'a' pra ter o caractere correto } }

See running on ideone . And no Coding Ground . Also put it in GitHub for future reference .

If you can have other characters, just increase the number of array positions to fit the whole character and make the character count always using the first possible one.

This does not work if you can have separate character ranges. This algorithm only works for a single range of any size.

If you want to filter the ones with 0 not to print in the list, this is quite easy.

This algorithm does the same thing as the question.

But if you can not even be in the array , there you have to create a more complex structure where you save the character and its sum, only when it reaches at least 1. And there must be an algorithm of search in this array8 that can be linear, logarithmic or constant depending on how much performance assurance and acceptable complexity is required. It's much more complicated to do this.

Please note that I avoided the use of strlen() which is not the most appropriate . Then I walk the pointer ( string++ ) on each character and checks to see if is in the end . If you're having trouble reading this, check the pointer operators .

I almost did with while , I think it was the best in this case.

    
04.07.2017 / 02:38
0
#include <string.h>   // strlen()
//#include <stdio.h>

#define NUM_ALPHA 26
struct Quantidade{
   int qtd;
};

//char string =
//"aouihuiahsudasduihqmdoiqjnduiamsdoqnwuidamodkjwodkaposdj";
char string[] =
"aouihuiahsudasduihqmdoiqjnduiamsdoqnwuidamodkjwodkaposdj";

int main(){
     //struct Quantidade vetor[];
     struct Quantidade vetor[ NUM_ALPHA ];

     for( int i=0; i<NUM_ALPHA; i++ )
     {
         vetor[ i ].qtd = 0;  // initialize
     }

     // for(i=0; i<strlen(string); i++{
     for( size_t i=0; i<strlen(string); i++ )
     {
        //if(string[i] == 'a'){
        //    vetor[0].qtd++;
        //}
        //else if(string[i] == 'b'){
        //    vetor[1].qtd++;
        //}
        //...
        //else if(string[i] == 'z'){
        //     vetor[25].qtd++;
        //}
        vetor[ string[i] - 'a' ].qtd++;
     }

   return 0;
 }
    
05.07.2017 / 00:57