Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

thinkabout

Quantas vezes uma palavra se repete numa frase.

Recommended Posts

thinkabout

A primeira palavra já a consegui apanhar, agora faltam-me ideias para o algoritmo.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h> // strlen
#define Dim 100
/*
Desenvolva um programa que leia uma frase introduzida pelo utilizador e verifique
quantas vezes a primeira palavra se repete.
O programa não deve distinguir entre letras maiúsculas e minúsculas.
Exemplo: ter ou nao ter
O programa deverá escrever:
A palavra ter repete-se duas vezes
*/
void main()
{
char frase[Dim]; 
char palavra[Dim];

int tamanho,i=0,indicepalavra=0;
printf("Introduza uma frase com menos de %d caracteres \n",Dim);
gets(frase);
tamanho=strlen(frase);
for (i = 0; frase[i] != ' ' ; i++)
{
 palavra[i] = frase[i] ;
 indicepalavra++;
}
palavra[indicepalavra]='\0';
// printf("O tamanho do indice e %d \n" , indicepalavra);
}

Share this post


Link to post
Share on other sites
HappyHippyHippo

bem ...

primeiro deverás fazer o trim, que é exactamente o que fizeste no teu tópico anterior : tirar espaços no início e fim da frase

depois terás de ler a primeira palavra (cuidado com caracteres que não fazem parte da palavra como virgulas, pontos e afins)

depois, podes fazer a pesquisa menos eficiente, porque as outras são bem mais complexas:

## nota : terás sempre de começar após a primeira palavra
## nota : se a frase tiver 10 caracteres e a palavra inicial tiver 3, então é impossível ter a palavra a partir do índice 8 (8+3 = 11)
- para cada caracter da frase a começar após a primeira palavra até ao índice que somado ao tamanho da primeira palavra seja maior que o tamanho da frase
 - se o caracter da frase for igual ao primeiro caracter da primeira palavra
   ## nota que estás a comparar índices diferentes (o da frase e o da palavra)
   - usar um índice auxiliar com o valor do índice do ciclo exterior
   - enquanto o caracter da frase apontado pelo índice exterior + o índice auxiliar for igual ao caracter da palavra apontado pelo índice auxiliar e o índice auxiliar for menor que o tamanho da palavra
      - incrementar o índice auxiliar
   ## se percorreste toda a palavra, isto quer dizer que todos os caracteres são iguais
   ## tens de ter cuidado para o próximo caracter da frase não seja um alfanumérico porque estás a pesquisar palavras completas
   ## exemplo : tens de ter cuidado para a palavra "no" não seja encontrado na palavra "nosso" 
   - se o índice auxiliar for igual ao tamanho da palavra e o caracter da frase não for um caracter alfanumérico (espaço ou pontuação)
      - então encontraste a primeira ocorrência da palavra na frase.

Edited by HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
pmg

O programa não deve distinguir entre letras maiúsculas e minúsculas.

Usa a funcao tolower() (ou toupper()) para cada caracter do input para os converteres todas em minusculas (ou maiusculas).


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
eatg75

@thinkabout podias fazer algo como : partes a frase lida por tokens (usas o charater espaco, e tabs como delimitadores), agares a primeira token e aseguras que tens uma token valida, e vais partindo a frase lida enquanto nao chegar ao fim da frase, para cada token verificas se o comprimento e igual, se for equal comparas as strings e se forem igual mostras mostras para o ecra ao algo do genero. (se estas num ambiente *NIX ve o manual das seguintes funcoes strtok(3), tolower(3), strlen(3) e strcmp(3)).


Victarion seized the dusky woman by the wrist and pulled her to him.

Victarion - She will do it. Go pray to your red god. Light your fire, and tell me what you see.

Moqorro's dark eyes seemed to shine.

Moqorro - I see dragons.

Share this post


Link to post
Share on other sites
thinkabout

@thinkabout podias fazer algo como : partes a frase lida por tokens (usas o charater espaco, e tabs como delimitadores), agares a primeira token e aseguras que tens uma token valida, e vais partindo a frase lida enquanto nao chegar ao fim da frase, para cada token verificas se o comprimento e igual, se for equal comparas as strings e se forem igual mostras mostras para o ecra ao algo do genero. (se estas num ambiente *NIX ve o manual das seguintes funcoes strtok(3), tolower(3), strlen(3) e strcmp(3)).

Também é uma ideia.

Por agora estava a lutar com a ideia do HappyHippyHippo, mas ando um bocado a patinar no algoritmo o tolwer e assim fica para depois quando conseguir pelo menos comparar uma frase perfeita.

Ex: ter ou nao ter

Quando meto a frase , o programa simplesmente fica pasmado.

for (i = indicepalavra ; i < tamanho; i++)
{

if (frase[i] == palavra[0] ) // Palavra ter
{

  i=j;
  while (frase[j] == palavra[d])
  {
   conta++;
   j++;
   d++;
  }

  if (conta == strlen(palavra))
  {
  repete++;
  }

}

}
printf("repetiu-se %d", repete);
}

Share this post


Link to post
Share on other sites
thinkabout

e as inicializações das variáveis ?

Sorry, estava a tentar por a informação de forma compacta e fiz asneira.

int tamanho,i=0,j=0,indicepalavra=0,conta=0,repete=0,d=0;

Segue o código todo


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h> // strlen
#define Dim 100

void main()
{

char frase[Dim];  
char palavra[Dim];

int tamanho,i=0,j=0,indicepalavra=0,conta=0,repete=0,d=0;

printf("Introduza uma frase com menos de %d caracteres \n",Dim);
gets(frase);

tamanho=strlen(frase);

for (i = 0; frase[i] != ' ' ; i++)
{
palavra[i] = frase[i] ;
indicepalavra++;
}

palavra[indicepalavra]='\0';


// printf("O tamanho do indice e %d \n" , indicepalavra);

for (i = indicepalavra ; i < tamanho; i++)
{

if (frase[i] == palavra[0] ) // Palavra ter
{

i=j;

while (frase[j] == palavra[d])
{
conta++;
j++;
d++;
}

if (conta == strlen(palavra))
{
repete++;
}

}



}

printf("repetiu-se %d", repete);

}

Edited by thinkabout

Share this post


Link to post
Share on other sites
HappyHippyHippo
for (i = indicepalavra ; i < tamanho; i++)
{
 if (frase[i] == palavra[0] ) // Palavra ter
 {
   i=j;
   while (frase[j] == palavra[d]) // <--- imagina que alguma vez tenhas entrada no ciclo, d não está a apontar para o início da palavra na segunda vez


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
thinkabout

for (i = indicepalavra ; i < tamanho; i++)
{
 if (frase[i] == palavra[0] ) // Palavra ter
 {
i=j;
while (frase[j] == palavra[d]) // <--- imagina que alguma vez tenhas entrada no ciclo, d não está a apontar para o início da palavra na segunda vez

Já tive isso bem e meti mal :(.

No final do while meti um d=0; , mas o programa continua pasmado.

Share this post


Link to post
Share on other sites
HappyHippyHippo

como está não está, não estás a inicializar a variável em cada início de verificação


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
thinkabout

como está não está, não estás a inicializar a variável em cada início de verificação

Já corrigi e isto continua pasmado, ou então entendi o que escreves-te.

for (i = indicepalavra ; i < tamanho; i++)
{
  conta=0;
  d=0;
if (frase[i] == palavra[0] ) // Palavra ter
{

  i=j;

  while (frase[j] == palavra[d])
  {
   conta++;
   j++;
   d++;
  }



  if (conta == strlen(palavra))
  {
  repete++;
  }

}

}
printf("repetiu-se %d", repete);
}

Share this post


Link to post
Share on other sites
HappyHippyHippo

  i=j; // i = j ??? 

dica : as variáveis "conta" e "d" são desnecessárias

Edited by HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
thinkabout
[/size]
  i=j; // i = j ???

:( estava a "dormir" ...só pode..

- usar um índice auxiliar com o valor do índice do ciclo exterior (troquei-me na sintaxe aqui)

Agora ficou

 [/size]j=i; 

Agora já bomba, conta é mal... vou dormir por hoje amanhã volto a isto.

dica : as variáveis "conta" e "d" são desnecessárias

hummm....não estou a ver como avanço então a posição da letra na palavra, de qualquer forma como está ele começa a comparar bem. mas...

Depois quando entra a primeira vez no while compara o "ter" e depois continua a comparar lixo...(debug), tenho que corrigir isto e pensar nas variáveis e na condição de paragem.

- enquanto o caracter da frase apontado pelo índice exterior + o índice auxiliar for igual ao caracter da palavra apontado pelo índice auxiliar e o índice auxiliar for menor que o tamanho da palavra
- incrementar o índice auxiliar
## se percorreste toda a palavra, isto quer dizer que todos os caracteres são iguais
## tens de ter cuidado para o próximo caracter da frase não seja um alfanumérico porque estás a pesquisar palavras completas
## exemplo : tens de ter cuidado para a palavra "no" não seja encontrado na palavra "nosso"
- se o índice auxiliar for igual ao tamanho da palavra e o caracter da frase não for um caracter alfanumérico (espaço ou pontuação)
- então encontraste a primeira ocorrência da palavra na frase.

Edited by thinkabout

Share this post


Link to post
Share on other sites
thinkabout

Já consegui, mas não estou a ver como me livro do D e do CONTA.

int tamanho,i=0,j=0,indicepalavra=0,conta=0,repete=1,d=0;

for (i = indicepalavra ; i < tamanho; i++)
{
  conta=0;
  d=0;
if (frase[i] == palavra[0] ) // Palavra ter
{

  j=i;

  while (frase[j] == palavra[d] && d < strlen(palavra))
  {
conta++;
j++;
d++;
  }



  if (conta == strlen(palavra))
  {
  repete++;
  }

}

}

if (repete == 1)
{
printf("Nao se repetiu");
}
else
{
if(repete != 1)
printf("repetiu-se %d", repete);
}

  while (frase[j] == palavra[d] && d < strlen(palavra))

O compilador dá-me um warning aqui.

warning C4018: '<' : signed/unsigned mismatch

Edited by thinkabout
GeSHi

Share this post


Link to post
Share on other sites
HappyHippyHippo
for (i = indicepalavra ; i < tamanho - strlen(palavra); i++)
{
 if (frase[i] == palavra[0])
 {
   j=0;
   while (frase[i+j] == palavra[j] && j < strlen(palavra))
     j++;

   if (j == strlen(palavra))
     repete++;
 }
}


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
thinkabout

for (i = indicepalavra ; i < tamanho - strlen(palavra); i++)
{
 if (frase[i] == palavra[0])
 {
j=0;
while (frase[i+j] == palavra[j] && j < strlen(palavra))
  j++;

if (j == strlen(palavra))
  repete++;
 }
}

A variável repete está a ser iniciada a 1

Se fizer com o teu código ele ignora-me o primeiro ter.

ter ou nao ter -> nao se repetiu

ter ou nao ter ter -> repetiu-se 2 vezes

Se for com o meu

ter ou nao ter -> repetiu-se 2 vezes

ter ou nao ter ter - repetiu-se 3 vezes

Edited by thinkabout

Share this post


Link to post
Share on other sites
thinkabout

for (i = indicepalavra ; i <= tamanho - strlen(palavra); i++)

Já bomba.


j=0;
       while (frase[i+j] == palavra[j] && j < strlen(palavra))
         j++;

Smart esta :D

Edited by thinkabout

Share this post


Link to post
Share on other sites
thinkabout

toupper a trabalhar.

char frase[Dim]; 
char palavra[Dim];
char frasetratada[Dim];
tamanho=strlen(frase);
for (i = 0; i < tamanho+1; i++)
{
frasetratada[i]=toupper(frase[i]);
}

Não seria possível fazer isto com strupr / strlwr e dar o resultado a uma nova string ?

Algo como

freasetratada = strlwr(frase);

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.