Ir ao conteúdo
  • Cadastre-se

C Contar valores em uma matriz e imprimir o vetor e a quantidade


Posts recomendados

 

Boa Noite!

 

Preciso fazer um código onde eu  preencho uma matriz com valores do tipo char e conto o número de ocorrências de cada caractere que aparece na matriz. Após a contagem, tenho que listar cada caractere digitado e o número de ocorrências;

 

EX: digitei: "a, s, d, a, a, s"

o código deverá imprimir:

 

"a quantidade: 3

 s quantidade: 2

 d quantidade: 1"

 

 

 

Fiz o código abaixo mas não imprime corretamente, pois ele imprime da seguinte forma:

 

"a quantidade: 1"
"a quantidade: 2"
"a quantidade: 3"

 

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


int main()
{
	setlocale(LC_ALL, "Portuguese");

	// Declaração de Variáveis.
	int m = 0, n = 0, mi[10][10], mai[10][10];
	char mxn[10][10], c;
	int contl, contc, contl2, contc2;

	// Povoando matrizes "mi" e "mai" com "0" em todas as posições
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			mi[i][j] = 0;
			mai[i][j] = 0;
		}
	}

	// Usuário define o tamanho da matriz "mxn".
	while ((m < 1) || (m > 10))
	{
		printf("Digite a dimensão da matriz M: \n");
		scanf_s("%d", &m);
		while ((c = getchar()) != '\n' && c != EOF) {}
	}

	while ((n < 1) || (n > 10))
	{
		printf("Digite a dimensão da matriz N: \n");
		scanf_s("%d", &n);
		while ((c = getchar()) != '\n' && c != EOF) {}
	}

	// Povoa a matriz até o tamanho definido pelo usuário.
	for (int i = 0; i < m; i++)
	{
		for (int j = 0; j < n; j++)
		{
			printf("Digite o elemento para [%d,%d]: \n", i, j);
			mxn[i][j] = getchar();
			while ((c = getchar()) != '\n' && c != EOF) {}
		}
	}


	//testar
	for (int i = 0; i < m; i++)
	{
		for (int j = 0; j < n; j++)
		{
			putchar(mxn[i][j]);
		}
		printf("\n");
	}

	//Armazenamento de números de ocorrências.
		for (contl = 0; contl <= m; contl++)
		{
			for (contc = 0; contc <= n; contc++)
			{
				for (contl2 = 0; contl2 <= m; contl2++)
				{
					for (contc2 = 0; contc2 <= n; contc2++)
					{
						//Se achar um valor igual a outro e que não foi contado na matriz marca o valor como contado e soma.
						if ((mxn[contl][contc] == mxn[contl2][contc2]) && (mi[contl][contc] == 0))
						{
							//Marca o valor
							mi[contl2][contc2] = 1;
							//Soma 1 na primeira posição que aparece o valor.
							mai[contl][contc]++;
						}
					}
				}
			}
		}
		


	//Impressão dos valores finais.
		for (contl = 0; contl < m; contl++)
		{
			for (contc = 0; contc < n; contc++)
			{
				//Se a quantidade for maior ou igual a 1, imprime a quantidade na tela.
				if (mai[contl][contc] >= 1)
				{
					printf("%c\t", mxn[contl][contc]);
					printf("Quantidade: ");
					printf("%d\n", mai[contl][contc]);
				}

			}
		}

	system("pause");
	return 0;
}

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Vou repetir o que eu escrevi sobre isso há pouco nesse tópico:

 

Seu programa está muito complicado sem necessidade. 3 matrizes? Não precisa disso. E não é esperto ler primeiro porque não vai mudar nada. Faça as contas enquanto lê. É mais simples e eficiente.

 

E não precisa sequer de uma matriz para testar. Apenas uma sequência de números. Não é preciso fazer um programa inteiro primeiro. Pode fazer pequenos programas. Ninguém vai te culpar, mesmo porque ninguém vai saber. Projetos grandes são todos escritos assim.

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@Arthur Bezerra de Oliveira     na comparação dos caracteres precisa verificar se não é o mesmo , e seu código com algumas modificações poderia ser assim  :

#include<stdio.h>
#include<locale.h>
#include <string.h>
int main(){
    setlocale(LC_ALL, "Portuguese");
    // Declaração de Variáveis.
    int i,j,m,n;
    char m_x_n[10][10][2], // Matriz tridimensional
         c;
    int contl, contc, contl2, contc2;
    // Povoando matrizes "mi" e "mai" com "0" em todas as posições
    for( i=0; i<10; i++ ) 
        for( j=0; j<10; j++ )
            m_x_n[i][j][1] = 1 ; // inicializa a matriz com valor 1
    // Usuário define o tamanho da matriz "mxn".
    while( m < 1 || m > 10 ){    // garantir que esteja dentro da medida certa
        printf("Quantidade de Linhas da matriz M : ");
        scanf("%d",&m);
        while ((c = getchar()) != '\n' && c != EOF) {}
    }
    while( n < 1 || n > 10 ){    // validar essa dimensão
        printf("Quantidade de colunas da matriz N : ");
        scanf("%d",&n); 
        while ((c = getchar()) != '\n' && c != EOF) {}
    }
    // Povoa a matriz até o tamanho definido pelo usuário.
    for( i=0; i<m; i++ )
        for( j=0; j<n; j++ ){
            printf("Digite o elemento para [%d,%d] : ",i,j);
            m_x_n[i][j][0] = getchar(); // pegar um caractere do teclado e armazena na matriz
            while ((c = getchar()) != '\n' && c != EOF) {}
        }
    //escrever os carateres da Matriz na telar
    for( i = 0; i < m; i++){
        for( j = 0; j < n; j++){
            putchar(m_x_n[i][j][0]);    // comando esquisito , mas é melhor do que o puts
        }                               // seria melhor o printf mesmo
        printf("\n");
    }
    //Armazenamento de números de ocorrências.
    for( contl=0; contl<m; contl++ )    // percorrer as linha da matriz
        for( contc=0; contc<n; contc++ )// percorrer as colunas da matriz
            for( contl2=0; contl2<m; contl2++ )        // testar todas as posições da matriz con todas
                for( contc2=0; contc2<n; contc2++ )
                //Se achar um valor igual a outro e que não foi contado na matriz marca o valor como contado e soma.
                    if( ( m_x_n[contl][contc][0] == m_x_n[contl2][contc2][0] ) && 
                        ( contl != contl2 || contc != contc2 ) ){ // se o carctere for igual e não for o mesmo
                         m_x_n[contl][contc][1]++;     // incrementa a qtd dele 
                         m_x_n[contl2][contc2][0] = 0 ;// colocar esse valor zero no lugar do caratere na matriz
                                                       // para não interferir na contagem sendo somado novamente
                    }
    //Impressão dos valores finais.
    for( contl=0; contl<m; contl++ )
        for( contc=0; contc <n; contc++ )
            if(m_x_n[contl][contc][0] != 0){           // se nessa posição for zero , esse carac é repetido e foi apagado 
                                                       // nesse local , mas ainda está na matriz em outra posição
                printf("O Caractere %c  Saiu %d Vez",  // escreve o carac e a qtd dele na tela do console
                m_x_n[contl][contc][0],m_x_n[contl][contc][1]);        // onde está o carac e a qtd dele
                if(m_x_n[contl][contc][1] > 1 )printf("es . . . !\n"); // para o plural
                else printf(" . . . !\n");                             // ou singular
            }
    system("pause");
    return 32768;
}

 

  • Obrigado 2
Link para o comentário
Compartilhar em outros sites

@devair1010 Eu achei aquele complicado com as 3 matrizes e tal, mas agora tem uma possibilidade com apenas duas matrizes, mas  de TRÊS dimensões e 17 comandos de loop incluindo um loop de 4 loops for aninhados?

Não seria muito para listar as ocorrências? Vou ler tudo de novo 🤔

 

 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

Sempre é melhor escrever o programa em torno dos dados. 


Considere, @devair1010, essa estrutura como exemplo:

typedef struct
{
	int	linhas; // o esperado
	int	colunas;
	char	matriz[100]; // maximo 10x10 afinal
	int	n_simbolos; // total de simbolos distintos
	char	simbolo[100]; // a tabela
	char	total[100]; // de simbolos e totais
}	Rascunho;

Um rascunho como se a gente fosse usar papel e caneta e ir marcando as letras conforme a matriz. Tudo fica muito mais simples. Veja se concorda:


Considere as funções

int		define_tamanhos(Rascunho*);
int		le_matriz(Rascunho*);		
int		mostra_matriz(Rascunho*);	
int		mostra_tabela(Rascunho*);

Imagine o que elas fazem: o óbvio. E marcam no tal Rascunho os valores.

 

main()

int main()
{	Rascunho papel; // nosso papel e caneta
	papel.n_simbolos = 0;
	define_tamanhos(&papel);
	le_matriz(&papel);
	mostra_matriz(&papel);
	mostra_tabela(&papel);
	printf("Tecle ENTER para terminar \n"); getchar();
	return 0;
}

No fundo main() só tem uma variável: o papel pra marcar as letras e a tabela. E as funções vão preenchendo os valores conforme encontram.

 

Como eu expliquei num outro post, não há razão para ler a matriz e depois verificar as letras. Não é eficiente: quando você lê já pode ver se já tinha ou não a letra e fazer as contas, marcando no "papel" :) . Assim ao final só precisa mostrar a tabela de ocorrências.

 

Veja essa rotina

int		le_matriz(Rascunho* papel)
{	// o tamanho da matriz esta no 'papel' que veio como argumento
	printf("\nMatriz com %dx%d caracteres\n", papel->linhas, papel->colunas);
	char c = 0;
	char* M = papel->matriz; // mais fácil pra ler 
	for (int i = 0; i < papel->linhas; i++)
		for (int j = 0; j < papel->colunas; j++)
		{
			printf("Digite o elemento para [%d,%d] : ", i, j);
			c = getchar();
			M[i * papel->colunas + j] = c;
			// marca a presenca da letra 'c'
			int nova_letra = 1;
			for (int i = 0; i < papel->n_simbolos; i += 1)
				if (c == papel->simbolo[i])
				{
					papel->total[i] += 1; // ja tinha
					nova_letra = 0;
					break; // resolvido
				};	// if()
			if (nova_letra)
			{	// primeira vez de c
				papel->simbolo[papel->n_simbolos] = c;
				papel->total[papel->n_simbolos] = 1;
				papel->n_simbolos += 1;
			};
			while ((c = getchar()) != '\n' && c != EOF) {};
		};
	return 0;
};	// le_matriz()

Apenas um loop para ler a matriz. Mas dentro do loop já marca na tabela a letra (se é nova) ou marca a nova ocorrência (se já tinha). Mais simples e fácil de ler.

 

E mostrar o resultado é trivial

int		mostra_tabela(Rascunho* papel)
{	// mostra as letras na ordem em que apareceram
	printf("\n\tAs %d letras, na ordem de apresentacao\n\n", papel->n_simbolos);
	printf("\tLetra Total\n");
	for (int i = 0; i < papel->n_simbolos; i += 1)
		printf("\t %3c   %3d\n", papel->simbolo[i], papel->total[i]);
	printf("\n\nFim da lista\n");
	return 0;
};

Só um loop.

 

Um exemplo de execução:

Quantidade de Linhas da matriz [1..10]: 2
Quantidade de Colunas da matriz [1..10]: 4

Matriz com 2x4 caracteres
Digite o elemento para [0,0] : a
Digite o elemento para [0,1] : c
Digite o elemento para [0,2] : d
Digite o elemento para [0,3] : F
Digite o elemento para [1,0] : G
Digite o elemento para [1,1] : a
Digite o elemento para [1,2] : c
Digite o elemento para [1,3] : s

Matriz com 2x4 caracteres
a c d F
G a c s

        As 6 letras, na ordem de apresentacao

        Letra Total
           a     2
           c     2
           d     1
           F     1
           G     1
           s     1


Fim da lista
Tecle ENTER para terminar

Deixei até a "pausa" no final para manter sua tradição.

 

Eis um programa completo

Spoiler

#include <stdio.h>

typedef struct
{
	int		linhas;
	int		colunas;
	char 	matriz[100]; // max 10x10 afinal
	int		n_simbolos;
	char	simbolo[100];
	char	total[100];
}	Rascunho;

int		define_tamanhos(Rascunho*);
int		le_matriz(Rascunho*);		
int		mostra_matriz(Rascunho*);	
int		mostra_tabela(Rascunho*);

int main()
{	
	Rascunho papel; // nosso papel e caneta
	papel.n_simbolos = 0;
	define_tamanhos(&papel);
	le_matriz(&papel);
	mostra_matriz(&papel);
	mostra_tabela(&papel);
	printf("Tecle ENTER para terminar \n"); getchar();
	return 0;
}

int		define_tamanhos(Rascunho* papel)
{
	char c = 0;
	int m = 0;
	while (m < 1 || m > 10)
	{
		printf("Quantidade de Linhas da matriz [1..10]: ");
		scanf("%d", &m);
		while ((c = getchar()) != '\n' && c != EOF) {}
	};
	papel->linhas = m;
	m = 0;
	while (m < 1 || m > 10)
	{
		printf("Quantidade de Colunas da matriz [1..10]: ");
		scanf("%d", &m);
		while ((c = getchar()) != '\n' && c != EOF) {}
	};
	papel->colunas = m;
	return 0;
}	// define_tamanhos()

int		le_matriz(Rascunho* papel)
{
	// o tamanho da matriz esta no 'papel' que veio como argumento
	printf("\nMatriz com %dx%d caracteres\n", papel->linhas, papel->colunas);
	char c = 0;
	char* M = papel->matriz; // mais fácil pra ler 
	for (int i = 0; i < papel->linhas; i++)
		for (int j = 0; j < papel->colunas; j++)
		{
			printf("Digite o elemento para [%d,%d] : ", i, j);
			c = getchar();
			M[i * papel->colunas + j] = c;
			// marca a presenca da letra 'c'
			int nova_letra = 1;
			for (int i = 0; i < papel->n_simbolos; i += 1)
				if (c == papel->simbolo[i])
				{
					papel->total[i] += 1; // ja tinha
					nova_letra = 0;
					break; // resolvido
				};	// if()
			if (nova_letra)
			{	// primeira vez de c
				papel->simbolo[papel->n_simbolos] = c;
				papel->total[papel->n_simbolos] = 1;
				papel->n_simbolos += 1;
			};
			while ((c = getchar()) != '\n' && c != EOF) {};
		};
	return 0;
};	// le_matriz()

int		mostra_matriz(Rascunho* papel)
{
	printf("\nMatriz com %dx%d caracteres\n", papel->linhas, papel->colunas);
	for (int l = 0; l < papel->linhas; l += 1)
	{
		for (int c = 0; c < papel->colunas; c += 1)
			printf("%c ", papel->matriz[l * papel->colunas + c]);
		printf("\n");
	};	// for()
	return 0;
};

int		mostra_tabela(Rascunho* papel)
{	// mostra as letras na ordem em que apareceram
	printf("\n\tAs %d letras, na ordem de apresentacao\n\n", papel->n_simbolos);
	printf("\tLetra Total\n");
	for (int i = 0; i < papel->n_simbolos; i += 1)
		printf("\t %3c   %3d\n", papel->simbolo[i], papel->total[i]);
	printf("\n\nFim da lista\n");
	return 0;
};

 

 

  • Obrigado 2
Link para o comentário
Compartilhar em outros sites

22 horas atrás, devair1010 disse:

na comparação dos caracteres precisa verificar

@arfneto Entendi o seu conceito e achei muito prático e bem inteligente, inclusive me impressionei com a simplicidade e praticidade do seu código.
@devair1010 Também funcionou corretamente o seu código, bem parecido com o meu, mas aparentemente tridimensional.

Porém eu fiz dessa forma para seguir algumas "regras" do exercício que me pede para criar esse código, anexei a questão para vocês entenderem melhor.
Praticamente já resolvi a questão toda, só estou no impasse para imprimir.

 

Já tentei marcar os valores contados com "0" para que eles não apareçam na impressão porém acredito que não estou acertando a forma de fazer isso, já usei "While" e "If" de várias formas diferentes antes da impressão para definir os valores contados como "0", mas estou errando em algum ponto.

questao.png

  • Amei 1
Link para o comentário
Compartilhar em outros sites

3 horas atrás, devair1010 disse:

não entendi ,  qual o problema de a matriz ser tridimensional , o enunciado não proibe isso não ,  ali marquei mesmo com zero e está funcionando

 

@devair1010 Não há exatamente um problema em usar uma matriz tridimensional e não há uma razão para não funcionar assim. Apenas não é uma boa ideia: não acrescenta nada e apenas dá mais trabalho e fica mais difícil de ler o programa, como deve ter percebido comparando os exemplos que temos aqui.


Entenda que

  • essas dimensões da matriz nada tem a ver uma com a outra e quando você se afasta dos dados certamente vai ter mais trabalho
  • o primeiro problema já aparece no nome e sentido: uma matriz é apenas um nome e um endereço de início. E você tem que usar essas dimensões da matriz para coisas muito diferentes.
    • Você tem os dados em um plano
    • E a partir deles vai criar uma lista com cada símbolo e o total de vezes em que ele aparece. Esses seriam os outros planos da matriz
    • acontece que esses dados não tem nada a ver com a estrutura da matriz e vai complicar a lógica de seu programa. Imagine uma tabela de 8x8 símbolos, metade 'a' e metade 'Y' e acho que vai entender: você só tem dois valores e eles não tem essa estrutura 8x8
    • e o nome fica o mesmo então fica difícil de ler e escrever. Notou que em seu programa não se explica que os contadores de símbolos estão lá no segundo plano da matriz
    • E teve que zerar todos? E não há razão para zerar todos, desde que você saiba quantos símbolos distintos tem na matriz. Ela pode ter 100 valores iguais por exemplo.

Rascunho

typedef struct
{
	int	linhas; // o esperado
	int	colunas;
	char	matriz[100]; // maximo 10x10 afinal
	int	n_simbolos; // total de simbolos distintos
	char	simbolo[100]; // a tabela
	char	total[100]; // de simbolos e totais
}	Rascunho;

Eu digitei o programa que eu postei aqui em cima de seu programa, apenas para mostrar como podia ser mais fácil e legível se escrevesse em torno dos dados. E chamei de Rascunho porque era algo simplório escrito apenas para rodar da primeira vez e ser fácil de ler. E olhando acima você "vê" o enunciado e o caminho da solução. Mas algo assim já serviria, já que mostrou os valores certos logo na primeira vez. Mas...

typedef struct
{
	int	linhas; // o esperado
	int	colunas;
	char	matriz[100]; // maximo 10x10 afinal
	int	n_simbolos; // total de simbolos distintos
	char	total[100]; // de simbolos e totais
}	PlanoB;

Assim estaria melhor porque não há razão para repetir os símbolos ou colocar linha, coluna e mais um índice numa coisa que é só uma lista de totais. Os símbolos já estão na matriz afinal. Isso seria o simples. Mas..

typedef struct
{
	int	linhas; // o esperado
	int	colunas;
	char	matriz[10][10]; // maximo 10x10 afinal
	int	n_simbolos; // total de simbolos distintos
	char	total[100]; // de simbolos e totais
}	OsDados;

Isso seria o mais alinhado com o enunciado.

 

Entenda que não existe essa noção de vetor, matriz ou matriz multidimensional em C. Uma matriz de duas dimensões é apenas um vetor de vetores. Uma de 3 é um vetor de vetores de vetores. Nada mais. Todos alocados por linha na memória a partir do endereço inicial, e acessados pelo nome mais um deslocamento. Para duas dimensões essa é a conta

M[i * papel->colunas + j] = c; // para acessar M[i,j];

Se você não fizer o compilador vai fazer.

 

A contagem das letras


O mais difícil de justificar nessa solução na verdade não é o fato de forçar a tabela de totais em uma dimensão a mais da matriz, numa coisa que não tem essa estrutura e que não deveria ter o mesmo nome. O maior problema é voltar a processar a matriz num loop posterior. Não é eficiente. Se eu fosse corrigir os programas de vocês iria penalizar todas as soluções que tivessem essa ingenuidade incluída.
 

Uma vez que você leu uma letra, não há razão para não tabelar o resultado na hora.


Veja como foi feito no exemplo

			c = getchar();
			M[i * papel->colunas + j] = c;
			// marca a presenca da letra 'c'
			int nova_letra = 1;
			for (int i = 0; i < papel->n_simbolos; i += 1)
				if (c == papel->simbolo[i])
				{
					papel->total[i] += 1; // ja tinha
					nova_letra = 0;
					break; // resolvido
				};	// if()
			if (nova_letra)
			{	// primeira vez de c
				papel->simbolo[papel->n_simbolos] = c;
				papel->total[papel->n_simbolos] = 1;
				papel->n_simbolos += 1;
			};

E entenda como é trivial de ler. Como eu disse, sequer é preciso ter um vetor de símbolos e se eu fosse corrigir o meu programa ia descontar algo por ter esse vetor também. Depois eu mostro uma solução usando a terceira estrutura que mostrei

 

@Arthur Bezerra de Oliveira não se preocupe, não sou seu professor disfarçado aqui :) Pode programar omo achar melhor


Poste seu código se ainda precisa de ajuda.

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

45 minutos atrás, devair1010 disse:

seu código ficou muito bom  e bem reduzido ,  gostei , e estou estudando essa parte de struct ,  mas eu fiz com essa matriz por que no enunciado pede para criar e preencher uma matriz ,  então creio que matriz não seja vetor nem struct 

 

o que eu te disse foi que

  • a tabela de letras é muito diferente da matriz e colocar a tabela de letras como uma dimensão a mais da própria só vai complicar, além delas terem que ter o mesmo nome, o que deixa tudo menos legível. Você não pode escrever quantidade [ i ], letra[ i ], porque colocou os valores como uma dimensão a mais da matriz, e assim fica mais difícil de ler: tem que usar o mesmo nome: matriz. Só que não é a matriz. Basta ler os programas que temos aqui.
    Veja nesse trecho aqui como é mais simples de entender que achou um símbolo novo e aumentou o total deletes e o símbolo é c...
    		if (nova_letra)
    		{	// primeira vez de c
    			papel->simbolo[papel->n_simbolos] = c;
    			papel->total[papel->n_simbolos] = 1;
    			papel->n_simbolos += 1;
    		};

     

  • uma matriz de M[ A ][ B ][ C ] é um vetor de vetores de vetores. Não há o que fazer sobre isso. É a linguagem e o hardware. O compilador calcula a dimensão total e coloca os caras lá a partir do início, linha por linha. Uma matriz
    	char M[10][10];
    é um vetor de 10 vetores de 10 char cada um. M[0] por exemplo é char[10], M[1] é char[10]. Você  lê a declaração da direita para a esquerda.
    C só tem vetores, arrays. Não é FORTRAN. Eu programei por muitos anos em FORTRAN antes de usar C e demorei para aceitar que não existe array multidimensional em C ;) . É a realidade em C. M[0][7] é char. Assim é.
     
  • a matriz pode estar --- e está nos exemplos que te mostrei --- dentro da struct. Não muda nada escrever
    	papel->matriz[0][0];
    ou 
    	m_x_n2[contl2][contc2][0] = 0; 

    como no seu programa.
     

  • struct em C é só um agrupamento de variáveis dentro de um nome só, uma estrutura :)

    Usar uma estrutura simplifica a leitura do programa e a passagem de parâmetros, mas pode muito bem passar sem isso, em especial num programa tão simples. Só fica mais chato ficar passando os parâmetros para as funções, e assim mais difícil de ler.

Você pode pegar o programa que te mostrei e apagar a struct. É só trocar os parâmetros das funções. Vai funcionar igualzinho em minutos.

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Um exemplo para usar uma matriz de totais ou uma segunda dimensão na matriz original


A lógica que estão usando pode ser vista assim:
 

Exemplo 1
você tem uma matriz M[2][3] assim:

a b c
d e f

e então cria uma matriz T[2][3] assim:

1 1 1
1 1 1

com os totais de ocorrências das letras.
 

Exemplo 2

a a a
a a b

os totais seriam

5 0 0
0 0 1

Exemplo 3

a a b b 
X X 3 3

Os totais seriam

2 0 2 0
2 0 2 0


Acho que é o que fizeram, exceto que deixaram para ler tudo de novo depois, o que não é necessário nem eficiente.

 

  • Na matriz de totais um valor zero na posição de uma letra indica que ela já tinha aparecido antes. Uma letra que apareça 3 vezes tem o valor 3 na posição correspondente à primeira ocorrência e zero nas outras duas.
     
  • Uma propriedade interessante disso é que a soma de todos os valores dessa tabela deve bater com o total de elementos da matriz, linhas x colunas e você pode usar isso para testar.
     
  • Uma outra é que por definição vai usar todos os valores da matriz, então NÃO precisa inicializar a matriz de totais.

Exemplo: 


Usando matriz [ ] [ ] para ler os valores e totais [ ] [ ] para os totais e c para a letra...

			c = getchar();
			papel->matriz[i][j] = c; // na matriz
			papel->total[i][j] = 0;  // repetida
			n_lidos += 1;
			int x = 0;
			int y = 0;
			int nova_letra = 1; // assume nova letra
			for (int v = 0; v < n_lidos-1; v += 1)
			{
				// compara com os que ja leu
				if (c == papel->matriz[x][y])
				{	// entao ja tinha
					papel->total[x][y] += 1;
					nova_letra = 0;
					break;
				};	// if()
				y = y + 1;
				if (y >= papel->colunas)
				{
					y = 0;
					x = x + 1;
				}; // aponta para o prox na matriz
			};	// for(v)
			if (nova_letra)
			{
				papel->n_simbolos += 1;
				papel->total[i][j] = 1;// nova
			};	// if()
			while ((c = getchar()) != '\n' && c != EOF) {};

Esse código faz o ajuste dos totais a cada leitura. Apenas um loop olhando para trás nas letras que já foram lidas e acertando os contadores. Ao final da leitura os n_simbolos estão totalizados na matriz e se pode mostrar, sem ter que varrer a matriz a toa de novo.


Se vê problemas em usar uma estrutura basta apagar as referências a ela e declarar as variáveis localmente

 

Uma função que lê a matriz e faz as contas ao mesmo tempo:

Spoiler

int		le_matriz(Rascunho* papel)
{
	// o tamanho da matriz esta no 'papel' que veio como argumento
	printf("\nMatriz com %dx%d caracteres\n", papel->linhas, papel->colunas);
	char c = 0;
	int n_lidos = 0;
	papel->n_simbolos = 0;
	for (int i = 0; i < papel->linhas; i++)
	{
		for (int j = 0; j < papel->colunas; j++)
		{
			printf("Digite o elemento para [%d,%d] : ", i, j);
			c = getchar();
			papel->matriz[i][j] = c; // na matriz
			papel->total[i][j] = 0;  // repetida
			n_lidos += 1;
			int x = 0;
			int y = 0;
			int nova_letra = 1; // assume nova letra
			for (int v = 0; v < n_lidos-1; v += 1)
			{
				// compara com os que ja leu
				if (c == papel->matriz[x][y])
				{	// entao ja tinha
					papel->total[x][y] += 1;
					nova_letra = 0;
					break;
				};	// if()
				y = y + 1;
				if (y >= papel->colunas)
				{
					y = 0;
					x = x + 1;
				}; // aponta para o prox na matriz
			};	// for(v)
			if (nova_letra)
			{
				papel->n_simbolos += 1;
				papel->total[i][j] = 1;// nova
			};	// if()
			while ((c = getchar()) != '\n' && c != EOF) {};
		};	// for(j)
	};	// for(i)
	return 0;
};	// le_matriz()

 

 

E como mostrar os totais?

 

Ao final n_simbolos distintos estarão na matriz totais[ ] [ ]. Pode ser um só, se a matriz for de apenas uma letra, por exemplo. Então para imprimir é um único loop: enquanto tiver algo pra listar vai listando. Nada mais.


Exemplo

int		mostra_tabela(Rascunho* papel)
{	// mostra as letras na ordem em que apareceram
	printf("\n\tAs %d letras, na ordem em que apareceram\n\n",
           papel->n_simbolos);
	printf("\tLetra Total\n");
	int l = 0;
	int c = 0; // linha e coluna
	int a_listar = papel->n_simbolos; // esses sao os distintos
	while (a_listar > 0)
	{
		if (papel->total[l][c] != 0)
		{	// uma letra nova
			printf("\t %3c   %3d\n",
                   		papel->matriz[l][c],
                   		papel->total[l][c]);
			a_listar = a_listar - 1; // mostrou mais um
		};
		c = c + 1;
		if (c >= papel->colunas)
		{
			c = 0;
			l = l + 1;
		};
	};	// while()
	printf("\n\nFim da lista\n");
	return 0; // acabou
};

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!