2

我有六个字符串变量,比如 str11、str12、str13、str21、str21 和 str23。

我需要比较这些变量的组合。

我必须检查的组合是 str11 -- str12 -- str13 作为一组,str21 -- str22 -- str23 作为另一组。我必须比较这两组。

现在我很困惑我应该使用哪种方法进行比较?

我可以附加相同组的字符串并进行比较,这只是一个比较说( str11 append str12 append str13 ) eqauls ( str21 append str22 append str23 )

或者

我应该进行个人 3 比较吗?

if( str11 equals str21 ) {

    if( str12 equals str22 ) {

        if( str13 equals str23 ) {

        }

    }

}

当我进行字符串比较时,由于字符串长度而使我付出代价的性能因素是什么?让我们假设所有字符串的长度相同(大约)。

4

8 回答 8

10

我会单独测试。

“AB”“CD”“EF”是否等于“ABC”“DE”“F”?

我认为没有。

PS如果是,那么这是一个非常特殊的情况,如果您决定以这种方式编码(作为串联比较),那么请注释掉它。

于 2009-01-06T13:35:32.523 回答
8

绝对没有必要将比较分成三个 if 语句。您也可以简单地对您的比较进行 AND,例如

if (  str11 equals str21
   && str12 equals str22
   && str13 equals str23) ...
于 2009-01-06T13:31:57.650 回答
3

您的变量名称表示主要的代码异味。听起来您应该有两个数组,而不是六个变量,每个数组包含三个字符串。换句话说,最初这样的事情会好得多:

String[][] strs = new String[2][3];
strs[0][0] = str11;
strs[0][1] = str12;
...

有可能根据您从哪里获得六个字符串,您不需要在比较之前立即手动执行此操作,但可能会以更友好的格式传递您的参数。

如果您确实希望通过比较字符串对象的数组来做到这一点,并且您使用的是 Java 1.5 或更高版本,请记住您可以访问 java.util.Arrays.equals() 方法来实现数组相等。尽可能多地使用库方法是避免重新发明轮子的额外工作和可能的实现错误的好方法(例如,到目前为止,两个提交的实现都有错误)。

您采取的确切路线可能取决于您正在编写的域 - 如果您的特定问题需要您始终比较 3 元组,那么编写代码来显式比较三个字符串的组并不是一个好主意,因为它会可能比比较任意长度数组的代码更容易理解。(如果你要走这条路,那么无论如何我们都是一个带有 && 条件的 if() 条件而不是嵌套的 if 块,正如 Adam Bellaire 所演示的那样)。

不过,一般来说,如果您将其设置为使用任意长度的数组,您将拥有一个更可重用的代码块。

于 2009-01-07T16:51:15.483 回答
1

将字符串附加在一起并进行比较将不起作用。例如,字符串 1 和 2 可以为空,字符串 3 可以包含“gorps”,而字符串 4 包含“gorps”,而字符串 5 和 6 为空。附加结果的比较将返回 true,尽管这将是误报。你必须想出一个你保证不会包含在任何字符串中的分隔符才能让它工作,这可能会变得混乱。

我会按照您的方式进行比较。它易于阅读且简单明了。

于 2009-01-06T13:34:13.977 回答
1

对一个大 char[] 的迭代可能比对 n 个总长度相等的单独字符串的迭代更快。这是因为数据非常本地化,CPU 很容易预取数据。

但是,当您在 Java 中连接多个字符串时,您将使用 StringBuilder/Buffer,然后在某些情况下将 i 转换回字符串。由于 SB.append() 的工作方式和 Java String 是不可变的,这将导致内存分配增加,这反过来又会造成内存瓶颈并显着降低应用程序的速度。

我建议保持字符串不变并进行单独比较。由于较长的 char[] 所带来的性能提升很可能远低于您在较高分配率下可能遇到的问题。

于 2009-01-06T14:11:47.723 回答
1

恕我直言:我认为您的代码和问题不仅有点味道,而且几乎很臭(这里是大笑脸)。

1)变量名称表明实际上有字符串向量;如前所述
2) 个人比较与级联比较的问题引发了如何定义字符串元组相等性的问题;也已经提到了。

但最让我印象深刻的是:

3)对我来说,这看起来像是“过早优化”的典型案例,并且在错误的地方计算 CPU 周期。

如果您真的关心性能,请忘记 3 个人比较与单个比较的成本。反而:

创建两个连接字符串的额外开销如何?

  (str11 + str12 + str13) = (str21 + str22 + str23)

让我们分析一下内存管理器和要完成的操作。在底层,这意味着 4 个额外的内存分配、2 个额外的 strcpy,以及另外 4 个额外的 strcat 或 strcpy(取决于 VM 的执行方式;但大多数会使用另一个 strcpy)操作。然后调用一次比较,它不首先使用 strlen 计算字符;相反,它要么预先知道大小(如果对象标头还包括字符数,这很可能),要么它只是运行到一个 0 字节。这被称为一次与 3 次。要比较的实际字符数大致相同(忘记额外的 0 字节)。这给我们留下了对 strcmp 的 2 次额外调用(几个 nS),而我上面描述的开销(几个 uS)。如果我们将 GC 回收开销(0 分配与 4)相加,我'

附加通知:
理论上,JITter 可以优化它或其中的一部分,并按照 Adam Bellaire 的建议实际生成代码,但我怀疑任何 JIT 开发人员都关心优化此类代码。顺便说一句,系统的字符串例程(又名字符串操作)通常比手动编码快得多,所以不要自己开始循环单个字符。

于 2009-01-13T16:22:56.497 回答
0

我会用简单的方法

动态运行两个数组的所有数组元素。

            boolean isEqual = true;
            for(int n = 0;n<str1.length;++n){
                isEqual &= str1[n].equals(str2[n]);
            }

            return isEqual;
于 2009-01-06T13:35:25.457 回答
0

我会将这两个组添加到两个数组中,然后遍历数组以比较该数组中的各个字符串。Markus Lausberg 给出的答案已经是一个很好的例子。

我不会担心性能成本。只需以最易读的方式编写即可。Java 编译器在性能优化方面非常出色。

示例方法:

    public boolean compareGroups(String[] group1, String[] group2){
    if (group1.length != group2.length ){
        return false;
    }

    for (int i = 0; i < group1.length; i++) {
        if (!group1[i].equals(group2[i])){
            return false;
        }
    }

    return true;
}

调用方法当然很简单:

        String[] group1 = new String[]{"String 1", "String 2", "String 3"};
    String[] group2 = new String[]{"String 1", "String 2", "String 3"};

    boolean result = compareGroups(group1, group2);
于 2009-01-06T14:19:53.683 回答