我试图用字母a到z和A到Z来生成长度为0到4的所有可能的单词。这就是我使用Java流的方法
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)));
还有其他解决方案,我不必使用distinct()
吗?我知道我可以这样做:
String[] letters
= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
List<String> words = new ArrayList<>();
words.add("");
for(String letter1 : letters) {
words.add(letter1);
for(String letter2 : letters) {
words.add(letter1 + letter2)
for(String letter3 : letters) {
words.add(letter1 + letter2 + letter3);
for(String letter4 : letters) {
words.add(letter1 + letter2 + letter3 + letter4);
}
}
}
}
但我想用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];
}
答案 0 :(得分:1)
感谢这个很酷的问题,非常好!
您需要distinct的原因是空字符串,即长度小于4个字符的单词。例如,.a..
,a...
,a
和""
都会生成""
,您需要使用distinct来删除它们。我们应该找到解决方法,因为明显可能意味着很多的比较,这可能会对这些数字产生相当大的影响。
防止创建重复项并不困难:不要在信件中添加flatMap
。
查看您自己的方法,如果您只对实际字符进行流式处理,并且仅在每个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])));
}
,那么您将获得所需内容:
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)));
}
这是一个很好的方法:
{{1}}
此替代方案基于Aaron的想法,我更喜欢它。我们首先从0枚举到capacity-1,然后将每个数字映射到其对应的单词。如果您有兴趣,我强烈建议您观看this video about the Library of Babel(从第17分钟开始)获取解释。
{{1}}
答案 1 :(得分:0)
我参加聚会有点晚了,因为几天前我刚刚了解了 Java 8 流和 lambda。不管怎样,我看到你的问题,我决定试一试。
我的解决方案涉及将流流水线与递归结合使用。我喜欢流的一个方面是您可以将它们链接在一起。这就是递归调用它们来解决排列问题的想法的来源。
希望你们喜欢它,并可以给我一些改进方法的想法。
编辑:感谢匿名用户提出的改进建议。现在考虑 r = 1。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class RecursivePermutation {
// Returns a stream of permutations of c.size()
// elements taken r at a time without repetition.
// Example: If C={1,2} and r=2
// Output: {(1,2), (2,1)}
// This recursive function uses the chain property of streams
public static <T> Stream<List<T>> permutations(List<T> c, int r){
if (r==1){
return c.stream()
.map(e -> Arrays.asList(e));
} else
if (r==2){
return c.stream()
.flatMap(
e1 -> c.stream() // e1: refers to an element of c
.filter(e2 -> !e1.equals(e2)) // e2: refers to an element of c
.map(e2 -> Arrays.asList(e1, e2))
);
} else {
return permutations(c, r-1)
.flatMap(
l -> c.stream()
.filter( e -> l.contains(e) == false)
.map(e -> {
List<T> out = new ArrayList<>();
out.addAll(l);
out.add(e);
return out;}
)
);
}
}
public static void main(String[] args) {
// Name Permutations
List<String> stringList = Arrays.asList("Joe", "Ana", "Pete", "Mark", "Lucy");
List<List<String>> sp =
permutations(stringList, 2).collect(Collectors.toList());
System.out.println(sp);
// Integers Permutations
List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7));
List<List<Integer>> np =
permutations(numbers, 3).collect(Collectors.toList());
System.out.println(np);
}
}
运行此代码将为您提供以下输出:
[[Joe, Ana], [Joe, Pete], [Joe, Mark], [Joe, Lucy], [Ana, Joe], [Ana, Pete], [Ana, Mark], [Ana, Lucy], [Pete, Joe], [Pete, Ana], [Pete, Mark], [Pete, Lucy], [Mark, Joe], [Mark, Ana], [Mark, Pete], [Mark, Lucy], [Lucy, Joe], [Lucy, Ana], [Lucy, Pete], [Lucy, Mark]]
[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 2, 6], [1, 2, 7], [1, 3, 2], [1, 3, 4], [1, 3, 5], [1, 3, 6], [1, 3, 7], [1, 4, 2], [1, 4, 3], [1, 4, 5], [1, 4, 6], [1, 4, 7], [1, 5, 2], [1, 5, 3], [1, 5, 4], [1, 5, 6], [1, 5, 7], [1, 6, 2], [1, 6, 3], [1, 6, 4], [1, 6, 5], [1, 6, 7], [1, 7, 2], [1, 7, 3], [1, 7, 4], [1, 7, 5], [1, 7, 6], [2, 1, 3], [2, 1, 4], [2, 1, 5], [2, 1, 6], [2, 1, 7], [2, 3, 1], [2, 3, 4], [2, 3, 5], [2, 3, 6], [2, 3, 7], [2, 4, 1], [2, 4, 3], [2, 4, 5], [2, 4, 6], [2, 4, 7], [2, 5, 1], [2, 5, 3], [2, 5, 4], [2, 5, 6], [2, 5, 7], [2, 6, 1], [2, 6, 3], [2, 6, 4], [2, 6, 5], [2, 6, 7], [2, 7, 1], [2, 7, 3], [2, 7, 4], [2, 7, 5], [2, 7, 6], [3, 1, 2], [3, 1, 4], [3, 1, 5], [3, 1, 6], [3, 1, 7], [3, 2, 1], [3, 2, 4], [3, 2, 5], [3, 2, 6], [3, 2, 7], [3, 4, 1], [3, 4, 2], [3, 4, 5], [3, 4, 6], [3, 4, 7], [3, 5, 1], [3, 5, 2], [3, 5, 4], [3, 5, 6], [3, 5, 7], [3, 6, 1], [3, 6, 2], [3, 6, 4], [3, 6, 5], [3, 6, 7], [3, 7, 1], [3, 7, 2], [3, 7, 4], [3, 7, 5], [3, 7, 6], [4, 1, 2], [4, 1, 3], [4, 1, 5], [4, 1, 6], [4, 1, 7], [4, 2, 1], [4, 2, 3], [4, 2, 5], [4, 2, 6], [4, 2, 7], [4, 3, 1], [4, 3, 2], [4, 3, 5], [4, 3, 6], [4, 3, 7], [4, 5, 1], [4, 5, 2], [4, 5, 3], [4, 5, 6], [4, 5, 7], [4, 6, 1], [4, 6, 2], [4, 6, 3], [4, 6, 5], [4, 6, 7], [4, 7, 1], [4, 7, 2], [4, 7, 3], [4, 7, 5], [4, 7, 6], [5, 1, 2], [5, 1, 3], [5, 1, 4], [5, 1, 6], [5, 1, 7], [5, 2, 1], [5, 2, 3], [5, 2, 4], [5, 2, 6], [5, 2, 7], [5, 3, 1], [5, 3, 2], [5, 3, 4], [5, 3, 6], [5, 3, 7], [5, 4, 1], [5, 4, 2], [5, 4, 3], [5, 4, 6], [5, 4, 7], [5, 6, 1], [5, 6, 2], [5, 6, 3], [5, 6, 4], [5, 6, 7], [5, 7, 1], [5, 7, 2], [5, 7, 3], [5, 7, 4], [5, 7, 6], [6, 1, 2], [6, 1, 3], [6, 1, 4], [6, 1, 5], [6, 1, 7], [6, 2, 1], [6, 2, 3], [6, 2, 4], [6, 2, 5], [6, 2, 7], [6, 3, 1], [6, 3, 2], [6, 3, 4], [6, 3, 5], [6, 3, 7], [6, 4, 1], [6, 4, 2], [6, 4, 3], [6, 4, 5], [6, 4, 7], [6, 5, 1], [6, 5, 2], [6, 5, 3], [6, 5, 4], [6, 5, 7], [6, 7, 1], [6, 7, 2], [6, 7, 3], [6, 7, 4], [6, 7, 5], [7, 1, 2], [7, 1, 3], [7, 1, 4], [7, 1, 5], [7, 1, 6], [7, 2, 1], [7, 2, 3], [7, 2, 4], [7, 2, 5], [7, 2, 6], [7, 3, 1], [7, 3, 2], [7, 3, 4], [7, 3, 5], [7, 3, 6], [7, 4, 1], [7, 4, 2], [7, 4, 3], [7, 4, 5], [7, 4, 6], [7, 5, 1], [7, 5, 2], [7, 5, 3], [7, 5, 4], [7, 5, 6], [7, 6, 1], [7, 6, 2], [7, 6, 3], [7, 6, 4], [7, 6, 5]]