Wyszukiwanie w tekscie C

0

Chciałem poćwiczyć na szybkości przeszukiwanie tekstu, napisałem program który miał szukać spółgłosek i samogłosek i tworzyć z nich łańcuch znaków ale coś nie śmiga. Fajnie jakby ktoś mógł przejrzeć kod i ew. dać jakieś uwagi.

#include <stdio.h>
#include <stdlib.h>
char *szukaniesam(char *lan);
char *szukaniespol(char *lan);
int main()
{

  char *lan[80];
  char *lansam;
  char *lanspol;
  char a;
  printf("wpisz lancuch\n");
  scanf("%79[^\n]s",lan);
  printf("Wprowadziles lancuch:%s \n",lan);
  do
  {
  printf("wybierz:\na-samogloski\nb-spolgloski\nc-koniec\n");
  a=getchar();
  if(a=='a')
  {
    lansam=szukaniesam(lan);
    printf("Lancuch zlozony z samoglosek:\n%s",lansam);
  }
  else if(a=='b')
  {
    lanspol=szukaniespol(lan);
    printf("Lancuch zlozony z spolglosek:\n%s",lanspol);
  }
  else if(a=='c')
  {
      printf("KONIEC\n");
      break;
  }
  else
  {
      printf("wprowadziles zla litere, mozesz wpisac tylko a lub b lub c\n");
  }
  }while(1);
}


char *szukaniesam(char *lan)
{
char *wsk1=NULL;
int i,j;


for(i=0;i<strlen(lan);i++)
    if(lan[i]=='a'&&lan[i]=='e'&&lan[i]=='i'&&lan[i]=='o'&&lan[i]=='u'&&lan[i]=='y')
{
wsk1=(char*)realloc(wsk1,(i+1)*sizeof(char));
wsk1[j]=lan[i];
j++;
}
wsk1=(char*)realloc(wsk1,(i+1)*sizeof(char));
wsk1[j]='\n';

return wsk1;

}

char *szukaniespol(char *lan)
{
   char *wsk2=NULL;
int i,j;


for(i=0;i<strlen(lan);i++)
    if(lan[i]=='b'&&lan[i]=='c'&&lan[i]=='d'&&lan[i]=='f'&&lan[i]=='g'&&lan[i]=='h'&&lan[i]=='j'&&lan[i]=='k'&&lan[i]=='l'&&lan[i]=='m'&&lan[i]=='n'&&lan[i]=='p'&&lan[i]=='r'&&lan[i]=='s'&&lan[i]=='t'&&lan[i]=='w'&&lan[i]=='x'&&lan[i]=='z')
{
wsk2=(char*)realloc(wsk2,(i+1)*sizeof(char));
wsk2[j]=lan[i];
j++;
}
wsk2=(char*)realloc(wsk2,(i+1)*sizeof(char));
wsk2[j]='\n';

return wsk2;
}
1
 scanf("%79[^\n]s",lan);
  1. masz niewłaścuwy typ danych lan
  2. taki string lepiej wczytać funkcją fgets.
for(i=0;i<strlen(lan);i++)
    if(lan[i]=='a'&&lan[i]=='e'&&lan[i]=='i'&&lan[i]=='o'&&lan[i]=='u'&&lan[i]=='y')
{
wsk1=(char*)realloc(wsk1,(i+1)*sizeof(char));
wsk1[j]=lan[i];
j++;
} 

To jest bardzo nieoptymalne, realokcje częste fragmentują pamięć i bardzo spowalniają algorytm.

Dodatkowo brak jest zwolnienia zaalokowanej pamięci.

1

A może jeszcze warto użyć strchr()? Szczególnie do identyfikowania czy literka jest samo/spół głoską. Albo index().

0

char *szukaniesam(char *lan) nazwa (choć durna) sugeruje jedynie szukanie i zero zarządzania pamięcią, a tworzy nowy napis na stercie!
O wiele lepiej zrobić tak:

const char *findCharFromSet(const char *input, const char *charSet)
{
    while(*input) {
        if (strchr(charSet, *input))
              break;
        ++input;
    }
    if (*input)
        return input;
    return NULL;
}

void strCpyIfInSet(const char *input, char *output, const char *charSet)
{
    while(input && *input) {
         input = findCharFromSet(input, charSet);
         if (input)
              *output++ = *input++;
    }
    *output = 0;
}

void strCpyVowels(const char *input, char *output)
{
     strCpyIfInSet(input, output, "aeiouy");
}

W ten sposób pokrywam więcej możliwości.
A zarządzie pamięcią pozostawić użytkownikowi tych funkcji.
Np:

const char *data = "jakis testowy tekst";
char *result = (char *)malloc((strlen(data)+1)*sizeof(char));
strCpyVowels(data, result);
result = (char *)realloc(result, (1+strlen(result))*sizeof(char));

realloc jest bardzo kosztowny, wiec lepiej rezerwować na zapas, a potem zwolnić nadmiar.

1 użytkowników online, w tym zalogowanych: 0, gości: 1