【问题标题】:Finding anagram using hashmap使用哈希图查找字谜
【发布时间】:2020-11-24 01:02:02
【问题描述】:

这是我的 java 解决方案,用于确定 t 是否是 s 的字谜(返回真或假)。当涉及到非常大的字符串时它会失败(例如,输出:false,预期:true)。

我的代码有什么问题?

import java.util.HashMap;
import java.util.Map;

public class solution {
    public static void main(String[] args){
    String s = "anfefeg";    // true
    String t = "fegafen";
    System.out.println(isAnagram(s,t));
    }
    public static boolean isAnagram(String s, String t) {
        defaultHashMap<Character, Integer> countS = new defaultHashMap<>(0);
        defaultHashMap<Character, Integer> countT = new defaultHashMap<>(0);
        if (s.length() != t.length()){
            return false;
        }
        // count frequencies of characters 
        for (int i=0; i < s.length(); i++){
            countS.put(s.charAt(i), countS.get(s.charAt(i)) + 1);
            countT.put(t.charAt(i), countT.get(t.charAt(i)) + 1);
        }
//        System.out.println(countS.entrySet());
//        System.out.println(countT.entrySet());

        // compare to map
        for (Map.Entry<Character, Integer> entry : countT.entrySet()){
            if (entry.getValue() != countS.get(entry.getKey())){
                return false;
            }
        }
        return true;
    }
}
/*
define a defaultHashMap class extending hashmap
*/
class defaultHashMap <K,V> extends HashMap<K,V> {
    protected V defaultValue;
    public defaultHashMap(V defaultValue) {
        this.defaultValue = defaultValue;
    }
    @Override
    public V get(Object k) {
        return containsKey(k) ? super.get(k) : defaultValue;
    }

}

【问题讨论】:

标签: java


【解决方案1】:

我会说这是因为您将Integer 实例与!= 进行比较,而不是equals。 Java 通常会缓存 Integer 的小值,因此如果您将像 5 这样的小数字多次转换为 Integer,它通常会返回完全相同的对象,这可能就是您的程序适用于小字符串的原因。

但是当你开始创建大整数时,就像你的程序会为非常长的字符串做的那样,那么 Java 每次都会创建一个新的整数,所以即使值相同,对象也不同,== 和 @ 987654327@ 不起作用,您必须改用equals

这应该可以解决您的问题。改变

        if (entry.getValue() != countS.get(entry.getKey())) {
            return false;
        }

        if (! entry.getValue().equals(countS.get(entry.getKey()))) {
            return false;
        }

【讨论】:

  • 有效!!!太感谢了!在这里学到了很多,对于java初学者来说真的很重要!
【解决方案2】:

通过ArrayList的另一种方式:

public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);

    System.out.println("Enter 1st string");
    String string1 = sc.nextLine().toLowerCase();

    System.out.println("Enter 2nd string");
    String string2 = sc.nextLine().toLowerCase();

    ArrayList<Character> arr1 = new ArrayList<>();
    ArrayList<Character> arr2 = new ArrayList<>();

    //Adding chars of a string to ArrayList
    for (Character c : string1.toCharArray()) {
        arr1.add(c);
    }

    //Adding chars from a string to ArrayList
    for (Character c : string2.toCharArray()) {
        arr2.add(c);
    }

    Collections.sort(arr1);
    Collections.sort(arr2);

    if (arr1.equals(arr2)) {
        System.out.println("BOTH STRINGS ARE ANAGRAM");
    } else
        System.out.println("STRINGS ARE NOT ANAGRAM !!");

    sc.close();
}

【讨论】:

    【解决方案3】:

    我们可以使用map来做高效的事情,时间复杂度是O(n)

    package com.test;
    
    import java.util.HashMap;
    
    public class Anagram {
        public static void main(String ar[]) {
            String str="anagram";
            String str1="anagram";
            char ch[]=str.toCharArray();
            char ch1[]=str1.toCharArray();
            HashMap<?, ?> map=constructMap(ch);
            HashMap<?, ?> mapq=constructMap(ch1);
            if(map.equals(mapq)) {
                System.out.println("Both are Anagram");
            }else {
                System.out.println("Not");
            }
        }
    
        private static HashMap<Character, Integer> constructMap(char[] ch) {
            // TODO Auto-generated method stub
            HashMap<Character, Integer> map=new HashMap<Character, Integer>();
            for(int i=0;i<ch.length;i++) {
            if(!map.containsKey(ch[i])) {
                map.put(ch[i],0);
            }else {
                map.put(ch[i], map.get(ch[i])+1);
            }
            }
            return map;
        }
    }
    

    【讨论】:

      【解决方案4】:

      对于 String1 中的每个字符,在 HashMap 中输入一个键值对,其中键是字符,值是它的计数。 然后对于 String2 迭代其字符,如果字符存在于 HashMap 中,则减少与该字符关联的计数,否则返回 false。 最后检查HashMap中是否有任何key的值大于0,如果是则返回false。 最后返回true。

      groovy 中的代码:

          def checkIfAnagram(String s1, String s2){
            if(s1.length()!=s2.length())
              return false
          
            HashMap<String,Integer> dict = new HashMap<String,Integer>();
            for(String s:s1.split("")){
              if(dict[s]){
                  dict[s] = dict[s]+1;
              }
              else{
                  dict[s] = 1;
              }
            }
          
            for(String s:s2.split("")){
              if(!dict[s]){
                  return false
              }
              else{
                  dict[s] = dict[s]-1; 
              }
            }
          
            dict.each{ key,value ->
              if(value > 0){
                  return false
              }
            }
            return true;
          
          }
          
          print(checkIfAnagram("Hello", "olleH"))
      

      【讨论】:

        猜你喜欢
        • 2019-02-02
        • 2016-03-10
        • 2023-04-02
        • 1970-01-01
        • 2012-03-10
        • 1970-01-01
        • 1970-01-01
        • 2011-04-12
        • 2014-08-06
        相关资源
        最近更新 更多