java:按不同顺序比较字符串和关键字

6qftjkof  于 2021-07-03  发布在  Java
关注(0)|答案(5)|浏览(516)

我有两个字符串,看起来像这样:

String str1 = "[0.7419,0.7710,0.2487]";
String str2 = "[\"0.7710\",\"0.7419\",\"0.2487\"]";

我想比较它们,尽管顺序不同,但它们是相等的。。。
哪种方法最快最简单?
我是否应该将每个数组拆分为数组并比较这两个数组?还是不?我想我必须删除“[”,“]”,“”字符以使它更清楚,所以我做了。我还把“,”换成了“,”但我不知道这是否有帮助。。。
提前感谢:)
编辑:我的字符串不总是一组双精度或浮点值。它们也可以是实际的单词或一组字符。

bvk5enib

bvk5enib1#

对于使用hashset的用户来说,这是一个非常简单的解决方案。
的好处set:-
它不能包含重复项。
元素的插入/删除是o(1)。
比数组快得多。这里保持元素的顺序也不重要,所以没关系。

String str1 = "[0.7419,0.7710,0.2487]";
String str2 = "[\"0.7710\",\"0.7419\",\"0.2487\"]";

Set<String> set1 = new HashSet<>();
Set<String> set2 = new HashSet<>();

String[] split1 = str1.replace("[", "").replace("]", "").split(",");
String[] split2 = str2.replace("[", "").replace("]", "").replace("\"", "").split(",");
set1.addAll(Arrays.asList(split1));
set2.addAll(Arrays.asList(split2));

System.out.println("set1: "+set1);
System.out.println("set2: "+set2);

boolean isEqual = false;
if(set1.size() == set2.size()){
    set1.removeAll(set2);
    if(set1.size() ==0){
        isEqual = true;
    }
}

System.out.println("str1 and str2 "+( isEqual ? "Equal" : "Not Equal") );

输出:

set1: [0.7710, 0.2487, 0.7419]
set2: [0.7710, 0.2487, 0.7419]
str1 and str2 Equal
q5lcpyga

q5lcpyga2#

因为您有一个混合结果类型,所以首先需要将其作为混合输入进行处理
下面是我将如何替换它,特别是对于较长的字符串。

private Stream<String> parseStream(String in) {
    //we'll skip regex for now and can simply hard-fail bad input later
    //you can also do some sanity checks outside this method
    return Arrays.stream(in.substring(1, in.length() - 1).split(",")) //remove braces
        .map(s -> !s.startsWith("\"") ? s : s.substring(1, s.length() - 1)); //remove quotes
}

接下来,我们有了一个字符串流,需要将其解析为原语或字符串(因为我假设我们没有某种奇怪的对象序列化形式):

private Object parse(String in) {
    //attempt to parse as number first. Any number can be parsed as a double/long
    try {
        return in.contains(".") ? Double.parseDouble(in) : Long.parseLong(in);
    } catch (NumberFormatException ex) {
        //it's not a number, so it's either a boolean or unparseable
        Boolean b = Boolean.parseBoolean(in); //if not a boolean, #parseBoolean is false
        b = in.toLowerCase().equals("false") && !b ? b : null; //so we map non-false to null
        return b != null ? b : in; //return either the non-null boolean or the string
    }
}

使用此方法,我们可以将混合流转换为混合集合:

Set<Object> objs = this.parseStream(str1).map(this::parse).collect(Collectors.toSet());
Set<Object> comp = this.parseStream(str2).map(this::parse).collect(Collectors.toSet());
//we're using sets, keep in mind the nature of different collections and how they compare their elements here
if (objs.equals(comp)) {
    //we have a matching set
}

最后,一些健全性检查的一个例子是确保输入字符串上有适当的大括号等 {a, b, ...c} ,以及序列/列表语法 [a, b, ...c] ,两者在这里有不同的比较。

ufj5ltwl

ufj5ltwl3#

这样地:

String[] a1 = str1.replaceAll("^\\[|\\]$", "").split(",", -1);
    String[] a2 = str2.replaceAll("^\\[|\\]$", "").split(",", -1);
    for (int i = 0; i < a2.length; i++)
        a2[i] = a2[i].replaceAll("^\\\"|\\\"$", "");
    Arrays.sort(a1);
    Arrays.sort(a2);
    boolean stringsAreEqual = Arrays.equals(a1, a2);

或者您可以使用功能齐全的方法(效率可能稍低一些):

boolean stringsAreEqual = Arrays.equals(
            Arrays.stream(str1.replaceAll("^\\[|\\]$", "").split(",", -1))
                    .sorted()
                    .toArray(),
            Arrays.stream(str2.replaceAll("^\\[|\\]$", "").split(",", -1))
                    .map(s -> s.replaceAll("^\\\"|\\\"$", ""))
                    .sorted()
                    .toArray()
    );

使用数组比使用集合(如其他人所建议的)的优点是,数组通常使用较少的内存,并且它们可以保存重复项。如果问题域的每个字符串中都包含重复的元素,则不能使用集合。

nvbavucw

nvbavucw4#

这可以通过下面的一个方法来实现,这个方法使用treeset来实现一组字符串,这样排序就可以内置句柄。它只是一个简单的转换都在字符串的集合和比较使用等于方法。请尝试以下代码:

String str1 = "[0.7419,0.7710,0.2487]";
        String str2 = "[\"0.7710\",\"0.7419\",\"0.2487\"]";
        String jsonArray = new JSONArray(str2).toString();
        Set<String> set1 = new TreeSet<String>(Arrays.asList(str1.replace("[", "").replace("]", "").split(",")));
        Set<String> set2 = new TreeSet<String>(Arrays.asList(jsonArray.replace("[", "").replace("]", "").replace("\"", "").split(",")));
        if(set1.equals(set2)){
             System.out.println(" str1 and str2 are equal");
       }

在上面的代码中,我借助jsonarray删除了“\”字符。
注:
但如果一个字符串中的重复元素和另一个字符串中的重复元素在数量上不同,这将不起作用,因为set不保留重复元素。
尝试使用保留重复元素的列表并解决您的问题。

String str1 = "[0.7419,0.7710,0.2487]";
            String str2 = "[\"0.7710\",\"0.7419\",\"0.2487\"]";
            String jsonArray = new JSONArray(str2).toString();
            List<String> list1=new ArrayList<String>(Arrays.asList(str1.replace("[", "").replace("]", "").split(",")));
            List<String> list2=new ArrayList<String>(Arrays.asList(jsonArray.replace("[", "").replace("]", "").replace("\"", "").split(",")));
            Collections.sort(list1);
            Collections.sort(list2);
            if(list1.equals(list2)){
                  System.out.println("str1 and str2 are equal");
            }
93ze6v8z

93ze6v8z5#

googlegson可以非常巧妙地处理这个任务,将值作为 Set<String> :

final String str1 = "[0.7419,0.7710,0.2487]";
    final String str2 = "[\"0.7710\",\"0.7419\",\"0.2487\"]";
    final String str3 = "[\"0.3310\",\"0.7419\",\"0.2487\"]";
    final Gson gson = new Gson();
    final Type setOfStrings = new TypeToken<Set<String>>() {}.getType();
    final Set<String> set1 = gson.fromJson(str1, setOfStrings);
    final Set<String> set2 = gson.fromJson(str2, setOfStrings);
    final Set<String> set3 = gson.fromJson(str3, setOfStrings);

    System.out.println("Set #1:" + set1);
    System.out.println("Set #2:" + set2);
    System.out.println("Set #3:" + set3);
    System.out.println("Set #1 is equivalent to Set #2: " + set1.equals(set2));
    System.out.println("Set #1 is equivalent to Set #3: " + set1.equals(set3));

输出为:

Set #1:[0.7419, 0.7710, 0.2487]
Set #2:[0.7710, 0.7419, 0.2487]
Set #3:[0.3310, 0.7419, 0.2487]
Set #1 is equivalent to Set #2: true
Set #1 is equivalent to Set #3: false

相关问题