我的目标是生成具有固定长度的迭代字母/数字字符串,例如:
aaaaaa
aaaaab
aaaaac
...
aaaaa9
aaaaba
...
999999
可以使用嵌套for循环轻松实现,如下面的代码:
public static void main(String[] strings) {
Object[] array = new Object[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
List<String> list = Lists.newArrayList();
int a, b, c, d, e, f;
for (a = 0; a < 35; a++) {
for (b = 0; b < 35; b++) {
for (c = 0; c < 35; c++) {
for (d = 0; d < 35; d++) {
for (e = 0; e < 35; e++) {
for (f = 0; f < 35; f++) {
list.add("" + array[a] + array[b] + array[c] + array[d] + array[e] + array[f]);
}
}
}
}
}
}
}
但最好知道如何重构它可以在多个线程中运行这样的代码,或者甚至已经存在一些库以生成这样的数字。
非常感谢任何帮助。
答案 0 :(得分:8)
您正在生成35 ^ 6 = 1838265625个值;所以你可以用一个for循环重写它:
for (int i = 0; i < 1838265625; ++i) {
int ii = i;
int f = ii % 35; ii /= 35;
int e = ii % 35; ii /= 35;
int d = ii % 35; ii /= 35;
// ...
int a = ii % 35;
list.add("" + array[a] + array[b] + array[c] + array[d] + array[e] + array[f]);
}
因此,要在多个线程中重写,只需在线程之间划分范围[0..1838265625)
,这样每个线程就会为该范围的一部分运行for循环,例如:线程1执行[0..1_000_000)
,线程2执行[1_000_000..2_000_000)
等。
您可能会发现使用ForkJoinPool
来管理范围的拆分和连接更容易,而不是尝试手动执行。
当然,我仍然在考虑Java 8之前的术语。您也可以使用流(如GhostCat建议):
IntStream.range(0, 1838265625).parallelStream()
.map(i -> {
int ii = i;
int f = ii % 35; ii /= 35;
int e = ii % 35; ii /= 35;
int d = ii % 35; ii /= 35;
// ...
int a = ii % 35;
return "" + array[a] + array[b] + array[c] + array[d] + array[e] + array[f]; })
.collect(someCollector);
答案 1 :(得分:1)
我没有50分可以评论,所以发帖作为答案。
为什么需要这么多嵌套循环? 2个循环就足够了。计算数组的长度,将其存储在length
像
for (i=0;i<length;i++)
{
for(i=0;i<6;i++)
{
//what to do
}
}
答案 2 :(得分:0)
我认为您的代码可以使用java8流转换为解决方案。然后你可以简单地从基于stream()的解决方案转到parallelStream()解决方案。
缺点是流只能使用引用类型/集合;因此,如果不使用原始字符数组,可能会导致性能下降。
答案 3 :(得分:0)
如果你想在六个地方获得35个字符的所有排列,我相信你会得到StackOverflowException,因为那将是一个包含1'838'265'625个条目的列表,每个条目至少12个字节是20GB的内存。
其次使用char数组,因为int有4个字节而char只有2个(unicode)。
最后在连接中,int将outbox转换为Integer并尝试转换为char,我认为你将获得该int的ASCII表示(例如,1是“标题的开头”,非打印字符)
如果你想要固定长度字的有界随机生成器,那么你可以使用
private static final String[] array = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x",
"y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
public List<String> randomWords(int numOfWords, int lengthOfWord){
List<String> list = new ArrayList<>();
for(int i = 0; i < numberOfWords; i++)
list.add(randomWord(lengthOfWord));
return list;
}
private String randomWord(int lengthOfWord){
Random rand = new Random();
StringBuilder sb = new StringBuilder();
for(int i = 0; i < lengthOfWord; i++){
sb.append(array[rand.nextInt(35)]);
}
return sb.toString();
}