Aluno:
RA:
Curso/Turma: Período: Disciplina:
C.C. - 3ª NOTURNO ESTRUTURA DE DADOS
Professor: Atividade: Data: NOTA:
Dr. Marcelo Augusto Cicogna PRIMEIRA PROVA 14/04/2011
Obs.:
Nota: Todas as questões deverão ser respondidas nas folhas de respostas. Serão consideradas nos critérios de correção a organização e a apresentação do raciocínio na forma de cálculos matemáticos, diagramas e esquemas.
Nas questões desta prova, considere a seguinte declaração de constantes e tipos.
/* Constantes */ #define SIZEIDUNID 6 #define SIZENOME 255 #define SIZELATLNG 9 #define SIZECOORDPRECIS 6 #define SIZEURL 1024 #define SIZENALUNOS 6
/* Definição do tipo TData. */ typedef struct TData
{
int idUnidade; //Código da unidade.
char* nome ; //Nome da unidade.
double latitude ; //Coordenada de latitude da unidade.
double longitude; //Coordenada de longitude da unidade.
char* url ; //URL (endereço eletrônico) da unidade.
float nAlunos ; //Número de alunos da unidade.
} TData;
Questão 01. (1,0 ponto) Considerando a definição do tipo TData apresentada anteriormente, escreva na folha de respostas o código para as seguintes funções. Quando possível, utilize alguma função já implementada.
TData* dataCreate();
void dataSetFields(TData* pData, <continue a lista de parâmetros...>); void dataCopy(TData* pDataDest, TData* pDataSource);
# SOLUÇÃO # TData* dataCreate() {
//Alocação da variável TData.
TData* pData = malloc(sizeof(TData)); if (pData)
{
pData->nome = malloc(SIZENOME*sizeof(char)); pData->url = malloc(SIZEURL *sizeof(char)); }
return (pData); }
//--- void
dataSetFields(TData* pData, int idUnidade, char nome[], double latitude, double longitude, char url[], float nAlunos)
{
if (pData)
{ //Atribuição dos parâmetros recebidos. pData->idUnidade = idUnidade; pData->latitude = latitude ; pData->longitude = longitude; pData->nAlunos = nAlunos ; strcpy(pData->nome, nome ); strcpy(pData->url, url ); } } //--- void
dataCopy(TData* pDataDest, TData* pDataSource) {
if (pDataDest && pDataSource)
dataSetFields(pDataDest, pDataSource->idUnidade, pDataSource->nome , pDataSource->latitude , pDataSource->longitude, pDataSource->url , pDataSource->nAlunos ); } //--- TData* dataClone(TData* pDataSource) {
TData* pDataClone = NULL; if (pDataSource) { pData = dataCreate(); dataCopy(pDataClone, pDataSource); } return (pDataClone); } ♦
Questão 02. (2,0 pontos) Escreva uma função que salve o conteúdo de uma variável TData seguindo o padrão de formatação de um arquivo XML (ilustrado na seqüência). Para isto, considere que o arquivo XML é um arquivo de tipo texto comum e utilize a função fprintf() para escrever informações no arquivo. A função a ser criada tem o seguinte cabeçalho:
void dataSaveToXML(char sFileName[], TData* pData);
O parâmetro sFileName representa o caminho e o nome do arquivo a ser criado, semelhante ao que foi utilizado na função vectorSaveToFile(). O arquivo XML a ser criado tem um exemplo de formatação apresentado a seguir. Os campos que estão em negrito fazem parte da definição do tipo
TData apresentada anteriormente. Os demais nomes são uma padronização para que o arquivo XML possa ser lido pelo Google Earth ou Google Maps. Em outras palavras, o que não está em negrito é deve aparecer explicitamente no uso da funções fprintf(). Um exemplo é apresentado nas dicas
desta questão. Tente escrever o arquivo utilizando o “endentamento” de dois espaços apresentado no exemplo.
<Placemark>
<name>Faculdade Anhanguera de Valinhos</name> <url>"http://www.anhanguera.com"</url> <LookAt> <longitude>-47.001928</longitude> <latitude>-22.963732</latitude> <altitudeMode>relativeToGround</altitudeMode> </LookAt> <Point> <coordinates>-47.001928, -22.963732</coordinates> </Point> </Placemark>
Dica: a) para imprimir um sinal, negativo ou positivo, antes de um número, utilize um “+” na formatação; exemplo fprintf(fout, “%+9.6f”, lat); b) para escrever uma string str num arquivo texto aberto com fopen() e com o nome fout, utilize fprintf(fout, “%s”, str); c) para escrever os tags em XML, considere o seguinte exemplo como guia: fprintf(fout, “<name>%s</name>\n”, pData->nome); controle o “endentamento” inserindo o número correto de de espaços em branco antes de <name>.
# SOLUÇÃO # void
dataSaveToXML(char sfilename[], TData* pData); /**
Função para ler o conteúdo de um vetor num arquivo texto (ASCII). @param sFileName variável contendo o caminho e o nome do arquivo. @param pData ponteiro para variável TData a ser salva de um arquivo XML. @return (0) caso haja sucesso na leitura, um valor diferente de (0) indicará falha na leitura do arquivo.
@version 1.01
@author Marcelo Augusto Cicogna */
{
//Abrir arquivo tipo texto para leitura.
FILE* fout = fopen(sFileName, "wt"); if (fout && (pData != NULL) ) {
fprintf(fout, “<Placemark>” );
fprintf(fout, “ <name>%s</name>” , pData->nome); fprintf(fout, “ <url>\”%s\”</url>”, pData->url ); fprintf(fout, “ <LookAt>” );
fprintf(fout, “ <longitude>%+9.6lf</longitude>”, pData->longitude); fprintf(fout, “ <latitude>%+9.6lf</latitude>” , pData->latitude ); fprintf(fout, “ <altitudeMode>relativeToGround</altitudeMode>”); fprintf(fout, “ </LookAt>” );
fprintf(fout, “ <Point>” );
fprintf(fout, “ <coordinates>%+9.6lf, %+9.6lf </coordinates>”, pData->longitude, pData->latitude ); fprintf(fout, “ </Point>” ); fprintf(fout, “</Placemark>”); //Fechar o arquivo. fclose(fout); }
return (fin == NULL); }
Questão 03. (1,0 ponto) Escreva uma função que copie o conteúdo de uma variável do tipo TVector
(pVctSource) para outra variável TVector (pVctDest). Ambas as variáveis são passadas por referência (ponteiros). A função deve verificar o tamanho dos vetores antes de realizar a cópia. Em caso de diferença, utilize a estratégia comentada em aula que não necessita de alocação extra de memória.
void vectorCopy(TVector* pVctDest, TVector* pVctSource); # SOLUÇÃO #
void
vectorCopy(TVector* pVctDest, TVector* pVctSource)
/**
Função para copiar um vetor (pVctA := pVctB).
A cópia ocorre sem alocação de memória, tendo como origem os dados do vetor PVctB com destino em pVct. Caso os vetores tenham tamanhos (size) diferentes, a cópia ocorre para um número de elementos igual ao menor tamanho.
@param pVctA ponteiro para uma variável TVector de destino da cópia. @param pVctB ponteiro para uma variável TVector de origem da cópia. @version 1.01
@author Marcelo Augusto Cicogna */
{
if ( pVctDest && pVctSource &&
(pVctDest ->size * pVctSource->size > 0) ) {
//Size para o processo de cópia (A := B).
int sizeAux = (pVctDest->size < pVctSource ->size)? pVctDest->size : pVctSource->size; //Copiar valores para o novo vetor.
int i = 0;
for(i=0; i<sizeAux; i++) { pVctDest->vet[i] = pVctSource->vet[i]; } } } ♦
Questão 04. (1,0 ponto) Considere a implementação da função vectorClone() conforme código apresentado a seguir.
TVector
vectorClone(TVector vct) {
//Valor de retorno.
TVector vctClone = vectorCreate(vct.size); //Realizar cópia de valores.
if (vct.size > 0) {
int i = 0;
for(i=0; i<vct.size; i++) { vctClone.vet[i] = vct.vet[i]; } } return (vctClone); }
Pede-se: Altere a função vectorClone() para utilizar a função vectorCopy() implementada na
# SOLUÇÃO #
TVector
vectorClone(TVector vct) {
//Valor de retorno.
TVector vctClone = vectorCreate(vct.size); //Realizar cópia de valores.
if (vct.size > 0) { vectorCopy(&vctClone, &vct); } return (vctClone); } ♦
Questão 05. (1,0 ponto) Escreva uma função que concatene (emende) duas variáveis TVector. A função deve criar um novo vetor de tamanho igual à soma dos dois vetores passados como parâmetro.
TVector* vectorConcat(TVector* pVctA, TVector* pVctB);
Dica: Utilize a função vectorCreate() na criação do vetor “pVctConcat”.
# SOLUÇÃO # TVector*
vectorConcat(TVector* pVctA, TVector* pVctB)
/**
Função para concatenar dois vetores TVector. A concatenação ocorre sem alocação de memória. @param pVctA ponteiro para uma variável TVector. @param pVctB ponteiro para uma variável TVector. @version 1.00
@author Marcelo Augusto Cicogna */
{
//Valor de retorno.
TVector* pVctConcat = NULL;
if ( pVctA && pVctB && (pVctA->size * pVctB->size > 0) ) {
//Size para o vetor resultante da concatenação.
int sizeAux = pVctA->size + pVctB->size; pVctConcat = vectorCreate(sizeAux); //Copiar valores para o novo vetor.
int i = 0;
//... primeiro o conteúdo do vetor pVctA.
for(i=0; i<pVctA->size; i++) {
pVctConcat->vet[i] = pVctA->vet[i]; }
//... e na sequencia, o conteúdo do vetor pVctB.
for(i=pVctA->size; i<sizeAux; i++) { pVctConcat->vet[i] = pVctB->vet[i-pVctA->size]; } } return(pVctConcat); } ♦♦♦
Questão 06. (1,0 ponto) Escreva uma função que preencha uma variável TVector. Com valores crescentes. A função deve receber o valor inicial e o passo, conforme cabeçalho a seguir.
void vectorFillStep(TVector* pVct, int valIni, int step);
vectorFillStep(pVct, 5, 5);
O resultado deve ser:
[5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
Note que o vetor é preenchido até a posição final.
# SOLUÇÃO # void
vectorFillStep(TVector* pVct, int valIni, int step) /**
Função para preencher um vetor com valores variáveis. @param pVct ponteiro para uma variável TVector. @param valIni valor inicial da faixa de preenchimento.
@param setp valor positivo ou negativo do espaçamento entre valores. @version 1.00
@author Marcelo Augusto Cicogna */
{
if (pVct->size > 0) {
int i = 0; int val = valIni;
for(i=0; i<pVct->size; i++) { pVct->vet[i] = val; val += step; } } } ♦
Questão 07. (2,0 pontos) Seguindo a descrição do “Mundo dos Blocos” realizada no ATPS de Estrutura de
Dados, considere o arquivo de entrada de dados do lado esquerdo do próximo quadro: 5 mover 0 acima 1 mover 3 acima 4 mover 2 acima 4 empilhar 1 acima 4 empilhar 4 topo 2 encontra maior mover 3 acima 4 encontra maior sair 0: 1: 2:2 1 0 3: 4:4 3
Para este arquivo de comandos, determine o arquivo de saída utilizando as indicações apresentadas no lado direito do quadro anterior. Faça na folha de resposta desenhos demonstrando (um para cada comando) a evolução dos blocos.
♦ 0 1 2 3 4 Configuração Inicial 0 1 2 3 4 mover 0 acima 1 0 1 2 3 4 mover 3 acima 4 0 1 2 3 4 mover 2 acima 4 0 1 2 3 4 empilhar 1 acima 4 0 1 2 3 4 empilhar 4 topo 2 1 0 2 3 4 encontra maior 1 0 2 3 4 mover 3 acima 4 encontra maior 1 0 2 3 4 Sair