如何编写Java程序以仅打印字符串中的重复字符?

时间:2019-09-24 13:40:39

标签: java arrays collections set

我只想使用collections(Set)从字符串中打印重复的字符。

我已经编写了代码,但是如果String为“ ashish”,它将显示正确的结果,但是如果String为“ ashish java”,则由于出现char'a'的次数为3次而将失败。

public class DuplicateStringMethod {
    public static void duplicateString(String str) {
        char[] cArray = str.toCharArray();
        Set<Character> set = new HashSet<Character>();

        for(char c:cArray) {
            if(set.add(c)==false) {
                System.out.println(c);
            }
        }
    }

    public static void main(String[] args) {
        duplicateString("Java ashishj ");
    }
}

它将打印a a s h。但是我只想使用a s h界面来Set

7 个答案:

答案 0 :(得分:1)

尝试:

public static void duplicateString(String str) {
    Set<Character> firstTime = new HashSet<Character>();
    Set<Character> reported = new HashSet<Character>();

    char[] cArray = str.toCharArray();
    for(char c:cArray) {
        if (!firstTime.contains(c)) {
          firstTime.add(c);
          continue;
        }
        if (reported.contains(c)) { continue; }
        reported.add(c);
        System.out.println(c);
    }
}

由于霍尔格的建议,我进行了一些测试:

  
      
  • 添加:10443次操作的52443260ns
  •   
  • 包含:28209745ns(用于10000000次操作)
  •   

因此上面的代码虽然不短,但最快。

答案 1 :(得分:1)

对于我来说,“仅使用Set接口需要什么”还不是很清楚,但是我假设这意味着重复的字符将在Set中返回。有几种方法可以做到这一点。第一个是在输入字符串的字符上的直接循环。它利用Set.add的功能,如果修改了集合,则返回true;如果没有修改,则返回false。这意味着返回add的{​​{1}}操作是重复的。

false

有一种简单的方法可以做到这一点,这与以流形式表达的本质上是相同的:

static Set<Character> dups0(String input) {
    Set<Character> dups = new HashSet<>();
    Set<Character> seen = new HashSet<>();
    for (char ch : input.toCharArray()) {
        if (! seen.add(ch)) {
            dups.add(ch);
        }
    }
    return dups;
}

某些人可能会发现它令人讨厌,因为它的过滤器操作会产生副作用。另外,如果并行运行,结果将需要像static Set<Character> dups1(String input) { Set<Character> seen = new HashSet<>(); return input.chars() .mapToObj(ch -> (char)ch) .filter(ch -> !seen.add(ch)) .collect(toSet()); } 之类的东西。

另一种方法是生成一个字符频率表,并删除仅出现一次的所有条目:

ConcurrentHashMap.newKeySet

请注意,这在地图的values-collection视图上使用了collections批量修改操作。为了确保映射是可变的,我使用了static Set<Character> dups2(String input) { Map<Character, Long> map = input.chars() .mapToObj(i -> (char)i) .collect(groupingBy(ch -> ch, HashMap::new, counting())); map.values().removeIf(v -> v == 1); return map.keySet(); } 的三参数重载来指定映射的实现类型。

如果您不喜欢突变,可以通过一种纯流方法来实现:

groupingBy

答案 2 :(得分:0)

检查此程序

public static void duplicateString(String str) {

        char[] cArray = str.replaceAll("\\s+", "").toCharArray();

        Set<Character> set = new HashSet<Character>();
        Set<Character> alreadyExistingSet = new HashSet<Character>();

        for (char c : cArray) {
            if (set.add(c) == false && alreadyExistingSet.add(c) == true) {
                System.out.print(c);
            }
        }
    }

答案 3 :(得分:0)

您需要做的就是使用add()类的Set方法来告诉您是否要插入(添加)的东西已经包含在集合中。当函数返回false时,表示当前添加的“内容”是重复项。 然后,将其添加到Set个重复项中。这样,重复多次的项目将仅在新集合中显示一次。最后,为了保存订单,您可能需要使用LinkedHashSet来存储重复项。

public class TestDups {

    public static void main (String[] args) {
        String str = "Java ashishj ";
        Set<Byte> myset = new TreeSet<>();
        Set<Character> dups = new LinkedHashSet<>();
        for (byte c: str.getBytes() ) {
            if (!myset.add(c)) {
                dups.add((char)c);
            }
        }

        dups.stream().forEach(System.out::print);
    }
}

上面的代码输出为“ ash”。请注意末尾的空白,因为原始字符串在单词之间和末尾包含两个空格。

答案 4 :(得分:0)

public static void main(String[] args) {
        String s = "Javaashishj";
        char[] cArray = s.toCharArray();
        Set<Character> set = new HashSet<Character>();
        for (char c : cArray) {
            if (!set.contains(c)) {
                set.add(c);
                System.out.println(c);
            }
        }
    }

答案 5 :(得分:0)

您可以在此处使用String.split()。此方法根据提供的正则表达式将字符串分成字符串数组。我们将使用“”,因为我们想在每个单个字符之后分割字符串,然后将结果输入流中。

public static void duplicateString( String str ) {

    // collect all characters in a map, whose String value is the character and whose key value is the count of occurrences in the string
    Map<String,Long> charCountMap = Arrays.stream( str.split( "" ) )
            .filter( charInString -> !charInString.equals( " " ) ) // don't want spaces
            .collect( Collectors.groupingBy( Function.identity(), Collectors.counting() ) );

    charCountMap.entrySet()
            .stream()
            .filter( entrySet -> entrySet.getValue() > 1 ) // filter out occurrences that are one or less
            .forEach( entrySet -> System.out.println( String.format( "Char %s appeared %d times", entrySet.getKey(), entrySet.getValue() ) ) );
}

答案 6 :(得分:0)

  

再使用一组存储重复的元素并打印该元素。   尝试这样:

public static void duplicateString(String str) {
        str=str.replaceAll(" ","");
        char[] cArray = str.toCharArray();
        Set<Character> set = new HashSet<Character>();
        Set<Character> set1 = new HashSet<Character>();
        for(char c:cArray) {
            if(set.add(c)==false) {
                if(set1.add(c) == true)
                    System.out.println(c);
            }
        }
    }
相关问题