Linguagem C: Matrizes, parte 2

Pedrinho tem duas maçãs

e Joãozinho duas matrizes. Coitado do Joãozinho.

Algumas operações entre matrizes

No artigo anterior sobre matrizes, vimos como declarar, preencher in code, via input do usuário e como mostrar na tela. De quebra vimos que passamos matrizes por referência numa função, com a função sãoTomé.

O objetivo deste é realizar operações entre as duas matrizes.

Soma

Certo. Nada difícil com números inteiros, decimais, racionais e todos os outros do círculo maldito, certo?

Conjuntos Numéricos

Círculo maldito, retirado do Brasil Escola.

Nas matrizes, nada de diferente. Apenas devemos tomar um cuidado: “Não se soma matrizes de ordens diferentes”, dizem [NUM PODE FALAR O NOME, CONSIDEREM "PROFESSOR BOLINHA" NO LUGAR DO NOME REAL] e o matematiques (gostei deste site!).

Sabe porquê? Quando você soma matrizes, não “soma matrizes” ao pé da letra, você soma os elementos dentro da matriz com os elementos da outra matriz na mesma posição.

2+4 | 3 + 3 | 4+4

Soma fantasma

2+4 | 3+3 | 4 + ??!!?!??!?!?!

É assim que a vida é. Se não é compatível, não rola. Mesma coisa (nesse caso) na matemática.

Mão na massa

void soma(int m[][10], int n[][10], int o[][10], int linhas, int colunas)
{
  int i,j;

  for(i=0;i<linhas;i++)
  {
      for(j=0;j<colunas;j++)
      {
        o[i][j] = m[i][j] + n[i][j];
      }
  }
}

A função soma trabalha da seguinte forma:

- Preciso das duas matrizes que serão somadas (m e n)

- Preciso da matriz que vai conter o resultado da soma (o) {Opcional}

- Preciso da quantidade de linhas e colunas

Faço 2 for’s (p/ acessar linhas e suas colunas). Indico entre os colchetes a linha e coluna que estou somando e faço a adição.

o[i][j] = m[i][j] + o[i][j]
=
o[linha 1][coluna 1] = m[linha 1][coluna 1] + o[linha 1][coluna 1]
=
o[1][1] = 2 + 3

No trecho acima, está suposto que na matriz M, linha 1 na coluna 1, temos o valor 2. Na matriz O, linha 1 na coluna 1, temos o valor 3.

Somamos os dois valores e colocamos na Matriz o, linha 1, coluna 1.

Rode o código todo se quiser uma visão ainda melhor:

#include <stdio.h>
#include <stdlib.h>

void preencher(int m[][10],int linhas, int colunas);
void mostrar(int m[][10],int linhas, int colunas);
void soma(int m[][10], int n[][10], int o[][10], int i, int j);

int main(int argc, char *argv[])
{
  int a[10][10], b[10][10], c[10][10];

  printf("Matriz A:\n");
  preencher(a,2,2);
  printf("Matriz B:\n");
  preencher(b,2,2);
  printf("Somando...\n");
  soma(a,b,c,2,2);

  mostrar(c,2,2);

  system("PAUSE");
  return 0;
}

void preencher(int m[][10], int linhas, int colunas)
{
  int i, j;

  for(i=0;i<linhas;i++)
  {
      for(j=0;j<colunas;j++)
      {
        printf("matriz[%d][%d]: ",i,j);
        scanf("%d",&m[i][j]);
      }
  }
}

void mostrar(int m[][10],int linhas, int colunas)
{
  int i, j;

  for(i=0;i<linhas;i++)
  {
      for(j=0;j<colunas;j++)
      {
        printf("matriz[%d][%d]= %d\n",i,j,m[i][j]);
      }
  }
}

void soma(int m[][10], int n[][10], int o[][10], int linhas, int colunas)
{
  int i,j;

  for(i=0;i<linhas;i++)
  {
      for(j=0;j<colunas;j++)
      {
        o[i][j] = m[i][j] + n[i][j];
      }
  }
}

E a subtração?

Mesma coisa. Basta trocar o sinal de + pelo de -.

Multiplicação também dá na mesma né?

Sim, sim. É só trocar o sinal… Não, não.

Daqui pra baixo o bixo pega.

Se para somar precisamos que sejam matrizes de ordem igual, na multiplicação temos uma liberdade um pouco maior. Apenas precisamos que a quantidade de colunas da primeira seja igual a quantidade de linhas da segunda.

Porém, não multiplicamos a posição m[1][1] pela n[1][1]. Multiplicamos as colunas de M pelas linhas de N.

A matriz resultante será da seguinte ordem: linhas de M por colunas de N.

Multiplicação
Um bom link de suporte: multiplicação de matrizes.

Mão na massa

aaa

void multiplicar(int m[][10], int n[][10], int o[][10], int limite)
{
  int i,j,k;

  for(i=0;i < limite; i++)
  {
    for(j=0;j < limite; j++)
    {
      o[i][j] = 0;

      for(k=0; k < limite; k++)
      {
        o[i][j] += m[i][k] + n[k][j];
      }
    }
  }
}

Fixamos normalmente nas linhas. Passamos para as colunas. Já tem algo diferente: Zero a posição o[i][j], pois provavelmente ela está com um valor maluco como 29839 ou – 2783.

Dentro das colunas, abrimos o laço de K. É com ele que conseguimos multiplicas as colunas de M pelas linhas de N.

Sabemos que estamos na linha i de M, mas e para iterar pelas colunas? Usamos K.

m[i][k]

Sabemos que estamos na coluna j de N, mas e para iterar pelas linhas?
Algum chute?

n[k][j]

Precisamos passar por todas as linhas e colunas, mas usaremos as linhas e colunas em momentos diferentes nas matrizes. K resolve isso.

Código completo:

#include <stdio.h>
#include <stdlib.h>

void preencher(int m[][10],int linhas, int colunas);
void mostrar(int m[][10],int linhas, int colunas);

void multiplicar(int m[][10], int n[][10], int o[][10], int limite);

int main(int argc, char *argv[])
{
  int a[10][10], b[10][10], c[10][10];

  printf("Matriz A:\n");
  preencher(a,2,2);
  printf("Matriz B:\n");
  preencher(b,2,2);
  printf("Multiplicando...\n");
  multiplicar(a,b,c,2);

  mostrar(c,2,2);

  system("PAUSE");
  return 0;
}

void preencher(int m[][10], int linhas, int colunas)
{
  int i, j;

  for(i=0;i<linhas;i++)
  {
      for(j=0;j<colunas;j++)
      {
        printf("matriz[%d][%d]: ",i,j);
        scanf("%d",&m[i][j]);
      }
  }
}

void mostrar(int m[][10],int linhas, int colunas)
{
  int i, j;

  for(i=0;i<linhas;i++)
  {
      for(j=0;j<colunas;j++)
      {
        printf("matriz[%d][%d]= %d\n",i,j,m[i][j]);
      }
  }
}

void multiplicar(int m[][10], int n[][10], int o[][10], int limite)
{
  int i,j,k;

  for(i=0;i < limite; i++)
  {
    for(j=0;j < limite; j++)
    {
      o[i][j] = 0;

      for(k=0; k < limite; k++)
      {
        o[i][j] += m[i][k] + n[k][j];
      }
    }
  }
}

IMPORTANTE

A matriz de saída será de ordem Mi, Nj.

Se tivermos M[2][3] X N[3][4]:

O[2][4]

Fechando a régua e passando a conta

Ou algo assim.

Essas são as operações básicas. Espero na próxima parte abordar sobre alocação dinâmica de matrizes. Ou seja, as matrizes não vão ser declaradas com M[20][20], deixando espaço a toa, mas sim com o pedido do usuário.

Fica pra quando eu conseguir :)

Cya!

About these ads

6 comentários sobre “Linguagem C: Matrizes, parte 2

  1. cara td bem! me ajuda, preciso de fazer uma matriz que armazena os numeros da linha, soma-os e fornecendo á média.

  2. olá amigo, olha meu algoritmo
    #include
    #include

    float** criaMatriz1(int numL, int numC)
    {
    float** mat1 = (float**) malloc(numL * sizeof(float*));

    int i;
    for(i = 0; i < numL; ++i)
    mat1[i] = (float*) malloc(numC * sizeof(float));

    return mat1;
    }

    void lerMatriz1(float** mat1, int numL, int numC)
    {
    int i,j;

    printf("Entre com os valores da matriz A :\n",numL,numC);
    for(i = 0; i < numL; ++i)
    {
    for(j = 0; j < numC; ++j)
    {
    scanf("%f",&mat1[i][j]);
    }
    }
    }

    float** criaMatriz2(int numL, int numC)
    {
    float** mat2 = (float**) malloc(numL * sizeof(float*));

    int i;
    for(i = 0; i < numL; ++i)
    mat2[i] = (float*) malloc(numC * sizeof(float));

    return mat2;
    }

    void lerMatriz2(float** mat2, int numL, int numC)
    {
    int i,j;

    printf("Entre com os valores da matriz B :\n",numL,numC);
    for(i = 0; i < numL; ++i)
    {
    for(j = 0; j < numC; ++j)
    {
    scanf("%f",&mat2[i][j]);
    }
    }
    }

    void imprimeMatriz2(float** mat2, int numL, int numC)
    {
    int i,j;
    for(i = 0; i < numL; ++i)
    {
    for(j = 0; j < numC; ++j)
    {
    printf("%f ",mat2[i][j]);
    }
    printf("\n");
    }
    }

    float** criaMatriz(int numL, int numC)
    {
    float** mat = (float**) malloc(numL * sizeof(float*));

    int i;
    for(i = 0; i < numL; ++i)
    mat[i] = (float*) malloc(numC * sizeof(float));

    return mat;
    }

    void imprimeMatriz1(float** mat1, int numL, int numC)
    {
    int i,j;
    for(i = 0; i < numL; ++i)
    {
    for(j = 0; j < numC; ++j)
    {
    printf("%f ",mat1[i][j]);
    }
    printf("\n");
    }
    }

    float** soma(float** mat1, float** mat2, int numL, int numC)
    {
    float** som = criaMatriz(numC,numL);

    int i,j;

    for(i = 0; i < numL; ++i)
    {
    for(j = 0; j < numC; ++j)
    {
    som[i][j]=mat1[i][j] + mat2[i][j];
    }
    }
    return som;
    }

    void imprimeMatriz(float** som, int numL, int numC)
    {
    int i,j;
    for(i = 0; i < numL; ++i)
    {
    for(j = 0; j < numC; ++j)
    {
    printf("%f ",som[i][j]);
    }
    printf("\n");
    }
    }

    int main()
    {
    //Leitura da ordem da matriz A;
    int numL, numC;

    printf("Entre com o numero de linhas e colunas das matrize A e B :\n");
    scanf("%d %d",&numL,&numC);

    float** mat1 = criaMatriz(numL,numC);

    /* mat1 = (float**) malloc(numL * sizeof(float*));

    int i;
    for(i = 0; i < numL; ++i)
    mat1[i] = (float*) malloc(numC * sizeof(float));*/

    lerMatriz1(mat1,numL,numC);

    imprimeMatriz1(mat1,numL,numC);

    float** mat2 = criaMatriz(numL,numC);

    /* mat2 = (float**) malloc(numL * sizeof(float*));

    int i;
    for(i = 0; i < numL; ++i)
    mat2[i] = (float*) malloc(numC * sizeof(float));*/

    lerMatriz2(mat2,numL,numC);

    imprimeMatriz2(mat2,numL,numC);

    float** som = soma(mat1,mat2,numL,numC);
    imprimeMatriz (som,numC,numL);

    system("pause");
    }

    é um de adição de matrizes,
    mas só funciona se forem matrizes quadradas.. se não forem matrizes não dá certo
    por exemplo se forem matrizes 2×3 … não som a terceira coluna ;x
    pode me ajudar mostrando o que está errado?
    obrigado.

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s