Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
改进Java代码性能的建议_Java_Algorithm_Combinations - Fatal编程技术网

改进Java代码性能的建议

改进Java代码性能的建议,java,algorithm,combinations,Java,Algorithm,Combinations,你好,我这么做只是为了好玩,我想知道是否有更有效/更快的方法来做这件事。对给定的数字和字母列表进行所有可能的组合,然后将它们打印到文本文件中。我目前有这个,并寻求建议 import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; public class combos { public static void main(String[] args){ char[] alph

你好,我这么做只是为了好玩,我想知道是否有更有效/更快的方法来做这件事。对给定的数字和字母列表进行所有可能的组合,然后将它们打印到文本文件中。我目前有这个,并寻求建议

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class combos {

  public static void main(String[] args){

     char[] alphabet = new char[] {'0','1','2','3','4','a','b','c','d','e'};

     StringExcersise.possibleStrings(5, alphabet,"");
  }
  } class StringExcersise {
     public static void possibleStrings(int maxLength, char[] alphabet, String curr){

        if(curr.length() == maxLength) {
          try (PrintWriter out = new PrintWriter(new FileWriter("./Combos.txt", true))) {
          out.println(curr);
          }catch (IOException e) {
          System.err.println(e);}

        } else {
          for(int i = 0; i < alphabet.length; i++) {
              String oldCurr = curr;
              curr += alphabet[i];
              possibleStrings(maxLength,alphabet,curr);
              curr = oldCurr;
            }
        }
    }
}

目前运行大约需要26秒。

最后写入文件并用尾部递归替换递归将时间缩短到不到1秒:

public static void main(String[] args)
{
    char[] alphabet = new char[]{'0', '1', '2', '3', '4', 'a', 'b', 'c', 'd', 'e'};

    Set<String> permutations = new HashSet<>();
    possibleStrings(5, alphabet, "", permutations);

    try (PrintWriter out = new PrintWriter(new FileWriter("./Combos.txt", true)))
    {
        out.println(permutations);
    }
    catch (IOException e)
    {
        System.err.println(e);
    }
}

public static void possibleStrings(int maxLength, char[] alphabet, String curr, Set<String> permutations)
{
    if (curr.length() == maxLength)
    {
        permutations.add(curr);
    }
    else
    {
        for (char anAlphabet : alphabet)
        {
            possibleStrings(maxLength, alphabet, curr + anAlphabet, permutations);
        }
    }
}

最大的性能瓶颈是IO。每次打开/关闭文件都非常昂贵。我建议你只打开一个。此外,您不需要首先创建集合,因为随着集合的增长,这会变得非常昂贵,只需在计算结果时将结果写入缓冲文件即可

通过构建char[]而不是字符串并打印char[],可以获得相对较小的改进

class StringExercise {
    static void possibleStrings(char[] alphabet, PrintWriter pw, char[] curr, int index) {
        if (index == curr.length) {
            pw.println(curr);
            return;
        }
        for (char c : alphabet) {
            curr[index] = c;
            possibleStrings(alphabet, pw, curr, index + 1);
        }
    }
}

public class Combos {
    public static void main(String[] args) throws FileNotFoundException {
        long start = System.currentTimeMillis();
        try (PrintWriter pw = new PrintWriter("combos.txt")) {
            StringExercise.possibleStrings("01234abcde".toCharArray(), pw, new char[5], 0);
        }
        System.out.printf("Took %.3f seconds to run%n", (System.currentTimeMillis()-start)/1e3);
    }
}
印刷品

Took 0.030 seconds to run

我检查它是否生成了预期的输出。

只是一个想法,但是为什么不将所有可能的值保存在一个静态列表中,并在文件中写入一次,而不是每次都对所有可能的值执行一次呢。I/O操作的成本很高。如果是出于其他目的,则可能会出现这种情况。每次运行它时,我都会使用不同的数字和字母列表。是否有方法使每组数字和字母在输出文件中的新行上?我想您可以在每个字符串值之后追加\n,当它写入文件时,它们将在新行上。