MC102MN

Introdução a Algoritmos e programação de computadores

Aula IX, processamento de dados com vetores

Vetores já são suficientes para fazermos programas de processamento de dados simples. Digamos que queremos fazer uma mini-planilha pra essa matéria. Ela deve guardar (por enquanto) os RAs dos alunos e suas notas nas três provas. Queremos implementar então as quatro operações seguintes:

  • inserir um aluno
  • remover um aluno
  • atualizar uma nota de um aluno
  • ler as notas e média de um aluno

Podemos realizar todas essas operações com vetores. A primeira consideração que temos que ter ao desenvolver um programa nesse estilo é qual a representação que escolheremos para os nossos dados. A partir da representação os algoritmos saem facilmente. Agora adotaremos a representação a seguir:

  • cada aluno é representado como quatro vetores int ra[NALUNOS], double prova1[NALUNOS], double prova2[NALUNOS], e double prova3[NALUNOS]
  • a princípio NALUNOS é um número grande (100, 200, ou algo assim), mas manteremos um contador n que representa o número de alunos que já temos no sistema.

Inserindo um novo aluno

Podemos inserir um novo aluno com a seguinte função

int novo_aluno(int ra[], double prova1[], double prova2[], double prova3[], int n) {
  int novo_ra;
  double novo_p1, novo_p2, novo_p3;
  scanf("%d %lf %lf %lf", &novo_ra, &novo_p1, &novo_p2, &novo_p3);
  ra[n] = novo_ra;
  prova1[n] = novo_p1;
  prova2[n] = novo_p2;
  prova3[n] = novo_p3;
  return n+1;
}

E essa função é usada na forma

nalunos = novo_aluno(ra, prova1, prova2, prova3, nalunos);

Buscando um aluno por ra

Como vimos na aula passada, podemos buscar o número interno de um aluno dado o seu ra usando o algoritmo de busca linear:

int busca(int vetor[], int n, int elem) {
  int i;
  for (i = 0; i < n; ++i) {
    if (vetor[i] == elem) {
      return i;
    }
  }
  return -1;
}

Para usar isso, fazemos algo como

int aluno = busca(ra, nalunos, 089017);

Agora se quisermos imprimir as notas do aluno, podemos:

printf("%lf %lf %lf \n", prova1[aluno], prova2[aluno], prova3[aluno];

Mudando a nota de um aluno

Para mudar a nota de um aluno, basta escrever no vetor correspondente. Ou seja:

int aluno = busca(ra, nalunos, 089017);
prova1[aluno] = 0.; // Acabei de descobrir que ele pescou

Removendo um aluno do sistema

Para remover um aluno a operação é mais complicada. Vamos fazer uma função:

int remove_aluno(int ras[], int p1[], int p2[], int p3[], int nalunos, int ra) {
  int aluno = busca(ras, nalunos, ra);
  if (aluno == -1) return nalunos;
  ras[aluno] = ras[nalunos-1];
  p1[aluno] = p1[nalunos-1];
  p2[aluno] = p2[nalunos-1];
  p3[aluno] = p3[nalunos-1];
  return nalunos-1;
}

Isso então é usado assim:

nalunos = remove_aluno(ra, prova1, prova2, prova3, nalunos, 089017);

Reparem que em nenhum momento apagamos de fato alguém da lista! O que fizemos foi colocar o último no lugar que estava ocupado pelo aluno que queremos remover e diminuir o número total de alunos no sistema. Os dados dele ainda podem estar lá (estarão se ele for o último aluno), mas desaparecerão assim que inserirmos outro aluno e nunca serão encontrados pela busca (que termina antes de chegar nele com certeza).

E agora?

Agora nós temos um mini modelo de bancos de dados, e podemos fazer várias coisas interessantes. Por exemplo, já vimos um código pra fazer a regressão linear de dois vetores:

void lstsq(double x[], double y[], int n, double res[2]) {
  double a, b, sxy = 0, sx = 0;
  double sy = 0, sx2 = 0, mx = 0, my = 0;
  int i;
  for (i = 0; i < 10; ++i) {
    sx += x[i];
    sy += y[i];
    sx2 += x[i]*x[i];
    sxy += x[i]*y[i];
  }
  mx = sx/10;
  my = sy/10;
  b = (sxy - (sx*sy/10))/(sx2-(sx*sx)/10);
  a = my-b*mx;
  res[0] = a;
  res[1] = b;
}

Com isso podemos calcular a correlação linear entre as notas das duas provas, e ver se a segunda foi realmente mais difícil que a primeira:

double res[2], eps = 0.1;
lstsq(prova1, prova2, nalunos, res);
if (res[1] < -eps) {
  printf("É, a segunda prova foi de fato mais difícil que a primeira.\n");
} else if (res[1] > eps) {
  printf("Que nada, a primeira foi mais fácil.\n");
} else {
  printf("As duas provas foram igualmente difíceis\n");
}

Podemos fazer também várias outras operações com esses dados, inclusive gravá-los em arquivos.

Author: Alexandre Tachard Passos <alexandre.tp@gmail.com>

Date: 2010-09-02 14:06:54 BRT

HTML generated by org-mode 6.21b in emacs 23