3

対処する URL がたくさんあります。私はそれらの約20'000'000をハッシュセットに保存します。それはいくつかのメモリの問題を引き起こします。

圧縮文字列クラスを作成しようとしました:

import java.io.*;//file writer
import java.util.*;
import java.util.zip.*;

class CompressedString2 implements Serializable{
    private int originalSize;
    private byte[] cstring;



    public CompressedString2 (){
        compress("");
    }


    public CompressedString2 (String string){
        compress(string);
    }


    public void compress(String str){
        try {
            byte[] bytes = str.getBytes("UTF-8");
            originalSize = bytes.length;

            ByteArrayOutputStream deflatedBytes = new ByteArrayOutputStream();
            DeflaterOutputStream dos = new DeflaterOutputStream(deflatedBytes,new Deflater(Deflater.DEFAULT_COMPRESSION));
            dos.write(bytes);
            dos.finish();
            cstring=deflatedBytes.toByteArray();
        }catch(Exception e){e.printStackTrace();}

    }


    public String decompress() throws Exception{
        String result="";
        try{
            ByteArrayOutputStream deflatedBytes=new ByteArrayOutputStream();
            deflatedBytes.write(cstring);
            deflatedBytes.close();


            InflaterInputStream iis = new InflaterInputStream(new ByteArrayInputStream(deflatedBytes.toByteArray()));
            byte[] inflatedBytes = new byte[originalSize];
            iis.read(inflatedBytes);
            result= new String(inflatedBytes, "UTF-8");
        }catch(Exception e){e.printStackTrace();}
        return result;
    }
}

しかし、実際には、次のようなものでそれらを保存すると:

HashSet<String> urlStr=new HashSet<String>();
HashSet<CompressedString> urlComp=new HashSet<CompressedString>();


        String filePath=new String();

            filePath=args[0];

        int num=0;

        try{
            BufferedReader br = new BufferedReader(new FileReader(filePath));

            String line = br.readLine();
            while (line != null) {

                num++;
                urlStr.add(line);
                urlComp.add(new CompressedString(line));

            line = br.readLine();
            }
        } catch(Exception e){
        System.out.println("fehler..:");
            e.printStackTrace();
        }

ObjectOutputStream oos1 = new ObjectOutputStream(new FileOutputStream("testDeflator_rawurls.obj"));
oos1.writeObject(urlStr);
ObjectOutputStream oos4 = new ObjectOutputStream(new FileOutputStream("testDeflator_compressed2.obj"));
oos4.writeObject(urlComp);

「圧縮された」URLはさらに大きくなります...

URLを正常に圧縮する方法を知っている人はいますか?

4

9 に答える 9

5

セットに含まれている場合は、追加/削除/検索するだけです。これらの操作を「キャラクター フォレスト」で行うこともでき、よりコンパクトな表現になる可能性があります。それぞれが 1 つの文字を保持し、互いにリンクされているノードのツリーを考えています。フォレストのルートには、「h」、「f」、およびその他のいくつかが含まれます。「h」ノードの下には「t」ノード、その下に別の「t」、その下に「p」などがあります。「f」ノードには「t」と「i」の子があります。最終的に木は枝分かれしますが、根の近くに多くの共有がある可能性があります. 次に、森を歩いて、そこに URL があるかどうかを確認します。

ノードには、セット内の URL の 1 つがそこで終了することを示すブール値メンバー、文字を保持するメンバー、および他のノードへのリンクの配列が必要になると思います。

于 2012-04-13T13:16:50.250 に答える
1

別のアプローチを検討しましたか?ハッシュセット内の2,000万の文字列はたくさんあります。それらをデータベースに保存し、そこから処理できますか?

于 2012-04-13T14:12:24.723 に答える
0

たとえば、100 個のリンクを (特殊な文字で区切って) 連結し、それらを 1 つの CompressedString に圧縮しようとするのはどうですか? 圧縮を効率的に行うには、最小の長さが必要になる場合があります。CompressedString クラスは、コレクション内の 100 個の文字列を復元できます。

于 2012-04-13T14:19:43.973 に答える
0

ただし、一般に、圧縮がうまく機能するには、文字列のパターンに基づいて機能するため、文字列を長くする必要があります。

于 2012-04-13T13:20:09.577 に答える
0

たとえば、多くの URL に共通のベースがある場合は、各文字列の最初の部分が 1 回表現されるようにRopes (プロジェクト ページhttp://www.mysite.com/) の使用を検討する必要があります。

このウィキペディアのページも参照してください

于 2012-04-13T13:38:55.353 に答える
0

短い文字列は、圧縮されていない文字列よりも小さく圧縮されない場合があります。-XX:+UseCompressedStringJava 6 の一部のバージョンでデフォルトでオンになっているものを試しましたか。

于 2012-04-13T13:28:01.343 に答える
0

一度に n 個の URL を圧縮できます。n は 10 から 100 の可能性があります。これにより、コンプレッサーは、文字列の繰り返しや歪んだ文字の確率分布を扱うことができます。欠点は、アクセスごとに数十から数百の URL を解凍する必要があることです。したがって、それを実装したら、メモリ使用量と速度の間でトレードオフするように n を変化させ、好みの妥協点を選択します。

于 2012-04-13T13:37:06.770 に答える
0

tinyurl を使用して長さを短くしてから保存できます。ここで
小さな URL への Java ユーティリティ クラスを見つけることができます。

于 2012-04-13T13:52:29.890 に答える