在Java中检查两个字符串是否为置换(Hashmap与数组的效率)
我在读一本编码书,试图学习更多关于Java的知识,遇到了这个问题 问题是:“给定两个字符串,编写一个方法来确定其中一个是否是另一个的排列。” 在仔细考虑了一分钟左右之后,我决定使用Hashmap解决方案。我的逻辑是添加、删除和搜索都是O(1),所以这是一个快速的解决方案。我的代码如下:在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
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.使用不同的字符串长度范围进行测量 。。。如果是这样,效率低下的原因是什么 这就是分析的目的。它会告诉你每种方法花费了多少时间。有些探查器可以测量到行号的级别:
Character
方法中花费了多少时间
这会有意义吗?很难预测
第三,在我的代码中,我试图避免使用Hashmap的remove()函数。。。我的逻辑正确吗
对。但是,您可以再次通过基准测试和/或分析来验证这一点
说了所有这些,我的>>教育猜测“HashMap在下面使用数组,所以它永远不会比正确使用数组更快”:是的,自动装箱确实会产生开销。它还存在其他几个缺陷:请注意,如果字符串可以包含任何Unicode字符(包括字母表中的字母,而不是通常的A-Z、A-Z和西欧字母表),那么本书的答案将不起作用,因为它只为数组分配256个字符。要解决此问题,
字母
需要初始化为new int[65536]
。在类似的问题中,如果可能的输入元素的数量太大而无法使用数组,则可以使用HashMap
。@ajb这是我使用HashMap的逻辑的一部分,我想我应该在字符串上节省空间。非常感谢。“book”示例中有一个打字错误:--字母[c]
应该是--字母[c]<0
。