Ir ao conteúdo

Posts recomendados

Postado

 

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
Postado

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
Postado

@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
Postado

@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
Postado

@arfneto    não precisa dessa segunda matriz , é só para manter os dados originais , se quiser usa-la para qualquer outra coisa .                   mas você tem razão aí é demais mesmo , vou Editar  e remover uma dessas matrizes   .   

  • Curtir 1
Postado

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
Postado
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
Postado
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
Postado

@arfneto    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  .

Postado
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
Postado

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

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...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!