hashset包含精确的字符位置和不正确的字符位置

t40tm48m  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(273)

我有一个类来确定2个字符数组中有多少匹配字符。使用 HashSet contains方法,如果一个字符数组包含第二个数组中的字符,则显示该字符。
问题是如果两个匹配的字符出现在多个位置。
例如,如果 array 1 = adcd 以及 array 2 = a05ddd , d 出现3次,而不是2次。
我如何修改它来计算正确的字符数?代码生成 "addd" 什么时候应该生产 "add" 对于不正确的字符,结果将是 "a--dd" ```
HashSet hash = new HashSet();
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 + "-";
}
gxwragnw

gxwragnw1#

很可能需要收集有关字符频率的数据,因此应该用一个Map来替换set。然后,可以根据两个词中的公共字符和字符的最小频率来构建结果字符串:

// 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 可以从Java11开始使用,它可以用Java8兼容的代码替换,使用 String::join + Collections.nCopies :

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

相关问题