哈希集包含准确的字符放置和不正确的字符放置
Hashset contains with exact character placement and incorrect character placement
我有一个 class 来确定 2 个字符数组中有多少个匹配字符。使用 HashSet
contains 方法,如果一个字符数组包含第二个数组中的字符,则显示该字符。
问题是如果我们有两个匹配的字符出现在多个位置。
例如,如果array 1 = adcd
和array 2 = a05ddd
,d
出现3次,而不是2次。
我将如何修改它以考虑正确的字符数?代码在应该产生 "add"
时产生 "addd"
对于不正确的字符,结果将是
"a--dd"
HashSet<Character> hash = new HashSet<Character>();
String word1 = "adcd";
String word2 = "a05ddd";
char[] ch1 = word1.toCharArray();
char[] ch2 = word2.toCharArray();
Character character = null;
String charLocation = "";
int count = 0;
for (int i = 0; i < ch1.length; i++)
{
hash.add(ch1[i]);
}
for (int i = 0; i < ch2.length; i++)
{
character = ch2[i];
if (hash.contains(character))
{
charLocation = charLocation + character;
count++;
}
if (!hashSet.contains(character))
correctCharPlacements = correctCharPlacements + "-";
}
很可能需要收集关于字符出现频率的数据--所以set应该换成map。然后可以根据常见字符 和 两个单词中字符的最小频率来构建结果字符串:
// helper method to build frequency map for a word/string
private static Map<Character, Integer> freqMap(String word) {
return word.chars()
.mapToObj(c -> (char)c)
.collect(Collectors.toMap(x -> x, x -> 1, Integer::sum, LinkedHashMap::new));
}
static String common(String w1, String w2) {
if (null == w1 || null == w2) {
return null;
}
Map<Character, Integer> map1 = freqMap(w1);
Map<Character, Integer> map2 = freqMap(w2);
Set<Character> commonChars = new LinkedHashSet<>(map1.keySet());
commonChars.retainAll(map2.keySet());
return commonChars.stream()
.map(x -> String.valueOf(x).repeat(Math.min(map1.get(x), map2.get(x))))
.collect(Collectors.joining(""));
}
测试:
System.out.println("common = " + common("adcd", "a05ddd"));
输出:
common = add
更新
由于 String::repeat
从 Java 11 开始可用,因此可以使用 String::join
+ Collections.nCopies
将其替换为 Java 8 兼容代码:
static String common(String w1, String w2) {
if (null == w1 || null == w2) {
return null;
}
Map<Character, Integer> map1 = freqMap(w1);
Map<Character, Integer> map2 = freqMap(w2);
Set<Character> commonChars = new LinkedHashSet<>(map1.keySet());
commonChars.retainAll(map2.keySet());
return commonChars.stream()
.map(x -> String.join("", Collections.nCopies(Math.min(map1.get(x), map2.get(x)), String.valueOf(x))))
.collect(Collectors.joining(""));
}
System.out.println("Java version: " + System.getProperty("java.version"));
System.out.println("common = " + common("adcd", "a05ddd"));
输出:
Java version: 1.8.0_201
common = add
更新 2
为了保持结果中第二个字符串的字符顺序,将缺失的字符替换为'-'
,可以实现如下方法:
static String common2(String w1, String w2) {
if (null == w1 || null == w2) {
return null;
}
Map<Character, Integer> map1 = freqMap(w1);
StringBuilder sb = new StringBuilder();
for (char c : w2.toCharArray()) {
if (map1.containsKey(c) && map1.get(c) > 0) {
sb.append(c);
map1.merge(c, -1, Integer::sum); // decrement the character counter in the first map
} else if (!map1.containsKey(c)) { // character missing in the first word
sb.append('-');
}
}
return sb.toString();
}
测试
String[][] tests = {
{"adcd", "ad05dd"},
{"adcd", "d05add"},
{"adcd", "d05dadd"},
};
for (String[] test : tests) {
System.out.printf("common(%s, %s) = %s%n", test[0], test[1], common(test[0], test[1]));
}
输出:
common(adcd, ad05dd) = ad--d
common(adcd, d05add) = d--ad
common(adcd, d05dadd) = d--da
我有一个 class 来确定 2 个字符数组中有多少个匹配字符。使用 HashSet
contains 方法,如果一个字符数组包含第二个数组中的字符,则显示该字符。
问题是如果我们有两个匹配的字符出现在多个位置。
例如,如果array 1 = adcd
和array 2 = a05ddd
,d
出现3次,而不是2次。
我将如何修改它以考虑正确的字符数?代码在应该产生 "add"
时产生 "addd"
对于不正确的字符,结果将是
"a--dd"
HashSet<Character> hash = new HashSet<Character>();
String word1 = "adcd";
String word2 = "a05ddd";
char[] ch1 = word1.toCharArray();
char[] ch2 = word2.toCharArray();
Character character = null;
String charLocation = "";
int count = 0;
for (int i = 0; i < ch1.length; i++)
{
hash.add(ch1[i]);
}
for (int i = 0; i < ch2.length; i++)
{
character = ch2[i];
if (hash.contains(character))
{
charLocation = charLocation + character;
count++;
}
if (!hashSet.contains(character))
correctCharPlacements = correctCharPlacements + "-";
}
很可能需要收集关于字符出现频率的数据--所以set应该换成map。然后可以根据常见字符 和 两个单词中字符的最小频率来构建结果字符串:
// helper method to build frequency map for a word/string
private static Map<Character, Integer> freqMap(String word) {
return word.chars()
.mapToObj(c -> (char)c)
.collect(Collectors.toMap(x -> x, x -> 1, Integer::sum, LinkedHashMap::new));
}
static String common(String w1, String w2) {
if (null == w1 || null == w2) {
return null;
}
Map<Character, Integer> map1 = freqMap(w1);
Map<Character, Integer> map2 = freqMap(w2);
Set<Character> commonChars = new LinkedHashSet<>(map1.keySet());
commonChars.retainAll(map2.keySet());
return commonChars.stream()
.map(x -> String.valueOf(x).repeat(Math.min(map1.get(x), map2.get(x))))
.collect(Collectors.joining(""));
}
测试:
System.out.println("common = " + common("adcd", "a05ddd"));
输出:
common = add
更新
由于 String::repeat
从 Java 11 开始可用,因此可以使用 String::join
+ Collections.nCopies
将其替换为 Java 8 兼容代码:
static String common(String w1, String w2) {
if (null == w1 || null == w2) {
return null;
}
Map<Character, Integer> map1 = freqMap(w1);
Map<Character, Integer> map2 = freqMap(w2);
Set<Character> commonChars = new LinkedHashSet<>(map1.keySet());
commonChars.retainAll(map2.keySet());
return commonChars.stream()
.map(x -> String.join("", Collections.nCopies(Math.min(map1.get(x), map2.get(x)), String.valueOf(x))))
.collect(Collectors.joining(""));
}
System.out.println("Java version: " + System.getProperty("java.version"));
System.out.println("common = " + common("adcd", "a05ddd"));
输出:
Java version: 1.8.0_201
common = add
更新 2
为了保持结果中第二个字符串的字符顺序,将缺失的字符替换为'-'
,可以实现如下方法:
static String common2(String w1, String w2) {
if (null == w1 || null == w2) {
return null;
}
Map<Character, Integer> map1 = freqMap(w1);
StringBuilder sb = new StringBuilder();
for (char c : w2.toCharArray()) {
if (map1.containsKey(c) && map1.get(c) > 0) {
sb.append(c);
map1.merge(c, -1, Integer::sum); // decrement the character counter in the first map
} else if (!map1.containsKey(c)) { // character missing in the first word
sb.append('-');
}
}
return sb.toString();
}
测试
String[][] tests = {
{"adcd", "ad05dd"},
{"adcd", "d05add"},
{"adcd", "d05dadd"},
};
for (String[] test : tests) {
System.out.printf("common(%s, %s) = %s%n", test[0], test[1], common(test[0], test[1]));
}
输出:
common(adcd, ad05dd) = ad--d
common(adcd, d05add) = d--ad
common(adcd, d05dadd) = d--da