生成所有可能的6个长度字符串和写入文件的最快方法是什么?

时间:2016-04-28 18:28:22

标签: java performance

我想生成所有可能的6个长度字符串 我需要这种格式: aaa000 aaa001 ...

这是我的代码:

private List<String> licensePlateList = new ArrayList<>();
private List<String> numberList = new ArrayList<>();
private List<String> letterList = new ArrayList<>();

public static void main(String[] args) {
    Main app = new Main();
    long start = System.nanoTime();

    app.generateNumbers();
    int letters = 26;
    int count = 3;
    final int combinations = (int) Math.pow(letters, count);
    StringBuilder sb = new StringBuilder(count);
    for (int i = 0; i < combinations; i++) {
        sb.setLength(0);
        for (int j = 0, i2 = i; j < count; j++, i2 /= letters)
            sb.insert(0, (char) ('a' + i2 % letters));
        app.letterList.add(sb.toString());
    }

    long time = System.nanoTime() - start;
    System.out.printf("Took %.3f seconds to generate", time / 1e9);

    for (int i=0;i<app.letterList.size();i++){
        for (int j=0;j<app.numberList.size();j++){
            String licensePlate = app.letterList.get(i)+app.numberList.get(j);
            try(FileWriter fw = new FileWriter("licensePlate2.txt", true);
                BufferedWriter bw = new BufferedWriter(fw);
                PrintWriter out = new PrintWriter(bw))
            {
                out.println(licensePlate);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    time = System.nanoTime() - start;
    System.out.printf("Took %.3f seconds to generate %,d combinations%n", time / 1e9, app.licensePlateList.size());
}

private void generateNumbers(){
    for (int i=0;i<1000;i++){
        numberList.add(String.format("%03d", i));
    }
}
}

我在generateNumbers()方法中生成所有可能的数字。在生成数字后的main()方法中,我将所有可能的3个长度字符串生成到letterList中。 在我用数字映射每个字符串并写出文件后。

但它真的很慢。你知道更快的方式吗?

2 个答案:

答案 0 :(得分:2)

您的算法正在为每个牌照打开一个新作家。

相反,打开一个作家并将其全部写入:

try(FileWriter fw = new FileWriter("licensePlate2.txt", true);
    BufferedWriter bw = new BufferedWriter(fw);
    PrintWriter out = new PrintWriter(bw)) {
    for (String letters : app.letterList) {
        for (String numbers : app.numberList) {
            out.print(letters);
            out.println(numbers);
        }
    }
} catch (IOException e) {
    e.printStackTrace();
}

请注意此代码如何通过单独编写每个字符串来避免为整个许可证编号创建中间字符串。

还要注意每个&#34;使用&#34;环路。

答案 1 :(得分:2)

$ java Test c:/temp/testOutput
Generated 17576000 combinations in 1.456 seconds

以下是代码:

import java.io.*;

public class Test {

    public static void main(String[] args) throws Exception {
        char sb[] = new char[7];
        sb[6] = '\n';

        int count = 0;
        long startTime = System.currentTimeMillis();

        BufferedWriter out = new BufferedWriter(new FileWriter(args[0]));

        for (char a = 'a'; a <= 'z'; a++) {
            sb[0] = a;
            for (char b = 'a'; b <= 'z'; b++) {
                sb[1] = b;
                for (char c = 'a'; c <= 'z'; c++) {
                    sb[2] = c;
                    for (char d = '0'; d <= '9'; d++) {
                        sb[3] = d;
                        for (char e = '0'; e <= '9'; e++) {
                            sb[4] = e;
                            for (char f = '0'; f <= '9'; f++) {
                                sb[5] = f;
                                out.write(sb);
                                count++;
                            }
                        }
                    }
                }
            }
        }
        out.close();
        long endTime = System.currentTimeMillis();
        System.err.println("Generated " + count + " combinations in " + (endTime - startTime) / 1000.0 + " seconds");
    }
}

请注意,在Linux上使用/ dev / null运行相同的代码,Windows上的NUL生成的时间基本相同(减少0.2秒),因此磁盘IO成本几乎可以分摊。每组合成本可降至1.456 / 17576000 = 0.082微秒。我相信C ++可以做得更好。

更新:将BufferedWriter更改为BufferedOutputStream并将byte []替换为char []会将时间减少到.908秒。这是因为编写代码不再需要将Java的UTF-16编码转换为实际文件中使用的UTF-8。