使用 java 流的字母大小写排列
Letter Case Permutation using java streams
如何使用 Java 流根据给定的字符串输入查找字母大小写的所有差异?
巩固我对 Java Streams 的理解。我正在使用 java 流解决 leetcode 简单问题。我对如何使用流解决这个回溯问题感到困惑。我特别困惑如何映射一个字符两次,即小写和大写。
Input: S = "a1b2"
Output: ["a1b2","a1B2","A1b2","A1B2"]
Stream.of(S.split(""))
.map(str -> str.toUpperCase()) // this will upper case only
.map(str -> str.toLowerCase()) // this will lower case only. how to use both?
.collect(Collectors.toList()); //how do i concatenate strings before adding into list
英语不好提前致歉
您可以使用平面图来做到这一点,但您的输出将是 ["a", "A", "1", "b", "B", "2"]
,这与您想要的完全不同。请注意,您的输出会迅速变大;输入中的每个字母的输出数量都会翻倍。这与流甚至不匹配。
一般来说,您想在这里做的事情是不可能的,或者需要弯曲工具,这类似于用锤子在三明治上涂抹黄油。您可能可以,但是为什么要在大火中这样做?这不会提高您使用那把锤子的技能。
正如rzwitserloot所说,这种问题一般不会用流来攻击,但是我会尽力解决你对问题的疑惑:
对于具有字母大写和小写版本的流,您可以使用如下内容:
Stream.of(input.split(""))
.filter(c -> Character.isLetter(c.charAt(0))) // Filter only letters
.flatMap(str -> Stream.of(str, str.toUpperCase())) // Flatten the stream with both letters
.collect(Collectors.toList())
如果您想在映射流中的值后连接列表中的字符串,而不是使用 Collectors.toList()
,您可以像这样使用 Collectors.joining()
:
Stream.of(input.split(""))
.filter(c -> Character.isLetter(c.charAt(0))) // Filter only letters
.flatMap(str -> Stream.of(str, str.toUpperCase()))
.collect(Collectors.joining()) // this collector can receive a delimiter if you want to join them separated by comman for example.
现在对于有问题的问题,您不需要字母的大小写版本,只需从输入单词中过滤字母并开始将它们在单词中替换为一个大写版本,这可能是一个可能的解决方案:
public static void main(String[] args) {
String input = "a1b2";
// Output: ["a1b2","a1B2","A1b2","A1B2"];
Set<String> result = new HashSet<>();
result.add(input);
Stream.of(input.split(""))
.filter(c -> Character.isLetter(c.charAt(0)))
.forEach(c -> result.addAll(
result.stream().map(str -> {
if (!str.equals(input.toUpperCase())) {
return str.replaceFirst(c, c.toUpperCase());
}
return str;
}).collect(Collectors.toSet()))
);
System.out.println(result);
}
如何使用 Java 流根据给定的字符串输入查找字母大小写的所有差异?
巩固我对 Java Streams 的理解。我正在使用 java 流解决 leetcode 简单问题。我对如何使用流解决这个回溯问题感到困惑。我特别困惑如何映射一个字符两次,即小写和大写。
Input: S = "a1b2"
Output: ["a1b2","a1B2","A1b2","A1B2"]
Stream.of(S.split(""))
.map(str -> str.toUpperCase()) // this will upper case only
.map(str -> str.toLowerCase()) // this will lower case only. how to use both?
.collect(Collectors.toList()); //how do i concatenate strings before adding into list
英语不好提前致歉
您可以使用平面图来做到这一点,但您的输出将是 ["a", "A", "1", "b", "B", "2"]
,这与您想要的完全不同。请注意,您的输出会迅速变大;输入中的每个字母的输出数量都会翻倍。这与流甚至不匹配。
一般来说,您想在这里做的事情是不可能的,或者需要弯曲工具,这类似于用锤子在三明治上涂抹黄油。您可能可以,但是为什么要在大火中这样做?这不会提高您使用那把锤子的技能。
正如rzwitserloot所说,这种问题一般不会用流来攻击,但是我会尽力解决你对问题的疑惑:
对于具有字母大写和小写版本的流,您可以使用如下内容:
Stream.of(input.split(""))
.filter(c -> Character.isLetter(c.charAt(0))) // Filter only letters
.flatMap(str -> Stream.of(str, str.toUpperCase())) // Flatten the stream with both letters
.collect(Collectors.toList())
如果您想在映射流中的值后连接列表中的字符串,而不是使用 Collectors.toList()
,您可以像这样使用 Collectors.joining()
:
Stream.of(input.split(""))
.filter(c -> Character.isLetter(c.charAt(0))) // Filter only letters
.flatMap(str -> Stream.of(str, str.toUpperCase()))
.collect(Collectors.joining()) // this collector can receive a delimiter if you want to join them separated by comman for example.
现在对于有问题的问题,您不需要字母的大小写版本,只需从输入单词中过滤字母并开始将它们在单词中替换为一个大写版本,这可能是一个可能的解决方案:
public static void main(String[] args) {
String input = "a1b2";
// Output: ["a1b2","a1B2","A1b2","A1B2"];
Set<String> result = new HashSet<>();
result.add(input);
Stream.of(input.split(""))
.filter(c -> Character.isLetter(c.charAt(0)))
.forEach(c -> result.addAll(
result.stream().map(str -> {
if (!str.equals(input.toUpperCase())) {
return str.replaceFirst(c, c.toUpperCase());
}
return str;
}).collect(Collectors.toSet()))
);
System.out.println(result);
}