字符串中最少重复的字符

时间:2019-05-29 07:38:48

标签: java

我正在尝试查找字符串中重复最少的字符,它对于某些输入有效,但是对于某些输入却失败。

Map<Character, Integer> map = new HashMap<Character, Integer> ();

    String s = "abcdabcdabcdacd";
    char[] chars = s.toCharArray();

    for (Character ch: chars) {
        if (map.containsKey(ch)) {
            map.put(ch, map.get(ch) + 1);
        } else {
            map.put(ch, 1);
        }
    }

    Set<Character> keys = map.keySet();

    for (Character ch: keys) {
        if (map.get(ch) ==1) {
            System.out.println(ch + " ");
        }
    }

我希望输出为b,但不会显示任何内容。 如果我输入aabaa作为输入,则显示b,这是正确的。

4 个答案:

答案 0 :(得分:2)

正如我已经评论过的,您只检查只出现一次的字符,而不是最少出现的字符。

您可以通过以下方式更改代码:

public class PrintB {

    public static void main(String[] args) {
        Map<Character, Integer> map = new HashMap<>();

        String s = "abcdabcdabcdacd";
        char[] chars = s.toCharArray();

        for (Character ch: chars) {
            if (map.containsKey(ch)) {
                map.put(ch, map.get(ch) + 1);
            } else {
                map.put(ch, 1);
            }
        }

        Set<Character> keys = map.keySet();
        boolean broken = false;
        for ( int i = 0; i < s.length(); i++ ) { // the max will be s.length()

            for (Character ch : keys) {
                if (map.get(ch) == i) { // this amount is checked for each char
                    System.out.println(ch + " ");
                    broken = true;
                }
            }
            if ( broken ) {
                i = s.length(); // sure, there are other ways to break out of the loop
            }
        }
    }
}

答案 1 :(得分:1)

您可以简单地使用流:

final String s = "abcdabcdabcdacd";

String leastRepeated = 
   s.chars().mapToObj(i -> Character.toString((char) i))      // map to Stream<String>   
    .collect(Collectors.toMap(k -> k, v -> 1, Integer::sum))  // Map<String, Integer>
    .entrySet().stream()                                      // stream over map
    .min(Comparator.comparing(Entry::getValue))               // comparing values in map
    .get().getKey();                                          // get resp entry   

输出:

  

b

答案 2 :(得分:0)

您的代码无法按照您希望的方式工作的原因是,您的最后一个代码块仅在字符重复一次且仅重复一次时才打印:

for (Character ch: keys) {
    if (map.get(ch) ==1) {
        System.out.println(ch + " ");
    }

但是,通过使用Collections.min方法,我们可以找到最低的地图值,然后可以使用它从地图键中查找它所属的字符。这是带有上下文的完整代码:

/**
 * @return an array of Character objects that have occured the
 * least amount of times in the given {@code String} parameter.
 * <i>Note that all whitespaces found within the {@code String} will be ignored </i>
 */
public static Character[] getLeastRepeatingCharacters(String text) {

    Map<Character, Integer> map = new HashMap<Character, Integer> ();
    /*
     * Remove all whitespaces from the text as we don't
     * want to include them in our comparison oprations
     */
    text = text.replaceAll("\\s+","");

    for (Character ch : text.toCharArray()) {
        if (map.containsKey(ch)) {
            map.put(ch, map.get(ch) + 1);
        }
        else if (ch != '\0') {
            map.put(ch, 1);
        }
    }
    /*
     * Get map value that occurs the least amount of times
     */
    int leastOccuranceValue = Collections.min(map.values());
    java.util.List<Character> leastOccurances = new java.util.ArrayList<>();
    /*
     * Iterate through the map, find all characters that have
     * occured the least amount of times and add them to a list
     */
    for (java.util.Map.Entry<Character, Integer> entry : map.entrySet()) {
        if (entry.getValue().equals(leastOccuranceValue)) {
            leastOccurances.add(entry.getKey());
        }
    }
    return leastOccurances.toArray(new Character[0]);
}

public static void main(String[] args) {

    String text = "abcdabcdabcdacd";
    Character[] leastRepeating = getLeastRepeatingCharacters(text);

    String log = "Array of charactes that repeated the least amount of times in text '%s':%n%s";
    System.out.printf(log, text, Arrays.toString(leastRepeating));
}

输出:

您的字符串示例:

Array of charactes that repeated the least amount of times in text 'abcdabcdabcdacd ':
[b]

Sultuske提供的字符串示例:

Array of charactes that repeated the least amount of times in text 'kambcxdabcdalbcdacd ':
[x, k, l, m]

答案 3 :(得分:0)

您必须阅读整个地图才能获得最小出现次数,因此您不能在循环中打印,而应收集具有最小出现次数的字符,然后打印它们。

    public static void main(String[] args) {
        Map<Character, Integer> map = new HashMap<>();

        String s = "abcdaybcdabcdacdz";
        char[] chars = s.toCharArray();

        for (Character ch: chars) {
            if (map.containsKey(ch)) {
                map.put(ch, map.get(ch) + 1);
            } else {
                map.put(ch, 1);
            }
        }

        List<Character> reps = new ArrayList<>();

        Integer count = chars.length;
        Set<Entry<Character, Integer>> entries = map.entrySet();
        for (Entry<Character, Integer> entry : entries) {
            Integer n = entry.getValue();
            Character c = entry.getKey();
            if(n==count) {
                reps.add(c);
            }else if (n<count) {
                reps = new ArrayList<>();
                reps.add(c);
                count = n;
            }
        }

        for (Character character : reps) {
            System.out.println(character);
        }

    }