1

現在出回っている多くの人と同様のスレッドを作成したことをお詫びしますが、主にいくつかの方法についての洞察を得たいと思いました。

文字列のリストがあります(1つまたは1000を超える可能性があります)形式= XXX-XXXXX-XXここで、それぞれは英数字です

同じリストがある場合に再現できる一意の文字列(現在は18の長さですが、ファイルの長さやパスの長さを最大化しないようにすると、おそらくもっと長くなる可能性があります)を生成しようとしています。順序は関係ありません。順序を制限する方が簡単な場合も興味があるかもしれませんが。

私の現在のJavaコードは次のとおりです(今日失敗したので、なぜ私はここにいます):


public String createOutputFileName(ArrayList alInput, EnumFPFunction efpf, boolean pHeaders) {
    /* create file name based on input list */
    String sFileName = "";
    long partNum = 0;

    for (String sGPN : alInput) {
        sGPN = sGPN.replaceAll("-", ""); //remove dashes
        partNum += Long.parseLong(sGPN, 36);    //(base 36)
    }
    sFileName = Long.toString(partNum);
    if (sFileName.length() > 19) {
        sFileName.substring(0, 18); //Max length of 19
    }
    return alInput;
}

したがって、明らかにそれらを追加するだけではうまくいきませんでした(また、最初の18桁ではなく、最後の18桁を取る必要があると思います)

うまくいく良い方法(おそらくCRC関連)はありますか?

キーの作成を支援するために:最初の3文字はほとんどの場合数値であり、おそらく多くの重複があります(100のうち、10の異なる開始番号しかない場合があります)これらの文字は許可されていません-I、O文字はありません次に、最後の2つのalphacharサブセットの数値。

4

2 に答える 2

1

システム時刻を使用します。Javaでそれを行う方法は次のとおりです。

public String createOutputFileName() {
    long mills = System.currentTimeMillis();
    long nanos = System.nanoTime();
    return mills + " " + nanos;
}

アイテムとその部品番号に関する情報を追加したい場合は、もちろん可能です!

======== 編集:「バッチオブジェクトとはどういう意味ですか?」 =========

class Batch {

    ArrayList<Item> itemsToProcess;
    String inputFilename; // input to external process
    boolean processingFinished;

    public Batch(ArrayList<Item> itemsToProcess) {
        this.itemsToProcess = itemsToProcess;
        inputFilename = null;
        processingFinished = false;
    }

    public void processWithExternal() {
        if(inputFilename != null || processingFinished) {
            throw new IllegalStateException("Cannot initiate process more than once!");
        }
        String base = System.currentTimeMillis() + " " + System.nanoTime();
        this.inputFilename = base + "_input";

        writeItemsToFile();

        // however you build your process, do it here
        Process p = new ProcessBuilder("myProcess","myargs", inputFilename);

        p.start();
        p.waitFor();
        processingFinished = true;
    }

    private void writeItemsToFile() {
        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(inputFilename)));
        int flushcount = 0;
        for(Item item : itemsToProcess) {
            String output = item.getFileRepresentation();
            out.println(output);
            if(++flushcount % 10 == 0) out.flush();
        }
        out.flush();
        out.close();
    }

}
于 2011-02-23T23:13:57.577 に答える
0

GlowCoder の応答に加えて、うまくいく別の「まともなもの」を考えました。

base 36 でリストを追加するだけでなく、同じリストに対して 2 つの別々のことを行います。

この場合、負の数や 10 進数を使用する方法がないため、すべての数値を加算し、すべての数値を個別に乗算し、これらの base36 数値文字列を連結することも悪い方法ではありません。

私の場合、足した数の下 9 桁と掛けた数の下 9 桁を取ります。これにより、以前のエラーが解消され、非常に堅牢になります。オーバーフローが発生し始めるとエラーが発生する可能性はありますが、この場合も機能する可能性があります。許容される文字列の長さを拡張すると、より堅牢になります。

サンプルコード:


    public String createOutputFileName(ArrayList alInput, EnumFPFunction efpf, boolean pHeaders) {
        /* create file name based on input list */
        String sFileName1 = "";
        String sFileName2 = "";

        long partNum1 = 0;  // Starting point for addition
        long partNum2 = 1;  // Starting point for multiplication

        for (String sGPN : alInput) {
            //remove dashes
            sGPN = sGPN.replaceAll("-", "");
            partNum1 += Long.parseLong(sGPN, 36);    //(base 36)
            partNum2 *= Long.parseLong(sGPN, 36);    //(base 36)
        }

        // Initial strings
        sFileName1 = "000000000" + Long.toString(partNum1, 36);   // base 36
        sFileName2 = "000000000" + Long.toString(partNum2, 36);   // base 36

        // Cropped strings
        sFileName1 = sFileName1.substring(sFileName1.length()-9, sFileName1.length());
        sFileName2 = sFileName2.substring(sFileName2.length()-9, sFileName2.length());

        return sFileName1 + sFileName2;
    }
于 2011-02-25T14:56:05.207 に答える