繁体   English   中英

多线程while循环

[英]Multithreading while loop

所以伙计们,我有一个类似的循环

int counter=0;
ArrayList<String> array = new ArrayList<String>();
num=Math.pow(3,length);
while(counter != num)
{
    String temp = generateRandomStr(length);
    if(array.contains(temp)==false)
    {
        array.add(temp);
        counter++;
    }
}

为了解释,我想要一个 ArrayList,它具有给定长度和 3 个字母的所有可能字符串组合。

因此,如果length=11num=177147运行时间几乎是 11 分钟。 长度越大,运行时间至少需要半小时。

有没有办法多线程这个循环?

编辑:

我已经阅读了所有的回复,我感谢你们每一个人。 是的,我知道我的代码是垃圾,我会继续努力。 由于我是学生,我没有经验,但我会尽力提高

问题是您使用的是随机方法而不是系统方法。

没有什么可以阻止generateRandomStr一遍又一遍地生成相同的字符串。 这是浪费时间。

当你的算法接近解决方案时,它的性能会变得越来越差,因为你找到的字符串越多,你在已经知道的结果上浪费的时间就越多。

最明智的蛮力方法是按顺序尝试每个字符串

aaaa
aaab
aaac

好吧,您可以使用 fork join 框架并执行以下操作:

import java.util.*;
import java.util.concurrent.*;

class Solver extends RecursiveTask<List<String>> {
    char characters[] = {'a','b','c'};
    int length;
    int idx;
    StringBuilder current;

    public Solver(int idx, int length, StringBuilder current) {
        this.length = length;
        this.idx = idx;
        this.current = current;
    }

    @Override
    public List<String> compute() {
        if(idx == length - 1){
            List<String> finalList = new ArrayList<>();
            finalList.add(current.toString());
            return finalList;
        }
        List<Solver> recursiveTasks = new ArrayList<>();
        for(int i = 0; i < 3; ++i) {
            current.append(characters[i]);
            recursiveTasks.add(new Solver(idx+1, length, new StringBuilder(current.toString())));
            current.deleteCharAt(idx);
        }
        recursiveTasks.forEach((task) -> task.fork());
        List<String> finalList = new ArrayList<>();
        recursiveTasks.forEach((task) -> finalList.addAll(task.join()));
        return finalList;
    }
}

public class Main
{
    public static void main(String[] args) {
        int length = 11;
        ForkJoinTask<List<String>> task = new Solver(0, length, new StringBuilder(""));
        new ForkJoinPool(4).invoke(task);
    }
}

在我看来,这比简单的递归实现更密集 memory。 对于长度 = 11,它就像微风一样工作。 只是要注意这个算法本质上是指数的,所以不要指望它适用于大量数字。 但是你想要一个递归实现。 好吧,就在这里

是的。 正如其他人所说,这是算法。 这将在不到 20 毫秒的时间内生成 177147 个长度为 11 的字符串的列表:

List<String> array = generate(11, "abc");

 private static List<String> generate(int length, String chars) {
     List<String> list = new ArrayList<>();
     generate(new char[length], 0, length, chars.toCharArray(), list);
     return list;
 }

 private static void generate(char[] buf, int i, int len, char[] chars, List<String> list) {
     if (i >= len) {
         list.add(new String(buf));
     } else {
         for (int k = 0; k < chars.length; ++k) {
             buf[i] = chars[k];
             generate(buf, i+1, len, chars, list);
         }
     }
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM