我只想使用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
。
答案 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);
}
}
}