Você está na página 1de 5

Estruturas de Dados

Lista 1: soluções
J. L. Rangel
1. Escreva um programa em C que lê três números inteiros do teclado, e imprime os
três números em ordem crescente.
#include <stdio.h>

int leInt(void) {
int i;
printf(">");
scanf("%d",&i);
return i;
}

void troca(int *i, int *j){


int k=*i;
*i=*j;
*j=k;
}

int main(void) {
int i1, i2, i3;
i1=leInt();
i2=leInt();
i3=leInt();
if (i1>i2)
troca(&i1, &i2);
if (i2>i3) {
troca(&i2, &i3);
if (i1>i2)
troca(&i1, &i2);
}
printf("%d <= %d <= %d\n", i1, i2, i3);
}
4. Escreva uma função com protótipo
int contaletra(char *s);
que calcula o número de letras (maiúsculas e minúsculas) da cadeia s.
/*
letra verifica se c e’uma letra
veja tambem isalpha em <ctype.h>
*/
int letra(char c) {
return ((c>='A') && (c<='Z'))
|| ((c>='a') && (c<='z'));
}
(continua)

Estruturas de Dados J .L. Rangel - 1


int contaletra(char *s) {
int i;
int k=0; /* contador de letras */
int l=strlen(s);
for (i=0; i<l; i++)
if (letra(s[i]))
k++;
return k;
}
Observação: veja na biblioteca <ctype.h> a função isalpha (diz se um caracter é
uma letra) e outras funções semelhantes.
5. Escreva uma função que converte todas as letras de uma cadeia para maiúsculas.
O protótipo pode ser
void converte(char *s);
/* min diz se c e' uma letra minuscula
veja tambem islower em <ctype.h>
*/
int min(char c){
return (c>='a') && (c<='z');
}

/* veja tambem toupper em <ctype.h> */


void converte(char *s) {
int i;
int l=strlen(s);
int delta= 'a'-'A';
for (i=0; i<l; i++)
if (min(s[i]))
s[i]=s[i]-delta;
}
Em vez de
s[i]=s[i]-delta;
em C se pode escrever
s[i]-=delta;
Estas abreviações devem ser usadas com cuidado, para não tornar os programas
obscuros.
6. Escreva uma função que recebe como entrada uma cadeia, e devolve como saída
uma cópia da cadeia. Esta função deve alocar o espaço necessário para a cópia.
O protótipo pode ser
char *copia(char *s);
Solução (usando strcpy):
#include <stdlib.h>
#include <string.h>

char *copia(char *s) {


char *t=(char *)malloc(strlen(s)+1);
return strcpy(t,s);
}
Estruturas de Dados J .L. Rangel - 2
Esta outra solução é simples e elegante, mas não funciona!
char *copia(char *s) {
return s;
}
(Por que?)
7. Idem, convertendo as letras da cópia para maiúsculas.
Basta usar a função converte de (5).
8. Um código extremamente simples substitui cada letra pela letra seguinte,
circularmente (Z é codificado como A). Por exemplo, “Estruturas de Dados” se
transformaria em “Ftusvuvsbt ef Ebept”. Escreva funções para codificar e para
decodificar cadeias segundo este código.
/* ccod codifica um caracter */
char ccod(char c) {
if ((c>='A') && (c<'Z'))
return ++c;
if (c=='Z')
return 'A';
if ((c>='a') && (c<'z'))
return ++c;
if (c=='z')
return 'a';
return c;
}

/* cdec decodifica um caracter */


char cdec(char c) {
if ((c>'A') && (c<='Z'))
return --c;
if (c=='A')
return 'Z';
if ((c>'a') && (c<='z'))
return --c;
if (c=='a')
return 'z';
return c;
}

/* scod codifica a cadeia s, por cima! */


void scod(char *s) {
int i;
for (i=0; s[i]!='\0'; i++)
s[i]=ccod(s[i]);
}

/* sdec decodifica a cadeia s, por cima! */


void sdec(char *s) {
int i;
for (i=0; s[i]!='\0'; i++)
s[i]=cdec(s[i]);
}

Estruturas de Dados J .L. Rangel - 3


9. Escreva um programa que lê uma frase (várias palavras) do teclado, e escreve as
palavras uma por linha. Por exemplo, se a entrada fosse
Estruturas de Dados
a saída seria
Estruturas
de
Dados
Sugestão: O formato %[^\n] (qualquer coisa, exceto \n) pode ser usado por scanf
para ler uma cadeia que contém brancos, até o Enter final. Além disso, há outras
funções de leitura de cadeias, como gets e fgets, em <stdio.h>.
#include <stdio.h>

int main(void) {
int i;
char s[80];
int m; /* m=1 -> mudar de linha no proximo branco */

printf(">");
/* com formato " %[^\n]" scanf le
ate' o Enter do fim da entrada */
scanf(" %[^\n]",s);
printf("[%s]\n",s);

m=0;
for (i=0; s[i]!='\0'; i++)
if (s[i]==' ') {
if (m) {
printf("\n");
m=0;
}
} else {
printf("%c",s[i]);
m=1;
}
printf("\n");
}
• O controle com m é necessário para mudar de linha só uma vez entre as palavras,
mesmo que haja mais de um branco.
• O formato %[……] só permite que sejam lidos os caracteres dentro dos colchetes;
^ quer dizer “não”, de forma que %[^\n] quer dizer “qualquer coisa, até o fim da
linha”.
• Outras funções de <stdio.h> também leem uma linha, como gets, e fgets.
(fgets é preferível, porque sua chamada especifica quantos caracteres podem ser
lidos.)
10. Escreva uma função
int igual(char *s1, char *s2);
para descobrir se as cadeias s1 e s2 são iguais.
Sugestão: comece descobrindo porque a solução abaixo não é aceitável.
Estruturas de Dados J .L. Rangel - 4
/* bobagem! */
int igual(char *s1, char *s2) {
return s1==s2;
}
⇒ A função dada verifica se o endereço das duas cadeias é o mesmo, em vez de
verificar se os caracteres das duas cadeias são em mesmo número e iguais.
Solução recursiva:
int igual(char *s1, char *s2) {
if (s1[0]=='\0')
return (s2[0]=='\0');
if (s2[0]=='\0')
return 0;
return (s1[0]==s2[0]) && igual(++s1,++s2);
}
Solução iterativa (com for)
int igual(char *s1, char *s2) {
int i;
for(i=0; (s1[i]!='\0') && (s2[i]!='\0'); i++)
if (s1[i]!=s2[i])
return 0;
/* aqui um dos dois caracteres e' nulo! */
return s1[i]==s2[i];
}

(abr 00)

Estruturas de Dados J .L. Rangel - 5