使用java流的单词排列
我正在尝试生成所有可能的长度为0到4的单词,其中包含字母a到z和a到z。这就是我使用Java stream所得到的使用java流的单词排列,java,java-8,java-stream,Java,Java 8,Java Stream,我正在尝试生成所有可能的长度为0到4的单词,其中包含字母a到z和a到z。这就是我使用Java stream所得到的 static String[] letters = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""); letters[0] = ""; static final int CAPACITY = 1 + 52 + 52*52 + 52*52*52 + 5
static String[] letters
= " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
letters[0] = "";
static final int CAPACITY = 1 + 52 + 52*52 + 52*52*52 + 52*52*52*52;
static List<String> words
= Arrays.stream(LETTERS)
.flatMap(word -> Arrays.stream(LETTERS).map(word::concat))
.flatMap(word -> Arrays.stream(LETTERS).map(word::concat))
.flatMap(word -> Arrays.stream(LETTERS).map(word::concat))
.distinct()
.collect(Collectors.toCollection(() -> new ArrayList<>(CAPACITY)));
但是我想使用Java流来实现它
(编辑)
根据你的建议:
public static List<String> generateWords(int maxLength, String[]
letters) {
if (letters.length == 0)
return Arrays.asList("");
int capacity = IntStream.rangeClosed(0, maxLength)
.map(i -> (int) Math.pow(letters.length, i))
.sum();
return IntStream.range(0, capacity)
.mapToObj(i -> map(i, letters))
.collect(Collectors.toCollection(() -> new ArrayList<>(capacity)));
}
private static String map(int index, String[] letters) {
if(index == 0) return "";
return map((index - 1) / letters.length, letters)
+ letters[(index - 1) % letters.length];
}
publicstaticlist-generateWords(int-maxLength,String[]
(信件){
如果(字母长度==0)
返回数组。asList(“”);
int capacity=IntStream.rangeClosed(0,maxLength)
.map(i->(int)Math.pow(letters.length,i))
.sum();
返回IntStream.range(0,容量)
.mapToObj(i->map(i,字母))
.collect(收集器.toCollection(()->新阵列列表(容量));
}
私有静态字符串映射(int索引,字符串[]个字母){
如果(索引==0)返回“”;
返回映射((索引-1)/letters.length,letters)
+字母[(索引-1)%letters.length];
}
谢谢你提出的这个很酷的问题,真是个好问题
需要distinct的原因是空字符串,即长度小于4个字符的单词。例如,..a
、.a.
、.a.
和a.
都会导致a
,您需要使用distinct来删除它们。我们应该找到一种方法来解决这个问题,因为“不同”可能意味着大量的比较,这可能会对这些数字产生相当大的影响
防止重复并不难:不要在信件中添加“
。
看看您自己的方法,如果您只对实际字符进行流式处理,并且仅在每个平面图
之后添加”
,您就可以得到您所需要的:
Condsider letters = {a, b}, maxLength = 2
Start with Stream.of("")
1st flatMap: [a, b]
add "": [, a, b]
2nd flatMap: [a, b, aa, ab, ba, bb]
add "": [, a, b, aa, ab, ba, bb]
下面是一个很好的方法,可以做到这一点:
private static List<String> maxWords(int maxLength, String[] letters)
{
if (letters.length == 0)
{
return Arrays.asList("");
}
Stream<String> s = Stream.of("");
int[] capacity = { 1 };
for (int i = 0; i < maxLength; i++)
{
s = Stream.concat(Stream.of(""), s.flatMap(word -> Arrays.stream(letters).map(word::concat)));
capacity[0] = capacity[0] + (int) Math.pow(letters.length, i + 1);
}
return s.collect(Collectors.toCollection(() -> new ArrayList<>(capacity[0])));
}
私有静态列表maxWords(int-maxLength,String[]个字母)
{
如果(字母长度==0)
{
返回数组。asList(“”);
}
流s=流的长度(“”);
int[]容量={1};
对于(int i=0;iArrays.Stream(字母).map(word::concat));
容量[0]=容量[0]+(int)数学功率(字母长度,i+1);
}
返回s.collect(Collectors.toCollection(()->new ArrayList(容量[0]));
}
这个备选方案基于Aaron的想法,我更喜欢这个想法。我们首先从0到capacity-1进行枚举,然后将每个数字映射到其对应的字。如果您感兴趣,我强烈建议您观看(第17分钟)以获得解释
private static List<String> maxWords2(int maxLength, String[] letters)
{
if (letters.length == 0)
{
return Arrays.asList("");
}
int capacity = IntStream.rangeClosed(0, maxLength)
.map(length -> (int) Math.pow(letters.length, length))
.sum();
return IntStream.range(0, capacity).mapToObj(i -> {
StringBuilder s = new StringBuilder();
while (i > 0)
{
i--;
s.append(letters[i % letters.length]);
i /= letters.length;
}
return s.reverse().toString();
}).collect(Collectors.toCollection(() -> new ArrayList<>(capacity)));
}
私有静态列表maxWords2(int-maxLength,字符串[]个字母)
{
如果(字母长度==0)
{
返回数组。asList(“”);
}
int capacity=IntStream.rangeClosed(0,maxLength)
.map(长度->(int)数学功率(字母.长度,长度))
.sum();
返回IntStream.range(0,容量).mapToObj(i->{
StringBuilder s=新的StringBuilder();
而(i>0)
{
我--;
s、 追加(字母[i%字母.长度]);
i/=字母长度;
}
返回s.reverse().toString();
}).collect(收集器.toCollection(()->新阵列列表(容量));
}
谢谢你提出的这个很酷的问题,真是个好问题
需要distinct的原因是空字符串,即长度小于4个字符的单词。例如,..a
、.a.
、.a.
和a.
都会导致a
,您需要使用distinct来删除它们。我们应该找到一种方法来解决这个问题,因为“不同”可能意味着大量的比较,这可能会对这些数字产生相当大的影响
防止重复并不难:不要在信件中添加“
。
看看您自己的方法,如果您只对实际字符进行流式处理,并且仅在每个平面图
之后添加”
,您就可以得到您所需要的:
Condsider letters = {a, b}, maxLength = 2
Start with Stream.of("")
1st flatMap: [a, b]
add "": [, a, b]
2nd flatMap: [a, b, aa, ab, ba, bb]
add "": [, a, b, aa, ab, ba, bb]
下面是一个很好的方法,可以做到这一点:
private static List<String> maxWords(int maxLength, String[] letters)
{
if (letters.length == 0)
{
return Arrays.asList("");
}
Stream<String> s = Stream.of("");
int[] capacity = { 1 };
for (int i = 0; i < maxLength; i++)
{
s = Stream.concat(Stream.of(""), s.flatMap(word -> Arrays.stream(letters).map(word::concat)));
capacity[0] = capacity[0] + (int) Math.pow(letters.length, i + 1);
}
return s.collect(Collectors.toCollection(() -> new ArrayList<>(capacity[0])));
}
私有静态列表maxWords(int-maxLength,String[]个字母)
{
如果(字母长度==0)
{
返回数组。asList(“”);
}
流s=流的长度(“”);
int[]容量={1};
对于(int i=0;iArrays.Stream(字母).map(word::concat));
容量[0]=容量[0]+(int)数学功率(字母长度,i+1);
}
返回s.collect(Collectors.toCollection(()->new ArrayList(容量[0]));
}
这个备选方案基于Aaron的想法,我更喜欢这个想法。我们首先从0到capacity-1进行枚举,然后将每个数字映射到其对应的字。如果您感兴趣,我强烈建议您观看(第17分钟)以获得解释
private static List<String> maxWords2(int maxLength, String[] letters)
{
if (letters.length == 0)
{
return Arrays.asList("");
}
int capacity = IntStream.rangeClosed(0, maxLength)
.map(length -> (int) Math.pow(letters.length, length))
.sum();
return IntStream.range(0, capacity).mapToObj(i -> {
StringBuilder s = new StringBuilder();
while (i > 0)
{
i--;
s.append(letters[i % letters.length]);
i /= letters.length;
}
return s.reverse().toString();
}).collect(Collectors.toCollection(() -> new ArrayList<>(capacity)));
}
私有静态列表maxWords2(int-maxLength,字符串[]个字母)
{
如果(字母长度==0)
{
返回数组。asList(“”);
}
int capacity=IntStream.rangeClosed(0,maxLength)
.map(长度->(int)数学功率(字母.长度,长度))
.sum();
返回IntStream.range(0,容量).mapToObj(i->{
StringBuilder s=新的StringBuilder();
而(i>0)
{
我--;
s、 追加(字母[i%字母.长度]);
i/=字母长度;
}
返回s.reverse().toString();
}).collect(收集器.toCollection(()->新阵列列表(容量));
}
我参加聚会有点晚了,因为我几天前刚刚了解了Java 8 streams和Lambda。不管怎样,我看到了你的问题,决定试一试
我的解决方案涉及使用流管道和递归。我喜欢流的一个方面是可以将它们链接在一起。这就是递归调用它们来解决排列问题的想法的来源
希望大家喜欢它