【问题标题】:Remove all characters from String1 which are present in String2 and vice versa从 String1 中删除 String2 中存在的所有字符,反之亦然
【发布时间】:2017-05-29 23:50:58
【问题描述】:

我是 stackoverflow 的新手,这是我关于 stackoverflow 的第一个问题。

我有以下问题:

以这样的方式打印 Output1 和 Output2 的值,Output1 应打印 String1 中存在但 String2 中不存在的所有字符,Output2 应打印 String2 中存在但 String1 中不存在的所有字符。

示例: 如果 String1: ABC 和 String: BC 那么 Output1: A 和 Output2:

如果 String1: BC 和 String: BANGALORE 那么 Output1: C 和 Output2: ANGALORE

我知道这个问题类似于 Remove characters from the second string which are present in the first stringGiven two strings, str1 and str2 as input, remove all chars from str1 that appear in str2 但在这里我想将 String1 和 String2 的结果作为两个不同的字符串 Output1 和 Output2

我尝试了下面的程序来实现这一点,但不确定这是否是一个好的解决方案,因为我需要四个 for 循环来获得结果。

package com.test.java.program;
import java.util.Scanner;
public class PrintString {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        System.out.println("Enter first input as a string: ");
        String str1 = scanner.nextLine();

        System.out.println("Enter first input as a string: ");
        String str2 = scanner.nextLine();

        System.out.println(printStringOutput(str1, str2));
    }

    private static String printStringOutput(String str1, String str2){

        String strTemp1 = str1;

        int strLen1 = str1.length();
        int strLen2 = str2.length();

        for(int i=0; i<strLen1; i++){

            for(int j=0; j<strLen2; j++){

                if(str1.charAt(i) == (str2.charAt(j))){
                    str1 = str1.replace(str1.charAt(i), '\u0000');
                }
            }
        }

        for(int i=0; i<strLen2; i++){

            for(int j=0; j<strLen1; j++){

                if(str2.charAt(i) == (strTemp1.charAt(j))){
                    str2 = str2.replace(str2.charAt(i), '\u0000');
                }
            }
        }

        return "Output1: " + str1 + "\nOutput2: " + str2;
    }
}

我知道我们也可以使用正则表达式实现相同的结果,但不知道该怎么做。有人可以为这个问题提供更好的解决方案吗?

我假设给定的输入是字符串并且不对输入执行任何验证。

谢谢。

【问题讨论】:

  • “有人可以提供更好的解决方案吗” -- 这不是 StackOverflow 的工作方式。请访问help center 并阅读How to Ask。什么是更好的”?目前什么不起作用?
  • “我有个问题”?这是你在做作业时试图在这里寻求帮助的混淆方式吗?
  • @clearlight:实际上这个问题是我工作场所的一位同事问我的,我想出了上述解决方案。我知道这是正确的方法,但不是获得所需输出的有效方法。
  • @Jim Garrison :这工作得非常好,但我正在寻找一种解决方案,它在性能方面会更好,正如 Andreas 所回答的那样。我错过了在我的问题中提到“在性能方面”。 :(
  • 那么问题在这里是题外话,属于Code Review

标签: java string


【解决方案1】:

其他两个答案(到目前为止)产生 1 个字符的字符串作为中间对象,这不是很有效。

Dmitry Gorkovets's answer 为基础,这是一个更好的版本:

String result1 = str1.chars()
                     .filter(ch -> str2.indexOf(ch) < 0)
                     .collect(StringBuilder::new,
                              (buf, ch) -> buf.append((char) ch),
                              StringBuilder::append)
                     .toString();

更新

由于mentioned by Jakub M.,如果str2 可以是一个长字符串,您可以通过将字符串转换为Map 字符来获得更好的性能,如下所示:

Set<Integer> set = str2.chars()
                       .boxed()
                       .collect(Collectors.toSet());

String result1 = str1.chars()
                     .filter(ch -> ! set.contains(ch))
                     .collect(StringBuilder::new,
                              (buf, ch) -> buf.append((char) ch),
                              StringBuilder::append)
                     .toString();

【讨论】:

  • 一旦谈到效率,在过滤器中使用 Set 而不是 indexOf。这使得解决方案 O(n) 而不是 O(n^2)。
  • 谢谢@Andreas。 :)
【解决方案2】:

使用流你可以这样做:

Stream.of(str1.split(""))
      .filter((a)->!str2.contains(a))
      .forEach(System.out::print);

Stream.of(str2.split(""))
      .filter((a)->!str1.contains(a))
      .forEach(System.out::print);

【讨论】:

    【解决方案3】:

    好吧,我在您的代码中没有发现任何问题,它可以正常工作。但是如果你想使用 Java 8 的特性,你可以使用这个代码:

    String str1 = "BC";
    String str2 = "BANGALORE";
    
    String result1 = str1.chars()
            .mapToObj(i -> (char)i)
            .filter(c -> str2.indexOf(c) < 0)
            .map(String::valueOf)
            .collect(Collectors.joining());
    
    String result2 = str2.chars()
            .mapToObj(i -> (char)i)
            .filter(c -> str1.indexOf(c) < 0)
            .map(String::valueOf)
            .collect(Collectors.joining());
    
    System.out.println(result1);
    System.out.println(result2);
    

    【讨论】:

      猜你喜欢
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多