Substituição de padrões

Bom, estou começando em Java e terei que desenvolver algo utilizando esse tipo de substituição de padrões que é um método de compressão de dados, porém não encontrei em nenhum lugar esse algoritmo. Alguém pode por favor me dar uma ajuda.
Obrigado.

Cara, sua pergunta está muito vaga. Eu quero te ajudar mas preciso de um pouco mais de detalhes.

Basicamente preciso implementar esse algoritmo de Substituição de padrões em Java de compressão de dados, não consegui achar muita coisa sobre esse algoritmo ainda e estou precisando aprender.

Acho que eu entendi, você quer fazer um banco de dados com objetos comprimidos? Se sim, você pode dar uma estudada na interface Serializable. Agora com relação a “Substituição de padrões em Java” eu não entendi. Você quer substituir o que? Os objetos comprimidos que foram salvos no banco de dados?

Seria mais básico, tipo em um arquivo de texto mesmo e não teria necessidade de um banco

Em português talvez seja mais difícil achar mesmo. Em inglês, dê uma olhada em http://www.stoimen.com/blog/2012/01/23/computer-algorithms-data-compression-with-diagram-encoding-and-pattern-substitution/

Abraço.

Seria exatamente isso TerraSkilll, só que seria em Java. Seria possível algo assim em Java?

Pelo que compreendi, você quer fazer algo semelhante ao Winrar.
Não sei como ele funciona, mas algo semelhante seria mapear todas as palavras e números e associar a elas um valor, preferencialmente numérico.
Ex.:
Maria é bonita, mas Maria é complicada.
Comprimindo a frase:
iniciando o mapeamento:
Maria = 1
é = 2
bonita = 3
, = 4
mas = 5
complicada = 6
quebra de linha = -1
fim do mapeamento, devendo ser observado que as informações acima fazem parte do documento, caso contrário, você vai comprimir e não vai reescrever depois.
Comprimindo a informação teríamos: [1 2 3 4 5 1 2 6 -1]

Sim e não é difícil de fazer, na verdade, parece fácil.
Há muitas formas de implementar isto.
Sugetão:
1 - usar a classe Set para remover as strings repetidas, depois:
II - usar a classe Map<Integer, String> e adicionar as chaves do Set uma a uma, sendo necessário um contador pois o map usa como chave, neste caso, um valor inteiro, que ficará associado à String.
Com o mapa construido, você o percorre pegando os valores e substituindo estes no documento, utilizando a chave numérica associada no map.
Lembre de escrever o mapa no documento também.
Partindo daí, fica mais simples fazer o resto, pois ainda vai sobrar outras coisas pra fazer, mas são implementações sem complicação.

A codificação a seguir é bem simples e pode ser usada para ler as informações de um bloco de notas.

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;

public class PraQWinrarXD {

    public static void main(String[] args) {
        comprimir(abrirArquivo());
    }

    private static File abrirArquivo() {
        JFileChooser jfc = new JFileChooser();
        return jfc.showOpenDialog(jfc) == JFileChooser.APPROVE_OPTION ? jfc.getSelectedFile() : null;
    }

    private static void comprimir(File arquivo) {
        //Set para remover valores repetidos
        Set<String> valores = new TreeSet<>();
        //Map para catalogar as strings
        Map<Integer, String> mapa = new TreeMap<>();
        //Array multifuncional, armazena dados podendo "comprimir" e "expandir" a informação
        ArrayList<String> comprimir = new ArrayList<>();
        
        mapa.put(-1, "\n");//catalogando a quebra de linha
        
        if (arquivo != null) {
            try {
                BufferedReader ler = Files.newBufferedReader(arquivo.toPath(), StandardCharsets.UTF_8);
                String linha;
                while ((linha = ler.readLine()) != null) {
                    for (String string : linha.split(" ")) {
                        valores.add(string);
                        comprimir.add(string);
                    }
                    comprimir.add("\n");//inserindo a quebra de linha
                }
            } catch (IOException ex) {
                Logger.getLogger(PraQWinrarXD.class.getName()).log(Level.SEVERE, null, ex);
            }
            int contador = 0;
            //Catalogando o restante das informações
            for (String valor : valores) {
                mapa.put(contador++, valor);
            }
            //Comprimindo a informação
            ArrayList<Integer> controle = new ArrayList<>();
            mapa.keySet().forEach((chave) -> {
                for (int i = 0; i < comprimir.size(); i++) {
                    if (!controle.contains(i)) {
                        if (comprimir.get(i).equals(mapa.get(chave))) {
                            comprimir.set(i, chave + "");
                            controle.add(i);
                        }
                    }
                }
            });

            System.out.println("===========CODIFICADO===============\n");
            comprimir.forEach(linha -> System.out.print(linha + (!linha.equals("-1") ? " " : "\n")));

            controle.clear();

            System.out.println("\n===========DECODIFICADO=============\n");
            //Traduzindo a informação
            for (int i = 0; i < comprimir.size(); i++) {
                comprimir.set(i, mapa.get(Integer.parseInt(comprimir.get(i))));
            }
            comprimir.forEach(linha -> System.out.print(linha + (!linha.equals("\n") ? " " : "")));
        }
    }
}

Para ser mais sofisticado tem que usar regex, entretanto, terá que remover e catalogar caracteres especiais antes, ou então vai ter que fazer alguns tratamentos como PatternSyntaxException e outros.

Exemplo de processamento:


Obs.: quando for salvar, é necessário incluir em uma área do documento as informações constantes no map, para fins de recupera-la futuramente.

1 curtida

Esta funcionando normalmente seu código? to tentando testar aqui e deu um erro.

Veja se esse vídeo te ajuda:

https://www.youtube.com/watch?v=ajncQV0z3qY

Gostaria de saber se esse método de compressão de “Substituição de Padrões” é eficiente para arquivos binários (fotos, vídeos, etc.) ou se ele só vai funcionar bem com arquivos de texto mesmo.

Ele só funciona para arquivos de texto mesmo.

Resumo: a codificação é um exemplo do funcionamento e foi projetada apenas para bloco de notas.
Uma implementação para qualquer tipo de arquivo demanda conhecimento que não disponho no momento, entretanto, a lógica é a mesma e a sofisticação depende da utilização de expressões regulares.
O que eu procuraria fazer: ver como ler os bytes de um arquivo qualquer, procurar identificar os trechos que corresponderiam a espaço e quebra de linha, catalogar e … a lógica é a mesma, entretanto, ao invés de strings o mapa guardaria bytes que estariam associados a um número.
Vc pode fazer isto perfeitamente em java com classes que manipulam stream, entretanto, como disse, desconheço todo o necessário no momento.
Té +;