Lista Encadeada formando uma matriz [RESOLVIDO]

1 resposta
gpd38

Enunciado Antigo: Preencher duas matrizes esparsas, Remover elementos

1 Resposta

gpd38

Enunciado Novo: Preencher duas matrizes esparsas lendo de arquivo e Multiplicar as matrizes esparsas e gravar no arquivo o resultado da multiplicação
. . . . .
. . . . .
. . . . .
//Passou o tempo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e eu voltei com a solçução para que vcs vejam.

Se tiverem alguma sugestão sobre o que pode ser melhorado gostaria de saber

import java.io.IOException;
import javax.swing.JOptionPane;

/**
 * Classe Executavel
 * 
 * @author ___________
 */
public class Executavel {

	/**
	 * t = tamanho; 1 ou 2 = matriz utilizada; l = linha; c = coluna t1l =
	 * tamanho da linha na matriz1; t1c = tamanho da coluna na matriz1; t2l =
	 * tamanho da linha na matriz2; t2c = tamanho da coluna na matriz2;
	 */
	static int t1l, t1c, t2l, t2c;
	static Leitura_Arquivo La;// variavel da classe Leitura de Arquivo
	// variavel criada para ser somente nesta classe para identificar em qual
	// matriz estou trabalhando
	static int id_matriz = 0;
	static String linha, nome, nome_arquivo_gravar;
	// vetor de strings que armazena uma linha do
	// arquivo em cada poição do vetor
	static String vetpalavras[];
	static Matriz_Esparsa Matriz = new Matriz_Esparsa();

	public static void main(String args[]) throws IOException {

		nome = JOptionPane
				.showInputDialog("Digite o nome do arquivo de entrada.");
		// Este try captura a excecao do arquivo nao ser encontrado
		try {
			La = new Leitura_Arquivo(nome);
			linha = La.Acessar_Arquivo();
			while (linha != null) {
				vetpalavras = linha.split("\ ");
				if (vetpalavras[0].equalsIgnoreCase("M")) {
					Matriz.Cria_Matriz(vetpalavras);
					/*
					 * Aqui o id_matriz esta sendo incrementado pois como ja
					 * entrou uma vez a proxima sera para indicar para o codigo
					 * que ele ira trabalhar com a matriz 2
					 */
					id_matriz++;
					// Armazena o tamanho de linha e coluna das duas matrizes
					if (id_matriz == 1) {
						t1l = Integer.parseInt(vetpalavras[1]);
						t1c = Integer.parseInt(vetpalavras[2]);
					} else {
						t2l = Integer.parseInt(vetpalavras[1]);
						t2c = Integer.parseInt(vetpalavras[2]);
					}
				} else if (vetpalavras[0].equalsIgnoreCase("I")) {
					// Tratar caso queira inserir em uma posicao na matriz que
					// nao exista
					if (id_matriz == 1) {
						if (Integer.parseInt(vetpalavras[1]) > t1l
								|| Integer.parseInt(vetpalavras[2]) > t1c) {
							System.out
									.println("Você tentou acessar uma posição na matriz que é invalida!!! \n\n");
							System.exit(0);
						}
					} else {
						if (Integer.parseInt(vetpalavras[1]) > t2l
								|| Integer.parseInt(vetpalavras[2]) > t2c) {
							System.out
									.println("Você tentou acessar uma posição na matriz que é invalida!!! \n\n");
							System.exit(0);
						}
					}
					Matriz.Insere_Matriz(vetpalavras);
				} else if (vetpalavras[0].equalsIgnoreCase("R")) {
					// Tratar caso queira remover de uma posição na matriz que
					// não exista
					if (id_matriz == 1) {
						if (Integer.parseInt(vetpalavras[1]) > t1l
								|| Integer.parseInt(vetpalavras[2]) > t1c) {
							System.out
									.println("Você tentou acessar uma posição na matriz que é invalida!!! \n\n");
							System.exit(0);
						}
					} else {
						if (Integer.parseInt(vetpalavras[1]) > t2l
								|| Integer.parseInt(vetpalavras[2]) > t2c) {
							System.out
									.println("Você tentou acessar uma posição na matriz que é invalida!!! \n\n");
							System.exit(0);
						}
					}
					/*
					 * String opcao =JOptionPane.showInputDialog(
					 * "Deseja mostrar antes de remover o Elemento?\nS - Sim\nN - Não"
					 * ); if (opcao.equalsIgnoreCase("S")) {
					 * Matriz.Tela(id_matriz); }
					 */
					Matriz.Remove_Matriz(vetpalavras);
				} else {
					System.out
							.println("Não existe esta escolha na execução do codigo!!!");
				}
				linha = La.Acessar_Arquivo();// le a proxima linha do arquivo
			}
			La.CloseArquivo();// fecha o arquivo
		} catch (IOException ex) {
			System.out.println("\nARQUIVO NAO ENCONTRADO\n");
			System.exit(0);
		}// catch

		System.out.println("\n\nMatriz depois das alterações");
		Matriz.Tela(1);// Mostra a matriz 1 depois de todas as operações
		Matriz.Tela(2);// Mostra a matriz 2 depois de todas as operações

		// Verifica se a multiplicação pode ser feita
		if (t1c == t2l) {
			Matriz.Multiplicar();
		} else {
			System.out
					.println("\n Não é possivel efetuar a multiplicacao, pois as matrizes nao sao compativeis para tal operacao. ");
		}
		// falta gravar no arquivo
	}// main
}// class
import java.io.IOException;

import javax.swing.JOptionPane;

/**
 * Classe Matriz_esparsa
 * 
 * @author ____________
 */
class Matriz_Esparsa {

	Escrita_Arquivo Ea;// variavel da classe Escrita de Arquivo
	No sentinela1;// variavel que referencia a matriz 1
	No sentinela2;// variavel que referencia a matriz 2
	No sentinela3;// variavel que referenci a matriz de multiplicacao
	// variavel para guardar o tamanho da matriz de multiplicacao
	// posicao ZERO = nao contem nada
	// posicao UM = coluna da matriz 1
	// posicao DOIS = linha da matriz 2
	// posicao TRES = valor do elemento
	String vet_informacao_matriz_multiplicacao[] = new String[4];
	int controlamatriz = 0;// variavel que controla em qual matriz estou

	// trabalhando

	/**
	 * Construtor da Classe
	 * 
	 * Aqui ele inicializa as referencias das tres matrizes
	 */
	public Matriz_Esparsa() {
		sentinela1 = new No(-1, -1, -1);
		sentinela2 = new No(-1, -1, -1);
		sentinela3 = new No(-1, -1, -1);
	}// fim construtor

	/**
	 * Metodo Cria_Matriz
	 * 
	 * Este metodo recebe um vetor contendo em cada posição as informacoes
	 * para inserir na matriz esparsa o conteudo necessario
	 * 
	 * @param vetpalavras
	 *            - vetor contendo uma linha do arquivo onde em cada posição
	 *            esta uma informação exemplo: M 4 3 --> vet[0]=M ; vet[1]=4 ;
	 *            vet[2]=3
	 */
	public void Cria_Matriz(String[] vetpalavras) {
		int l = Integer.parseInt(vetpalavras[1]), c = Integer
				.parseInt(vetpalavras[2]);
		controlamatriz++;// incremento antes de usar porque ele começa de ZERO,
		No nova = null;// variavel que sera inserida na matriz esparsa
		No guia = null;// variavel que sera usada para percorrer a matriz e
		// encontrar a posiçao certa para a inserçãoo da nova
		// celula

		// Esta condiçao informa qual a matriz será usada
		if (controlamatriz == 1) {
			System.out.println("CRIA MATRIZ 1");
			// armazena o valor da linha da matriz A
			vet_informacao_matriz_multiplicacao[1] = vetpalavras[1];
			guia = sentinela1;// referencia a matriz 1
		} else if (controlamatriz == 2) {
			System.out.println("CRIA MATRIZ 2");
			// armazena o valor da coluna da matriz B
			vet_informacao_matriz_multiplicacao[2] = vetpalavras[2];
			guia = sentinela2;// referencia a matriz 2
		} else {
			System.out.println("CRIA MATRIZ 3");
			guia = sentinela3;// referencia a matriz de multiplicação
		}

		// Esta condicao informa qual a matriz sera usada
		for (int i = 0; i < c; i++) {
			nova = new No(-1, -1, i);
			nova.prox = guia.prox;
			guia.prox = nova;
			guia = guia.prox;
			nova.inf = null;
		}// for

		if (controlamatriz == 1) {
			guia = sentinela1;// Voltar a referencia de guia para celula cabeça
			// da matriz1
		} else if (controlamatriz == 2) {
			guia = sentinela2;// Voltar a referencia de guia para celula cabeça
			// da matriz1
		} else {
			guia = sentinela3;// Voltar a referencia de guia para celula cabeça
			// da matriz de multiplicacao
		}

		// Construcao da coluna de sentinelas
		for (int i = 0; i < l; i++) {
			nova = new No(-1, i, -1);
			nova.inf = guia.inf;
			guia.inf = nova;
			guia = guia.inf;
			nova.prox = null;
		}// for
		guia = null;// retirei a referencia para que esta variavel possa ser
		// deletada pelo SO
	}// metodo Cria_Matriz

	/**
	 * Metodo InsereMatriz
	 * 
	 * Este metodo insere o conteudo na matriz esparsa
	 * 
	 * @param vetpalavras
	 *            - vetor contendo uma linha do arquivo onde em cada posição
	 *            esta uma informação exemplo: I 0 0 3 --> vet[0]=I ; vet[1]=0
	 *            ; vet[2]=0 ; vet[3]=3
	 */
	public void Insere_Matriz(String[] vetpalavras) {
		int l = Integer.parseInt(vetpalavras[1]), c = Integer
				.parseInt(vetpalavras[2]), v = Integer.parseInt(vetpalavras[3]);
		No L1;// referencia para a linha da matriz
		No C1;// referencia para a coluna da matriz
		No novo = new No(v, l, c);// cria uma nova celula com os valores de
		// linha, coluna e conteudo da linha lida

		// Esta condiçao informa qual a matriz será usada
		if (controlamatriz == 1) {
			L1 = sentinela1;
			C1 = sentinela1;
		} else if (controlamatriz == 2) {
			L1 = sentinela2;
			C1 = sentinela2;
		} else {
			L1 = sentinela3;
			C1 = sentinela3;
		}

		// Procura a linha especifica e guarda sua posição
		while (L1.lin != novo.lin) {
			L1 = L1.inf;
		}

		// Procura a coluna especifica e guarda sua posição
		while (C1.col != novo.col) {
			C1 = C1.prox;
		}

		// ==== Linkar a Linha ====
		// verifica se a proxima celula é null, pois se for será a 1ª
		// inserção naquela linha respectivamente
		if (L1.prox == null) {
			novo.prox = L1.prox;
			L1.prox = novo;
		} // nao sendo vai caminhando para dentro da matriz ate chegar na
		// posi??o correta
		else {
			No pri1 = L1;// primeira celula
			No seg1 = L1.prox;// segunda celula

			// se a segunda celula for diferente de NULL e a coluna de onde eu
			// quero estar ainda
			// for maior do que a coluna de onde estou continuo caminhando ate
			// encontrar
			// a posição correta para a inserção
			while (seg1 != null && novo.col > seg1.col) {
				pri1 = pri1.prox;
				seg1 = seg1.prox;
			}

			// insere no final daquela lista
			if (seg1 == null) {
				novo.prox = pri1.prox;
				pri1.prox = novo;
				// } else if (seg1.prox == null && novo.col > seg1.col) {
				// novo.prox = seg1.prox;
				// seg1.prox = novo;
			} // insere entre duas celulas
			else if (novo.col < seg1.col) {
				pri1.prox = novo;
				novo.prox = seg1;
			}
		}

		// ==== Linkar a Coluna ====
		// verifica se a proxima celula é null, pois se for será a 1ª
		// inserção naquela coluna respectivamente
		if (C1.inf == null) {
			novo.inf = C1.inf;
			C1.inf = novo;
		} // nao sendo vai caminhando para dentro da matriz ate chegar na
		// posi??o correta
		else {
			No pri1 = C1;// primeira celula
			No seg1 = C1.inf;// segunda celula

			// se a segunda celula for diferente de NULL e a linha de onde eu
			// quero estar ainda
			// for maior do que a linha de onde estou continuo caminhando ate
			// encontrar
			// a posição correta para a inserção
			while (seg1 != null && novo.lin > seg1.lin) {
				pri1 = pri1.inf;
				seg1 = seg1.inf;
			}

			// insere no final da lista
			if (seg1 == null) {
				novo.inf = pri1.inf;
				pri1.inf = novo;
				// } else if (seg1.inf == null && novo.lin > seg1.lin) {
				// novo.inf = seg1.inf;
				// seg1.inf = novo;
			} // insere entre duas celulas
			else if (novo.lin < seg1.lin) {
				pri1.inf = novo;
				novo.inf = seg1;
			}
		}
	}// metodo InsereMatriz

	/**
	 * Metodo removeMatriz
	 * 
	 * Este metodo retira um elemento da matriz dado sua posição. Não é
	 * preciso falar qual o valor a ser tirado porem isso seria uma
	 * implementação interessante de se fazer.
	 * 
	 * @param vetpalavras
	 *            - vetor contendo uma linha do arquivo onde em cada posição
	 *            esta uma informação exemplo: R 0 0 --> vet[0]=R ; vet[1]=0 ;
	 *            vet[2]=0
	 */
	public void Remove_Matriz(String[] vetpalavras) {
		int l = Integer.parseInt(vetpalavras[1]), c = Integer
				.parseInt(vetpalavras[2]);

		No L1;// referencia para a linha da matriz
		No C1;// referencia para a coluna da matriz
		No novo = new No(l, c);// cria uma nova celula que sera usada como
		// objeto de comparação para excluir a celula
		// original

		// Esta condiçao informa qual a matriz será usada
		if (controlamatriz == 1) {
			L1 = sentinela1;
			C1 = sentinela1;
		} else {
			L1 = sentinela2;
			C1 = sentinela2;
		}

		// Procura a linha especifica e guarda sua posição
		while (L1.lin != novo.lin) {
			L1 = L1.inf;
		}

		// Procura a coluna especifica e guarda sua
		while (C1.col != novo.col) {
			C1 = C1.prox;
		}

		// ==== Verifica Linha ====
		// Cria-se duas referencias: 1 para a sentinela e a outra para a proxima
		No pri = L1;// primeira celula
		No seg = L1.prox;// segunda celula

		// Verifica se a segunda celula é diferente de null e se a coluna que
		// eu qero ainda é maior que a coluna
		// em que estou porque se for continuo caminhando naquela lista ate
		// encontrar a posção correta
		while (seg != null && novo.col > seg.col) {
			pri = pri.prox;
			seg = seg.prox;
		}

		// encontrei a posição
		// A celula que desejo remover esta no final da lista
		if (seg.prox == null && novo.col == seg.col) {
			pri.prox = seg.prox;
			seg.prox = null;
		} // encontrei a posição
		// a celula que desejo remover esta entre duas celulas
		else if (novo.col == seg.col) {
			pri.prox = seg.prox;
			seg.prox = null;
		}

		// ==== Verifica Coluna ====
		// Cria-se duas referencias: 1 para a sentinela e a outra para a abaixo
		pri = C1;// primeira celula
		seg = C1.inf;// segunda celula

		// Verifica se a segunda celula é diferente de null e se a linha que eu
		// qero ainda é maior que a linha
		// em que estou porque se for continuo caminhando naquela lista ate
		// encontrar a posção correta
		while (seg != null && novo.lin > seg.lin) {
			pri = pri.inf;
			seg = seg.inf;
		}

		// encontrei a posição
		// A celula que desejo remover esta no final da lista
		if (seg.inf == null && novo.lin == seg.lin) {
			pri.inf = seg.inf;
			seg.inf = null;
		} // encontrei a posição
		// a celula que desejo remover esta entre duas celulas
		else if (novo.lin == seg.lin) {
			pri.inf = seg.inf;
			seg.inf = null;
		}
	}// Metodo removeMatriz

	/**
	 * Metodo Tela
	 * 
	 * Este metodo é usado por um usuario, que nao tem acesso a metodos desta
	 * classe , para mostrar o conteudo das matrizes. Este metodo PUBLICO chama
	 * o PRIVADO Mostrar.
	 * 
	 * @param id_matriz
	 *            - identificador de qual matriz deve ser mostrada
	 */
	public void Tela(int id_matriz) {
		// Esta condiçao informa qual a matriz será usada
		if (id_matriz == 1) {
			System.out.println("\nMatriz1");
			Mostrar(1);
		} else if (id_matriz == 2) {
			System.out.println("\nMatriz2");
			Mostrar(2);
		}
		System.out.println("");
	}// metodo tela

	/**
	 * Metodo Mostrar
	 * 
	 * Este metodo mostra o conteudo da matriz atraves de sua identificação
	 * 
	 * @param id_matriz
	 *            - identificador de qual matriz deve ser mostrada
	 */
	private void Mostrar(int id_matriz) {
		No aux_linha = null, aux_coluna;
		// Esta condiçao informa qual a matriz será usada
		if (id_matriz == 1) {
			aux_linha = sentinela1.inf;
		} else {
			aux_linha = sentinela2.inf;
		}

		// Este while fixa a linha e percorre as colunas de 0 ate N-1 atraves
		// das celulas
		while (aux_linha != null) {
			aux_coluna = aux_linha.prox;
			while (aux_coluna != null) {
				System.out.println("[" + aux_coluna.lin + "] ["
						+ aux_coluna.col + "] = " + aux_coluna.valor);
				aux_coluna = aux_coluna.prox;
			}
			aux_linha = aux_linha.inf;
		}// while
	}// metodo Mostrar

	/**
	 * Metodo multiplicar
	 * 
	 * Este metodo pega as informacoes das duas matriz criadas anteriormente e
	 * faz a operação de multiplicacao de matriz
	 * 
	 * @throws IOException
	 * 
	 */
	public void Multiplicar() throws IOException {
		// -------------------------------------------------------------
		// Esta parte é suada na gravação do arquivo
		String pergunta = "";
		// o usuario escolher ou nao o nome do arquivo de saida
		pergunta = JOptionPane
				.showInputDialog("Deseja escolher um nome para o arquivo de saida ?\nSim - S\nNão - N");
		if (pergunta.equalsIgnoreCase("S")) {
			Ea = new Escrita_Arquivo(1);
		} else {
			Ea = new Escrita_Arquivo(2);
		}
		// -------------------------------------------------------------

		// incrementa o controlamatriz para indicar para o codigo que agora ele
		// esta trabalhando com a matriz 3, ou seja, a matriz de multiplicação
		controlamatriz++;
		// variavel que armzena as informações para gravar no arquivo
		String informacoes_arquivo = "";
		// contador que informa quando devo quebrar linha no arquivo
		int contador = 1;
		// variavel que ajuda o contador a se referenciar na hora da quebra da
		// linha
		int onde_quebrar = Integer
				.parseInt(vet_informacao_matriz_multiplicacao[2]);
		// Variaveis usadas para percorrer as listas e efetuar os calculos
		No aux2_linha = sentinela1.inf;
		No aux1_coluna = sentinela2.prox, aux2_coluna = sentinela2.prox;
		No iniciolinha = sentinela1.inf, iniciocoluna = sentinela2.prox;
		int conta = 0;

		while (aux2_linha != null && aux2_linha.prox != null) {
			while (aux2_coluna.inf != null) {
				// Na mesma linha anda para a proxima celula
				aux2_linha = aux2_linha.prox;
				// Na mesma coluna anda para a celula abaixo
				aux2_coluna = aux2_coluna.inf;
				// calcula o valor que devera ser inserido na matriz de //
				// multiplicacao
				conta += aux2_linha.valor * aux2_coluna.valor;
			}
			// clacula o que precisa para fazer a gravação no arquivo ficar de
			// acordo com as normas especificadas no trabalho
			informacoes_arquivo += conta + " ";
			if (contador % onde_quebrar == 0) {
				informacoes_arquivo += "\n";
				Ea.Acessar_Arquivo(informacoes_arquivo);
				informacoes_arquivo = "";
			}
			// Insere o valor no vetor de strings por causa do parametro do
			// metodo inserir que aceita somente vetor de string
			vet_informacao_matriz_multiplicacao[3] = conta + "";
			// Zera a veriavel para ela ser usada novamente
			conta = 0;
			// Aqui é feito o ajuste das variaveis para
			// que elas não fiquem repetindo as mesmas posicoes
			if (aux2_coluna.inf == null) {
				aux2_linha = iniciolinha;// volta
				aux2_coluna = aux1_coluna.prox;// volta e anda
				aux1_coluna = aux2_coluna;// anda
				if (aux2_coluna == null) {
					aux2_coluna = iniciocoluna;
					aux1_coluna = iniciocoluna;
					aux2_linha = iniciolinha.inf;
					iniciolinha = iniciolinha.inf;
				}
				// forço ele a sair pois ja encontrei as respostas
				if (aux2_linha == null) {
					aux2_linha = aux1_coluna = aux2_coluna = iniciolinha = iniciocoluna = null;
				}
			}
			contador++;
		}
		Ea.CloseArquivo();
	}
//Tem a classe No
//Tem a classe Ler_Arquivo
//Tem a classe Escrever_Arquivo

Formato Arquivo de entrada

M 3 4
I 0 0 1
I 0 1 2
I 0 3 4
I 1 1 6
I 1 3 8
I 2 1 10
I 2 3 12
R 0 0
M 4 3
I 3 2 14
I 0 1 2
I 1 0 4
I 1 2 6
I 2 1 8
I 3 0 10
R 3 2
I 3 2 12
Criado 12 de setembro de 2007
Ultima resposta 23 de mar. de 2010
Respostas 1
Participantes 1