Finding anagrams for a given word

后端 未结 12 1033
温柔的废话
温柔的废话 2020-12-04 07:43

Two words are anagrams if one of them has exactly same characters as that of the another word.

Example : Anagram & Nagaram are anagrams

相关标签:
12条回答
  • 2020-12-04 08:02

    We know that if two words don't have the same length, they are not anagrams. So you can partition your dictionary in groups of words of the same length.

    Now we focus on only one of these groups and basically all words have exactly the same length in this smaller universe.

    If each letter position is a dimension, and the value in that dimension is based on the letter (say the ASCII code). Then you can calculate the length of the word vector.

    For example, say 'A'=65, 'B'=66, then length("AB") = sqrt(65*65 + 66*66). Obviously, length("AB") = length("BA").

    Clearly, if two word are anagrams, then their vectors have the same length. The next question is, if two word (of same number of letters) vectors have the same length, are they anagrams? Intuitively, I'd say no, since all vectors with that length forms a sphere, there are many. Not sure, since we're in the integer space in this case, how many there are actually.

    But at the very least it allows you to partition your dictionary even further. For each word in your dictionary, calculate the vector's distance: for(each letter c) { distance += c*c }; distance = sqrt(distance);

    Then create a map for all words of length n, and key it with the distance and the value is a list of words of length n that yield that particular distance.

    You'll create a map for each distance.

    Then your lookup becomes the following algorithm:

    1. Use the correct dictionary map based on the length of the word
    2. Compute the length of your word's vector
    3. Lookup the list of words that match that length
    4. Go through the list and pick the anagrams using a naive algorithm is now the list of candidates is greatly reduced
    0 讨论(0)
  • 2020-12-04 08:04

    First check if the length of the strings are the same. then check if the sum of the characters in both the strings are same (ie the ascii code sum) then the words are anagrams else not an anagram

    0 讨论(0)
  • 2020-12-04 08:05

    One solution is - Map prime numbers to alphabet characters and multiply prime number

    For ex - 
    
        a -> 2
        b -> 3
        ......
        .......
        ......
        z -> 101
    

    So

    'ab' -> 6
    'ba' -> 6
    'bab' -> 18
    'abba' -> 36
    'baba' -> 36
    

    Get MUL_number for Given word. return all the words from dictionary which have same MUL_number as given word

    0 讨论(0)
  • 2020-12-04 08:09

    tried to implement the hashmap solution

    public class Dictionary {
    
        public static void main(String[] args){
    
        String[] Dictionary=new String[]{"dog","god","tool","loot","rose","sore"};
    
        HashMap<String,String> h=new HashMap<String, String>();
    
        QuickSort q=new QuickSort();
    
        for(int i=0;i<Dictionary.length;i++){
    
            String temp =new String();
    
            temp= q.quickSort(Dictionary[i]);//sorted word e.g dgo for dog
    
            if(!h.containsKey(temp)){
               h.put(temp,Dictionary[i]);
            }
    
            else
            {
               String s=h.get(temp);
               h.put(temp,s + " , "+ Dictionary[i]);
            }
        }
    
        String word=new String(){"tolo"};
    
        String sortedword = q.quickSort(word);
    
        if(h.containsKey(sortedword.toLowerCase())){ //used lowercase to make the words case sensitive
    
            System.out.println("anagrams from Dictionary   :  " + h.get(sortedword.toLowerCase()));
        }
    
    }
    
    0 讨论(0)
  • 2020-12-04 08:12
    static void Main(string[] args)
    {
    
        string str1 = "Tom Marvolo Riddle";
        string str2 = "I am Lord Voldemort";
    
        str2=  str2.Replace(" ", string.Empty);
        str1 = str1.Replace(" ", string.Empty);
        if (str1.Length != str2.Length)
            Console.WriteLine("Strings are not anagram");
        else
        {
            str1 = str1.ToUpper();
            str2 = str2.ToUpper();
            int countStr1 = 0;
            int countStr2 = 0;
            for (int i = 0; i < str1.Length; i++)
            {
                countStr1 += str1[i];
                countStr2 += str2[i];
    
            }
            if(countStr2!=countStr1)
                Console.WriteLine("Strings are not anagram");
            else Console.WriteLine("Strings are  anagram");
    
        }
        Console.Read();
    }
    
    0 讨论(0)
  • 2020-12-04 08:14

    I came up with a new solution I guess. It uses the Fundamental Theorem of Arithmetic. So the idea is to use an array of the first 26 prime numbers. Then for each letter in the input word we get the corresponding prime number A = 2, B = 3, C = 5, D = 7 … and then we calculate the product of our input word. Next we do this for each word in the dictionary and if a word matches our input word, then we add it to the resulting list. All anagrams will have the same signature because

    Any integer greater than 1 is either a prime number, or can be written as a unique product of prime numbers (ignoring the order).

    Here's the code. I convert the word to UPPERCASE and 65 is the position of A which corresponds to my first prime number:

    private int[] PRIMES = new int[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31,
            37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103,
            107, 109, 113 };
    

    This is the method:

     private long calculateProduct(char[] letters) {
        long result = 1L;
        for (char c : letters) {
            if (c < 65) {
                return -1;
            }
            int pos = c - 65;
            result *= PRIMES[pos];
        }
        return result;
    }
    
    0 讨论(0)
提交回复
热议问题