本文为《Java Coding Problems》1-10题,问题涉及String, Number和Math (共39题)。
问题:统计字符串中每个字符的个数。
思路:使用HashMap进行计数。
代码如下:
public Map<Character, Long> countChars(String str) {
return str.chars() // 获取字符流, 返回IntStream
.mapToObj(c -> (char) c) // 将int转换为char
.collect(
Collectors.groupingBy(c -> c, Collectors.counting()) // 分组计数
);
}
使用函数式编程可以使代码更加简洁清晰。
上述代码仅支持char的计数,对Java来说是从0-65535的Unicode字符。对于其他Unicode字符,在Java中用两个char表示。为了支持普遍的字符计数,需要使用codePoint
,修改代码如下:
public Map<String, Long> countChars(String str) {
return str.codePoints() // 获取字符流, 返回IntStream
.mapToObj(c ->
String.valueOf(Character.toChars(c))) // 将codePoint转回String
.collect(
Collectors.groupingBy(c -> c, Collectors.counting()) //分组计数
);
}
一个codePoint可能包含一个或两个char,所以这里使用String
表示。
问题:找到字符串中第一个不重复的字符。
思路:第一次遍历使用HashMap进行计数,第二次遍历找到第一个出现次数为1的字符。
代码如下:
public String findFirstSingleChar(String str) {
Map<Integer, Long> countMap = str.codePoints() // 使用codePoint支持unicode
.boxed() // 将IntStream转变成 Integer Stream
.collect(
Collectors.groupingBy(
c -> c,
LinkedHashMap::new, // 使用LinkedHashMap进行计数
Collectors.counting()));
// LinkedHashMap会保持元素顺序
int cp = countMap.entrySet()
.stream()
.filter(e -> e.getValue() == 1)
.findFirst() // 第一个出现次数为1的codePoint
.map(Map.Entry::getKey)
.orElse(-1);
if (cp == -1) {
// 不存在
return null;
}
// 把codePoint转变成String
return String.valueOf(Character.toChars(cp));
}
问题:字符串中有多个空格分割的多个单词,翻转每个单词,删掉单词间的多余空格。
思路:将字符串切割成多个单词,然后挨个翻转,最后用空格连接所有单词。
代码如下:
public String reverseWords(String str) {
return Pattern.compile(" +")
.splitAsStream(str) // 使用正则表达式切割字符串
.map(w -> new StringBuilder(w).reverse()) // 使用StringBuilder翻转字符串
.collect(Collectors.joining(" ")); // 使用Collectors.joining连接字符串
问题:检查字符串是否都是由数字组成。
思路:使用matches
方法和正则表达式检查。
代码如下:
public boolean isDigit(String str) {
return str.matches("[0-9]+");
}
问题:统计字符串中的元音(a, e, i, o, u)和辅音数量。
思路:使用partitionBy
方法切分元音和辅音并计数。
代码如下:
public Pair<Long, Long> countVowelAndCons(String str) {
final Set<Character> vowels = new HashSet<>
(Arrays.asList('a', 'e', 'i', 'o', 'u'));
Map<Boolean, Long> result = str.toLowerCase()
.chars()
.mapToObj(c -> (char) c)
.filter(ch -> ch >= 'a' && ch <= 'z') // 只统计英文字符
.collect(
Collectors.partitioningBy( // 使用partitionBy将字符分为元音和辅音
vowels::contains,
Collectors.counting()));
return Pair.of(result.get(true), result.get(false));
}
问题:对字符串中某个字符进行计数。
思路:使用filter
进行计数。
代码如下:
public long count(String str, String ch) {
return str.codePoints()
.filter(c -> String.valueOf(Character.toChars(c)) == ch)
.count();
}
问题:将字符串转换成int
, long
,double
,float
。
思路:使用Integer.parseInt
等内置函数。
代码如下:
int num = Integer.parseInt(str);
long num = Long.parseLong(str);
float num = Float.parseFloat(str);
double num = Double.parseDouble(str);
问题:去掉字符串中的空白字符。
思路:使用内置replaceAll
方法和正则表达式\s
。
代码如下:
public String trimSpace(String str) {
return str.replaceAll("\\s", "");
}
问题:使用分隔符连接字符串数组。
思路:使用String.join
进行连接。
代码如下:
public String join(String[] str, char sep) {
return String.join(String.valueOf(sep), str);
}
问题:生成字符串中字符的全排列,返回全排列流。
思路:使用递归。
代码如下:
public Stream<String> permute(String prefix, String str) {
if (str.isEmpty()) {
return Stream.of(prefix);
}
// 遍历字符串所有位置
// 每次都把后续所有字符与当前位置交换
return IntStream.range(0, str.length())
.boxed()
.flatMap(i -> permute(prefix + str.charAt(i),
str.substring(0, i) + str.substring(i + 1)
));
}
参考资料:http://www.360doc.com/content/12/0420/13/9470897_205152817.shtml。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。