Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中检查两个字符串是否为置换(Hashmap与数组的效率)_Java_Hashmap_Big O - Fatal编程技术网

在Java中检查两个字符串是否为置换(Hashmap与数组的效率)

在Java中检查两个字符串是否为置换(Hashmap与数组的效率),java,hashmap,big-o,Java,Hashmap,Big O,我在读一本编码书,试图学习更多关于Java的知识,遇到了这个问题 问题是:“给定两个字符串,编写一个方法来确定其中一个是否是另一个的排列。” 在仔细考虑了一分钟左右之后,我决定使用Hashmap解决方案。我的逻辑是添加、删除和搜索都是O(1),所以这是一个快速的解决方案。我的代码如下: public static boolean isPermutation(String a, String b) { if(a.length() != b.length()) { r

我在读一本编码书,试图学习更多关于Java的知识,遇到了这个问题

问题是:“给定两个字符串,编写一个方法来确定其中一个是否是另一个的排列。”

在仔细考虑了一分钟左右之后,我决定使用Hashmap解决方案。我的逻辑是添加、删除和搜索都是O(1),所以这是一个快速的解决方案。我的代码如下:

    public static boolean isPermutation(String a, String b) {
    if(a.length() != b.length()) {
        return false;
    }
    HashMap<Character, Integer> map = new HashMap<Character, Integer>();
    for(int x = 0; x < a.length(); x++) {
        char letter = a.charAt(x);
        if(!(map.containsKey(letter))) {
            map.put(letter, 1);
        }
        else {
            int val = map.get(letter) + 1;
            map.put(letter, val);
        }
    }
    for(int y = 0; y < b.length(); y++) {
        char letter = b.charAt(y);
        if(!(map.containsKey(letter))) {
            return false;
        }
        else {
            int val = map.remove(letter) - 1;
            if(val > 0) {
                map.put(letter, val);
            }
        }
    }
    return true;
}
公共静态布尔值isPermutation(字符串a、字符串b){
如果(a.长度()!=b.长度()){
返回false;
}
HashMap=newHashMap();
对于(int x=0;x0){
地图放置(字母,val);
}
}
}
返回true;
}
然而,这本书使用数组作为答案

public boolean permutation(String s, String t) {
    if (s.length() != t.length()) {
        return false;
    }
    int[] letters = new int[256];
    char[] s_array = s.toCharArray();
    for (char c : s_array) {
        letters[c]++;
    }
    for (int i = 0; i < t.length(); i++) {
        int c = (int) t.charAt(i);
        if (--letters[c] < e) {
            return false;
        }
    }
    return true;
}
公共布尔置换(字符串s、字符串t){
如果(s.length()!=t.length()){
返回false;
}
int[]字母=新int[256];
char[]s_数组=s.toCharArray();
for(字符c:s_数组){
字母[c]++;
}
对于(int i=0;i
我有三个问题

首先,我想知道我的实现是否比这本书的效率低——如果是的话,效率低的原因是什么,以及是否可以纠正它们,使Hashmap实现比给定的数组实现更好(或至少相等)

其次,我知道我的Hashmap使用自动装箱将字符转换为字符。自动装箱是否会带来显著的减速

第三,在我的代码中,我试图避免使用Hashmap的remove()函数。我的逻辑是,虽然从理论上讲,删除应该是O(1),但使用put()替换现有密钥(在本例中,覆盖旧值)将更有效,因为替换的成本低于删除然后添加的成本。我的逻辑正确吗?这是我应该做的事吗


多谢各位

首先观察:大Oh符号不是性能的衡量标准。更确切地说,它表明了当变量(例如N)趋于无穷大时,算法将如何扩展

首先,我想知道我的实现是否比这本书的效率低

基准测试他们!说真的,仅仅通过检查代码就很难说哪种方法更快

您的基准需要考虑到这样一个事实,即相对绩效将取决于输入;e、 g.使用不同的字符串长度范围进行测量

。。。如果是这样,效率低下的原因是什么

这就是分析的目的。它会告诉你每种方法花费了多少时间。有些探查器可以测量到行号的级别:

。。。以及是否可以对它们进行纠正,使Hashmap实现比给定的数组实现更好(或至少相等)

这是你要弄清楚的。。。一旦您完成了基准测试和概要分析

其次,我知道我的Hashmap使用自动装箱将字符转换为字符。自动装箱是否会带来显著的减速

经济肯定会放缓。它应该是可测量的(或可估计的)。例如,如果您分析您的版本,您可以看到在
Character
方法中花费了多少时间

这会有意义吗?很难预测

第三,在我的代码中,我试图避免使用Hashmap的remove()函数。。。我的逻辑正确吗

对。但是,您可以再次通过基准测试和/或分析来验证这一点



说了所有这些,我的>>教育猜测“HashMap在下面使用数组,所以它永远不会比正确使用数组更快”:是的,自动装箱确实会产生开销。它还存在其他几个缺陷:请注意,如果字符串可以包含任何Unicode字符(包括字母表中的字母,而不是通常的A-Z、A-Z和西欧字母表),那么本书的答案将不起作用,因为它只为数组分配256个字符。要解决此问题,
字母
需要初始化为
new int[65536]
。在类似的问题中,如果可能的输入元素的数量太大而无法使用数组,则可以使用
HashMap
。@ajb这是我使用HashMap的逻辑的一部分,我想我应该在字符串上节省空间。非常感谢。“book”示例中有一个打字错误:
--字母[c]
应该是
--字母[c]<0