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

suzy

exercicios de strings

28 mensagens neste tópico

:) alguem tem exercicios de strings?

tou com bastante dificualde nesta area :wallbash:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

1) Dado uma string qualquer introduzida pelo utilizador, mostra-a no ecrã pela ordem inversa.

Ex:

INPUT: "isto e uma string"

OUTPUT: "gnirts amu e otsi"

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

2) substituir um caracter X na string por Y

ex:

input: "curto bues deste forum"

substituir 'u' por '1'

output: "c1rto b1es deste for1m"

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

1) Dado uma string qualquer introduzida pelo utilizador, mostra-a no ecrã pela ordem inversa.

Ex:

INPUT: "isto e uma string"

OUTPUT: "gnirts amu e otsi"

Este é interessante...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

1) Dado uma string qualquer introduzida pelo utilizador, mostra-a no ecrã pela ordem inversa.

Ex:

INPUT: "isto e uma string"

OUTPUT: "gnirts amu e otsi"

Este é interessante...

Feito em cima do joelho... :)

main()
{
int i,tam;
char input[30], output[30];

printf("\nIntroduza uma string: ");
gets(input);
tam=strlen(input);
for(i=0;i<tam;i++)
         {
           output[i]=input[tam-i];
          }
printf("String de saida: %s",output);
getch();
}

Se tiver alguma coisa mal, digam... :D Não posso testá-la neste PC...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
De aorcdo com uma pqsieusa de uma uinrvesriddae ignlsea, não ipomtra a odrem plea qaul as lrteas de uma plravaa etãso, a úncia csioa iprotmatne é que a piremria e útmlia lrteas etejasm no lgaur crteo.

O rseto pdoe ser uma ttaol csãofnuo que vcoê pdoe anida ler sem gnderas pobrlmaes. Itso é poqrue nós não lmeos cdaa lrtea isladoa, mas a plravaa cmoo um tdoo.

Cosiruo não?

certamente que todos perceberam a mensagem.

um desafio interessante é a partir de um texto normal, devolver outro texto com as letras interiores de cada palavra permutadas de lugar (tal como acontece no texto acima).

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

1) Dado uma string qualquer introduzida pelo utilizador, mostra-a no ecrã pela ordem inversa.

Ex:

INPUT: "isto e uma string"

OUTPUT: "gnirts amu e otsi"

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

int main(){
char inicial[255], final[255];
int i, ii;
printf("Insira uma string: ");
scanf("%s", &inicial);
ii=0;
for(i=(strlen(inicial)-1);i>=0;i--){
	final[ii] = inicial[i];
	ii++;
}
printf("String ao contrario: %s\n", final);
return 0;
}

Acho que aquele ii para adicionar à final não está muito elegante... Sugestões?

2) substituir um caracter X na string por Y

ex:

input: "curto bues deste forum"

substituir 'u' por '1'

output: "c1rto b1es deste for1m"

Uhm, não estou a ver... Dicas?

Vão postando aí mais exercícios, tou com uma fezada que é desta que vou pó C. :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

vou aproveitar um bocado do código do djthyrax, espero que ele nao se importe :x

Aqui esta outra maneira de fazer sem usar um vector auxiliar :)

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

int main(){
char inicial[255],tmp;
int i=0, j;
printf("Insira uma string: ");
scanf("%s", &inicial);
for(j=(strlen(inicial)-1);j>i;i++,j--){
	tmp = inicial[i];
	inicial[i]=inicial[j];
                inicial[j]=tmp;
}
printf("String ao contrario: %s\n", inicial);
return 0;
}

E fazendo uma função rápida para o outro exercicio:

void TrocaCars(char *str, char ch1, char ch2){
        int i=0;
        while(str[i] != '\0'){
                if (str[i] == ch1)
                      str[i] = ch2;
                i++;
        }
        return;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Depois de muito bate papo e esclarecimento de dúvidas com o BadBoy (Parv0 @ #p@p), aqui vai a resolução do 2:

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

void replace(char x, char y, char *z){
int i, len = strlen(z);
for(i=0;i<len;i++){
	if(z[i] == x) z[i]=y;
}
return;
}

int main(){
char inicial[255], trocar, por, final[255], lixo;
printf("Introduza uma string: ");
scanf("%s", final);
lixo = getchar();
strcpy(inicial, final);
printf("Introduza o que quer substituir: ");
scanf("%c", &trocar);
lixo = getchar();
printf("Introduza pelo que quer substituir: ");
scanf("%c", &por);
replace(trocar, por, final);
printf("\nOriginal: %s", inicial);
printf("\nFinal: %s \n", final);
return 0;
}

Tava com problemas à pala do enter, daí o lixo = getchar(); Alguma dica de como resolver isto?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Posso optimizar? Sim, eu sei, sou obcecado.

void replace(char x, char y, char *z){
for(; *z != 0; ++z) if( *z == x ) *z=y;
}

PS - Ninguém pegou na proposta do Rui Carlos porquê?

PS2 - Já agora deixo a minha proposta:

Dada uma string, inverter a ordem das palavras.

Ex:

IN: "uma frase qualquer"

OUT: "qualquer frase uma"

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

PS2 - Já agora deixo a minha proposta:

Dada uma string, inverter a ordem das palavras.

Ex:

IN: "uma frase qualquer"

OUT: "qualquer frase uma"

Dicas?

EDIT: Já tenho isto quase feito. Uma coisinha, como vejo o tamanho de um vector?

Off-topic:

O meu primeiro segmentation fault:

segmentationfaultym4.th.png

<3

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Para veres o tamnho de um vector em bytes:  tamanho = sizeof(vector);

O teu segmentation fault, deve ser porque na funcao strtok estas a usar um caracter " ".

http://www.cppreference.com/stdstring/strtok.html, aqui tens um pequeno resumo da funcao...

define antes uma string como por exemplor char car_delim[]  = " ";

e depois usas  a string no strtok... experimenta..procura...e le...  :)

cumps

mynos

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

void replace(char x, char y, char *z){
	int i, len = strlen(z);
for(i=0;i<len;i++){
	if(z[i] == x) z[i]=y;
}
return;
}

int main(){
char inicial[255], trocar, por, final[255], lixo;
printf("Introduza uma string: ");
scanf("%s", final);
lixo = getchar();
strcpy(inicial, final);
printf("Introduza o que quer substituir: ");
scanf("%c", &trocar);
lixo = getchar();
printf("Introduza pelo que quer substituir: ");
scanf("%c", &por);
replace(trocar, por, final);
printf("\nOriginal: %s", inicial);
printf("\nFinal: %s \n", final);
return 0;
}

bem isto inda da para por a compilar mais rapido ... aqui um bocadinho de optimizaçao de codigo :) :)

ja que tamos dentro do assunto deixo aqui umas dicas, :) quem compila em gcc pode escolher o nivel de optimização, quanto mais baixa for a optimizaçao mais pequeno é  o ficheiro quanto mais rapido for maior é o ficheiro (uma pequena analogia  as Artitecturas RISC e CISC ) ... melhor melhor é de nivel 3 rapido e pequeno ...

mas o utilizador pode fazer estas optimizaçoes, ta a fazer aqui o trabalho do compilador ...

por exemplo com um for aproveitanto aqui o codigo do djthyrax

fica mais rapido depois de compilado de para assembly que é onde vai bater tudo xD desta maneira

void replace(char x, char y, char *z){
int i, len = strlen(z);
for(i=0;i<len;i+=2){
	if(z[i] == x) z[i+1]=y;
                if(z[i] == x) z[i+2]=y;
}
return;
}

desta maneira tamos a aproveitar mais a memoria cache...

baixa os nivel de ciclos de relogio...

ja agora este tipo de optimizaçao chama-se loop unrolling.... entre outras , basta meter no google e tao logo la umas poucas ...

muitos programadores deixam este trabalho para o compilador... na minha opiniao acho que é a lingua portuguesa da programaçao :P, saber escrever um codigo.... ja veio numa revista um excerto de como saber escrever codigos... saber comentalos.... utilizar a identaçao... etc, mas isto pouco afecta a memoria e a rapidez ao contrario que isto é crucial senao vejam....

ja agora existem varios pacotes de benchmarking que permitem avaliar o desempenho SPEC, TPC ...

cumps..

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Para veres o tamnho de um vector em bytes:  tamanho = sizeof(vector);

O teu segmentation fault, deve ser porque na funcao strtok estas a usar um caracter " ".

http://www.cppreference.com/stdstring/strtok.html, aqui tens um pequeno resumo da funcao...

define antes uma string como por exemplor char car_delim[]  = " ";

e depois usas  a string no strtok... experimenta..procura...e le...  :)

cumps

mynos

Já lá pus o sizeof(). Mas mesmo usando isso para o strtok, ele faz segmentation fault:

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

int main(){
char inicial[255], *final;
char space[] = " ";
int i;
printf("Introduza uma string: ");
scanf("%s", inicial);
final = strtok(inicial, space);
printf("Resultado: ");
for(i=(sizeof(final)-1);i>=0;i--) printf("%s", final[i]);
return 0;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

por exemplo com um for aproveitanto aqui o codigo do djthyrax

fica mais rapido depois de compilado de para assembly que é onde vai bater tudo xD desta maneira

void replace(char x, char y, char *z){
int i, len = strlen(z);
for(i=0;i<len;i+=2){
	if(z[i] == x) z[i+1]=y;
                if(z[i] == x) z[i+2]=y;
}
return;
}

desta maneira tamos a aproveitar mais a memoria cache...

baixa os nivel de ciclos de relogio... .

Isso é muito bonito, mas nesse for, se o len for par, na ultima iteração, estás a fazer uma comparação desnecessariamente (o ultimo if)
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Cypher, tens aí um probleminha no ciclo. Tens que comparar e substituir no mesmo índice:

void replace(char x, char y, char *z){
int i, len = strlen(z);
for(i=0;i<len;i+=2){
	if(z[i] == x) z[i]=y;
                if(z[i+1] == x) z[i+1]=y;
}
return;
}

Já agora, cuidado com o unrolling. Se utilizares mais de 2 unidades, tens que ter a certeza que não ultrapassas o limite da string.

Dicas?

Bem... usando o strtok, guardar os apontadores para as palavras num array e depois apresentá-las do fim para o início; não esquecer de adicionar espaços :D claro que isso é onde vais provavelmente chegar... ::)

Isso é muito bonito, mas nesse for, se o len for par, na ultima iteração, estás a fazer uma comparação desnecessariamente (o ultimo if)

Ainda assim, se a performance for muito essencial, estás a trocar uns quantos jmps por uma comparação a mais. É uma boa troca :D

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

por exemplo com um for aproveitanto aqui o codigo do djthyrax

fica mais rapido depois de compilado de para assembly que é onde vai bater tudo xD desta maneira

void replace(char x, char y, char *z){
int i, len = strlen(z);
for(i=0;i<len;i+=2){
	if(z[i] == x) z[i+1]=y;
                if(z[i] == x) z[i+2]=y;
}
return;
}

desta maneira tamos a aproveitar mais a memoria cache...

baixa os nivel de ciclos de relogio... .

Isso é muito bonito, mas nesse for, se o len for par, na ultima iteração, estás a fazer uma comparação desnecessariamente (o ultimo if)

de qualquer das maneiras quando o compilador passar isto para assembly vai por dessa maneira ... aqui so tas a fazer o trabalho do compilador ...  mas este nao foi um grande exemplo dunfunde um bocado quem está a aprender... vou dar este, este exemplo, de como baixa os niveis de relogio...

for  [i=1;i<=3000;i++ ]
        a[i]=a[i]+b[i]*c; 

;

com optimizaçao ficaria assim

for  [i=1;i<=3000;i+=3]
        a[i]=a[i]+b[i]*c;
        a[i+1]=a[i+1]+b[i+1]*c;
        a[i+2]=a[i+2]+b[i+2]*c; 

;

ou seja cconsiste em maximizar o numero de instruções por cada iteraçao de um ciclo.. neste caso à um ganho de optimização de 25 %, tal cmo disse abocado quanto mais elevado escolheres o teu grau quando compilas com o gcc maior fica o ficheiro ... repara se escolheres o maior grau em alguns o compilador, neste casso mudei para 3 instruçoes dentro do  for logo percorre o for 1000 vezes :) em alguns programas poderia chegar ao transformar as 1000 execuçoes em 3 execuçoes tento 1000 instruçoes dentro do for... esta aqui uma ideia basica das arquitectuaras RISC (Reduced Instruction Set Computing), por isso é que dizem que no ultimo nivel de optmimizaçao é mais rapido mas o ficheiro é maior...

outro modo que o ususal dos programadores faz é isto...

a*=b;

c = a;

d =e;

ora para tentar anular a dependecia altera se a ordem das execuções das instruçoes ficaria assim

a*=b;

d =e;

c = a;

neste caso tem uma melhoria seca de 10 %.

Um caso em que tem uma melhoria de 60 % nao é brincadeira é bue ... é  na suspensao do pipeline... a maioria dos programadores faz isto bem mas, não se apercebe ... :)

por exemplo

for  (i=1;i<=3000;i++ )
                   for  (j=1;j<=3000;j++ )
                          a[j ][ i ] =0; 

agora com uma melhoria de 60%  :biggrin:

for  (i=1;i<=3000;i++ )
                   for  (j=1;j<=3000;j++ )
                          a[i ][ j ] =0; 

isto acontece por causa da forma como sao acedidos os elementos de uma matriz e ordem pela  qual estao armazenados em memoria

é crucial para maximizar os acertos na cache... leiam um bocado sobre a pipeline.... :) , nao compete só ao programador programar, tem que saber como é que funciona o sistema interno... ou seja assembly ...

bem existem poucos mais e tambem importantes metodos de optimização por isso quem quizer aprender a programar, porque programar nao é so meter o codigo... à que saber por que ordem por o codigo, etc...

ham e aconselho a que se nao quizerem aprender que vejam pelo menos como é codificar em assembly... em arquitecturas SISC e RISC, porque na versao final do programa ou seja quando chegar à parte de assembly denota-se o melhor codigo e o pior...

ja agora existe software para o linux que analisa os codigos e diz qual é o melhor nivel de optimização a utilizar, por isso se tiverem curiosos sobre este tema ... a arte de bem programar  :P,

google tem la muita coisa....

cumps... 

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Cypher, eu percebi a ideia. :) Agora, digam-me é como uso o strtok porque parece que o estou a usar mal... ::)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Cypher, eu percebi a ideia. :D Agora, digam-me é como uso o strtok porque parece que o estou a usar mal... ::)

Já te mostrei no IRC a página com um exemplo, que até já foi referida aqui no fórum... parece que estás a gozar...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Cypher, eu percebi a ideia. :D Agora, digam-me é como uso o strtok porque parece que o estou a usar mal... ::)

Já te mostrei no IRC a página com um exemplo, que até já foi referida aqui no fórum... parece que estás a gozar...

Tipo, eu já olhei para aquilo mas fiquei na mesma...

EDIT: Acho que já percebi. Imaginemos isto:

char str[] = "lawl lola lolita";
char delims[] = " ";
printf("\n%s", strtok( str, delims ));
printf("\n%s", strtok( str, delims ));

Isto iria devolver:

lawl

lola

?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

int main(void)
{
    char str[] = "lawl lola lolita";
    char *tmp = NULL;
    char delims[] = " ";

    tmp = strtok(str, delims);

    while(tmp != NULL)
    {
        printf("%s ", tmp);   
        tmp = strtok(NULL, delims);
    }

    putchar('\n');

    return 0;
}

Output:

[triton@woot c]# ./tok

lawl lola lolita

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Uhm, só me tava a fazer confusão NULL passado ao strtok.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

djthyrax, o teu código não funciona basicamente porque strtok devolve um apontador, não um valor... Na primeira chamada tens de passar o apontador (que neste caso é o nome da string), mas nas chamadas seguintes basta passares NULL porque o programa sabe onde procurar - posição seguinte à do último token. Mais info aqui.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Dada uma string, inverter a ordem das palavras.

Ex:

IN: "uma frase qualquer"

OUT: "qualquer frase uma"

Depois de muito matar a cabeça (este algoritmo só não funcionou à primeira porque me enganei nos printf's e tava a imprimir %s e não %c :x Se não fosse o Triton, nunca mais me via livro das segmentation faults :D), aqui vai a minha solução para este prob:

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

int main(){
printf("Introduza uma string: ");
char str[255];
fgets(str, 255, stdin);
int i, j, espacofirst, espacolast=(strlen(str)-2);
for(i=(strlen(str)-1);i>=0;i--){
	if(str[i] == ' '){
		espacofirst=i+1;
		for(j=espacofirst;j<=espacolast;j++) printf("%c", str[j]);
		printf(" ");
		espacolast=espacofirst-2;
	}
}
for(i=0;i<=espacolast;i++) printf("%c", str[i]); 
printf("\n");
return 0;
}

[me=djthyrax]is proud of himself and waits for HecKel's insults! :biggrin:[/me]

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora