【问题标题】:Anagram algorithm in javajava中的字谜算法
【发布时间】:2012-11-21 10:45:35
【问题描述】:

我想做字谜算法但是 此代码不起作用。我的错在哪里? 例如 des 和 sed 是字谜,但输出不是字谜 同时我必须使用字符串方法。不是数组。 :)

public static boolean isAnagram(String s1 , String s2)
{
    String delStr="";
    String newStr="";

    for(int i=0;i<s1.length();i++)
    {
        for(int j=0 ; j < s2.length() ; j++)
        {
            if(s1.charAt(i)==s2.charAt(j))
            {
                delStr=s1.substring(i,i+1);
                newStr=s2.replace(delStr,"");
            }
        }           
    }

    if(newStr.equals(""))
        return true;
    else
        return false;
}

【问题讨论】:

  • 你能解释一下你看到了什么错误吗?是否抛出异常?它只是没有返回您的期望吗?它是无限循环的吗?
  • 你能举个例子说明Anagram在你的情况下是什么吗?
  • 不,只有我写了 des 和 sed 但输出不是字谜
  • 为什么你的代码不起作用?因为每次匹配时都会用s2(少一个字母)覆盖newStr。比如s2ab,当你匹配b时,newStr变成a,那么当你匹配a时,newStr不会变成空字符串,而是变成b (因为它是 s2 减去匹配字符)。它不是代码中唯一的错误(重复字符、不同长度的字符串),但它是您将首先看到的错误。
  • 可能值得注意的是,在这么长时间之后,Java 已经取得了足够的进步,使其成为单行:Arrays.equals( a.chars().filter(Character::isAlphabetic).sorted().toArray(), b.chars().filter(Character::isAlphabetic).sorted().toArray());

标签: java algorithm data-structures anagram


【解决方案1】:

一种更简单的方法可能是对两个字符串中的字符进行排序,然后比较它们是否相等:

public static boolean isAnagram(String s1, String s2){

        // Early termination check, if strings are of unequal lengths,
        // then they cannot be anagrams
        if ( s1.length() != s2.length() ) {
            return false;
        }
        s1=s1.toLowerCase();
        s2=s2.toLowerCase();
        char[] c1 = s1.toCharArray();
        char[] c2 = s2.toCharArray();
        Arrays.sort(c1);
        Arrays.sort(c2);
        String sc1 = new String(c1);
        String sc2 = new String(c2);
        return sc1.equals(sc2);
}

我个人认为它比嵌套的 for-loops 更具可读性 =p

这具有 O(n log n) 运行时复杂度,其中n 是较长字符串的长度。

编辑:这不是最佳解决方案。请参阅@aam1r 的答案以了解最有效的方法(即您在面试中应该实际说的话)

【讨论】:

  • 哈哈。 +1 您可以使用 Arrays.equals() 来比较排序后的数组。
  • @PeterLawrey:或者使用一个简单的循环,这是等效的。但不是这个
  • @user1873885 不幸的是,“不起作用”并没有给我任何可以用来帮助您的信息 =(
  • @sampson-chen 我不明白问题。我写 des 和 sed 但输入不是字谜。同时我不使用数组类。只有字符串方法
  • @durron597 - 是的,aam1r 的答案是最佳解决方案,请投票赞成。
【解决方案2】:

这可以在使用恒定空间的线性时间内完成。这是帮助您入门的伪代码:

// Create new hashtable/hashmap to keep track of how many times each character
// is being used
character_map -> new hash map

// Initial check. If lengths are not the same, they can't be anagrams.
if s1.length != s2.length:
    throw exception "Not anagrams"

// Add all characters from s1 to hashmap. Increment the value to keep track of
// number of occurences
foreach character c1 in s1:
    character_map[c1]++

// Iterate through all character in s2 and decrement count of each character.
foreach character c2 in s2:
    character_map[c2]--

// If they are anagrams, each character should be at "0" count at the point.
// If we come across a character that is not, it means that they are not anagrams
foreach key k, value v in character_map:
    if v != 0:
            throw exception "Not anagrams"

这段代码没有排序,因此可以使用简单的循环来完成。总运行时间为 O(n),总空间为 O(1)——因此是最快的解决方案。您可以在哈希图中拥有的元素数量是恒定的(即您知道字母集中有多少项目)。

【讨论】:

  • 啊,桶排序,我的英雄。 +1。顺便说一句,这是O(1) 空间,而不是O(n)
  • 如果长度不同,就不能是字谜。 -> 首先删除空格。
【解决方案3】:
if(s1.charAt(i)==s2.charAt(j))
        delStr=s1.substring(i,i+1);
        newStr=s2.replace(delStr,"");

这段代码很好地展示了为什么你应该在你的if 周围总是有curly braces,即使只有一个语句。你的第二个任务实际上是在if-condition 之外,并且总是会发生。

检查两个字符串是否为Anagram 的最佳方法是将它们转换为字符数组(String#toCharArray)。然后使用Arrays.sort 方法对它们进行排序。并对它们进行比较。


更新:-

如果您只想使用String 方法,那么您实际上不需要嵌套循环。只需一个即可。

这是你修改后的代码:-

public static boolean isAnagram(String s1 , String s2){

    if (s1.length() != s2.length()) {
        return false;
    }

    for(int i = 0; i < s2.length(); i++) {

            if( !s1.contains("" + s2.charAt(i))) {
                return false;
            }

            s1 = s1.replaceFirst("" + s2.charAt(i), "");
            s2 = s2.replaceFirst("" + s2.charAt(i), "");
    }
    return true;
}

【讨论】:

  • 是的,我同意。始终建议在 if 周围使用 curly braces
  • @user1873885。也许。但要让它工作,你需要知道Anagram 是什么?看不懂代码的逻辑。
  • @durron597 是的,代码仍然不起作用,这就是为什么它还没有被接受:P,赞成是为了指出代码中的错误。
  • @durron597..啊!实际上,这是我在代码中能注意到的唯一逻辑错误,因为我不知道 Anagram OP 在说什么。
  • @GanGnaMStYleOverFlowErroR:这个帖子中现在有三个正确答案,所有这些答案的赞成票都比这个答案少。 Rohit,你现在应该给自己一个纪律严明的徽章;)
【解决方案4】:

按排序顺序比较字符串会更有效。

public static boolean isAnagram(String s1 , String s2) {
    return s1.length() == s2.length() 
        && checkSum(s1) == checkSum(s2)
        && Arrays.equals(lettersSorted(s1), lettersSorted(s2));
}

static long checkSum(String s) {
    long sqrSum = 0;
    for(int i = 0; i < s.length(); s++) {
       char ch = s.charAt(i);
       sqrSum += ch + (1L << ch);
    }
}

static char[] lettersSorted(String s) {
    char[] chars = s.toCharArray();
    Arrays.sort(chars);
    return chars;
}

这是一个 O(N ln N) 算法,但如果字符串通常不是字谜,则平均为 O(N)。

【讨论】:

  • 哈哈,到目前为止,我们只有 3 个人 - 关于伟大思想和所有人的格言,嗯? ;)
  • @sampson-chen 所以我添加了一些不同的东西。 ;)
  • @PeterLawrey 哈哈,那会更快,太糟糕了,我已经为你投票了;)
  • 这里 checkSum 方法的目的是什么?
  • 除了检查总和之外,您还可以在同一循环中检查 XOR。 sum 和 XOR 的组合应该使“冲突”相当罕见。
【解决方案5】:

我不确定你要做什么,但我很确定它不会起作用(它在 O(n^2) 中运行。试试这个(在 O(n log n) 中运行):

public static boolean isAnagram(String s1, String s2){
  if (s1.length() != s2.length()) return false;

  char[] c1 = s1.toCharArray();
  char[] c2 = s2.toCharArray();

  Arrays.sort(c1);
  Arrays.sort(c2);

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

  return true;
}

【讨论】:

【解决方案6】:

有多种可能的解决方案来确定字符串是否为 Anagram。 1.使用Array.sort()预定义的方法

String string1 = "abc";
String string2 = "bca";
char[] chars = string1.toCharArray();
char[] chars2 = string2.toCharArray();
Arrays.sort(chars);
Arrays.sort(chars2);
string1 = new String(chars);
string2 = new String(chars2);
if (string1.equalsIgnoreCase(string2)) {
  System.out.println("Anagram");
} else {
  System.out.println("Not Anagram");
}

时间复杂度:Ω(n log n) 2.通过迭代方法

char [] charArray = str.toCharArray();
if(str.length() == str1.length()){
    for(char ch : charArray){
        if(str1.indexOf(ch) == -1){
            System.out.println("Not Anagram");
        } 
    }    
    System.out.println("Anagram");
} else {
    System.out.println("Not Anagram");
}

时间复杂度:Ω(n)

虽然,第一种算法更易读,第二种算法确实执行得更快。

【讨论】:

  • 如果您想以不区分大小写的方式测试字谜,您应该在排序前将两个字符串都转换为小写(或大写)。否则 {'Z', 'a'}{'A', 'z'} 都按排序顺序排列,字符串不会相等,忽略大小写。第二个“迭代”算法不适用于字符串"aab""abb"
  • 你还可以在 index check if 语句中添加一个 break 语句来提高效率
【解决方案7】:

不起作用的原因:

以“des”和“sed”为例。

在匹配的最后一次迭代中,它将评估:

if(s1.charAt(i)==s2.charAt(j))
{
    delStr=s1.substring(i,i+1);
    newStr=s2.replace(delStr,"");
}

这将是:if( "s" == "s" )

然后它会进入 if 块,并评估

newStr = "sed".replace("s","");

这会给你“ed”,而不是一个空字符串。

这个故事的寓意是你总是从 s2 中替换字符减去一个字符,这永远不会是空的。

无论如何,使用 String.replace() 是不好的,因为默认情况下它将替换字符的所有实例。使用 String.replace(),它会将“sed”视为“seeeeeeed”的字谜。你最好使用 String.replaceFirst()。

无论如何,首先要进行以下修改:

String newStr = s2;
...
// inside if block
newStr = newStr.replaceFirst( delStr, "" );

【讨论】:

    【解决方案8】:

    下面是一个简洁的代码 sn-p,它在两个字符串的单次迭代中确定两个字符串是否是字谜,再加上一个 256 元素数组的最终迭代。这种方法避免了对字符串中的字符进行排序,并通过在映射数组中记录字符数来避免在字符串/字符数组之间进行转换。

    static boolean isAnagram(String s1, String s2) {
        if (s1.length() != s2.length()) return false;
        int n = s1.length();
        int[] charMap = new int[256];
        for (int i = 0; i < n; i++) {
            char c1 = s1.charAt(i);
            charMap[c1]++;
            char c2 = s2.charAt(i);
            charMap[c2]--;
        }
        for (int i = 0; i < charMap.length; i++) {
            if (charMap[i] != 0) return false;
        }
        return true;
    }
    

    这段代码基本上是递增和递减数组中对应于字符的索引位置。如果任何数组元素在迭代结束时不为零,则增量和减量的数量不相等,因此字符串包含不同的字符并且不能是彼此的字谜。

    鉴于此算法迭代两个相同大小的字符串一次,运行时间为 O(n)。空间复杂度为 O(1),因为 charMap 始终根据字符集要求保持不变。

    【讨论】:

      【解决方案9】:
      import java.util.Scanner;
      
      public class Anagrams {
      
      static boolean isAnagram(String a, String b) {
          a = a.toLowerCase();
          b = b.toLowerCase();
          if (a.length() != b.length()) {
              return false;
          }
      
          char[] chars = a.toCharArray();
          for (char c : chars) {
              int index = b.indexOf(c);
              if (index != -1) {
                  b = b.substring(0, index) + b.substring(index + 1, b.length());
              } else {
                  return false;
              }
          }
          return b.isEmpty();
      }
      
      public static void main(String[] args) {
          Scanner scan = new Scanner(System.in);
          String a = scan.next();
          String b = scan.next();
          scan.close();
          boolean ret = isAnagram(a, b);
          System.out.println((ret) ? "Anagrams" : "Not Anagrams");
      
          }
      }
      

      【讨论】:

        【解决方案10】:
        public boolean checkAnagram(String s, String t) {
            s = s.toLowerCase();
            t = t.toLowerCase();
        
            // We can ignore blanks
            char[] word1 = s.replaceAll("\\s","").toCharArray();
            char[] word2 = t.replaceAll("\\s","").toCharArray();
        
            // Anagrams length should be the same
            if (word1.length != word2.length) {
                return false;
            }
        
            // Sorting arrays is pretty fast, it can be O(logn) 
            Arrays.sort(word1);
            Arrays.sort(word2);
        
            if (Arrays.equals(word1, word2)) {
                return true;
            }
        
            return false;
        }
        

        【讨论】:

          【解决方案11】:

          O(n) 解决方案,无需任何排序且仅使用一张地图。还添加了其他解决方案中缺少的正确空检查。

          public boolean isAnagram(String leftString, String rightString) {
            if (leftString == null || rightString == null) {
              return false;
            } else if (leftString.length() != rightString.length()) {
              return false;
            }
          
            Map<Character, Integer> occurrencesMap = new HashMap<>();
          
            for(int i = 0; i < leftString.length(); i++){
              char charFromLeft = leftString.charAt(i);
              int nrOfCharsInLeft = occurrencesMap.containsKey(charFromLeft) ? occurrencesMap.get(charFromLeft) : 0;
              occurrencesMap.put(charFromLeft, ++nrOfCharsInLeft);
              char charFromRight = rightString.charAt(i);
              int nrOfCharsInRight = occurrencesMap.containsKey(charFromRight) ? occurrencesMap.get(charFromRight) : 0;
              occurrencesMap.put(charFromRight, --nrOfCharsInRight);
            }
          
            for(int occurrencesNr : occurrencesMap.values()){
              if(occurrencesNr != 0){
                return false;
              }
            }
          
            return true;
          }
          

          和不太通用的解决方案,但更快一点:

          public boolean isAnagram(String leftString, String rightString) {
            if (leftString == null || rightString == null) {
              return false;
            } else if (leftString.length() != rightString.length()) {
              return false;
            }
          
            char letters[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
            Map<Character, Integer> occurrencesMap = new HashMap<>();
            for (char l : letters) {
              occurrencesMap.put(l, 0);
            }
          
            for(int i = 0; i < leftString.length(); i++){
              char charFromLeft = leftString.charAt(i);
              Integer nrOfCharsInLeft = occurrencesMap.get(charFromLeft);
              occurrencesMap.put(charFromLeft, ++nrOfCharsInLeft);
              char charFromRight = rightString.charAt(i);
              Integer nrOfCharsInRight = occurrencesMap.get(charFromRight);
              occurrencesMap.put(charFromRight, --nrOfCharsInRight);
            }
          
            for(Integer occurrencesNr : occurrencesMap.values()){
              if(occurrencesNr != 0){
                return false;
              }
            }
          
            return true;
          }
          

          【讨论】:

          • 唯一真正值得一读的答案和解决方案。
          • 呵呵。谢谢:)。
          【解决方案12】:
          Using HashMap
          public boolean isAnagram(String word, String anagram) {
              if (word.length() != anagram.length())
                  return false;
          
              int count = 0;
              Map<Character, Integer> map = new HashMap<>();
          
              for (int i = 0; i < word.length(); i++) {
                  if (!map.containsKey(word.charAt(i)))
                      map.put(word.charAt(i), 1);
                  else
                      map.put(word.charAt(i), map.get(word.charAt(i)) + 1);
              }
          
              for (int i = 0; i < anagram.length(); i++) {
                  if (!map.containsKey(anagram.charAt(i)))
                      return false;
                  else if (map.get(anagram.charAt(i)) >= 1)
                      map.put(anagram.charAt(i), map.get(anagram.charAt(i)) - 1);
                  else
                      return false;
              }
          
              return true;
          }
          

          【讨论】:

            【解决方案13】:

            只是确保,您正在尝试检查 s1 是否是 s2 的字谜正确?这也意味着 s2 是 s1 的字谜。所以我只会对 s1 和 s2 进行排序并检查它们是否相等。

            String string1 = "fdafdas";
            String string2 = "fdwqkjl";
            char[] chars = string1.toCharArray();
            char[] chars2 = string2.toCharArray();
            Arrays.sort(chars);
            Arrays.sort(chars2);
            string1 = new String(chars);
            string2 = new String(chars2);
            if (string1.equals(string2)) {
                //They are an anagram
            }
            

            【讨论】:

            • 哎呀,不知道有这么多人发布同样的东西。我的错。
            【解决方案14】:

            这是一个更简单的方法,主要依赖于 java 完整的代码在这里https://github.com/rdsr/algorithms/blob/master/src/jvm/misc/AnagramsList.java(注意这解决了一个不同的问题)

            class Anagram {
                Map<Character, Integer> anagram;
            
                Anagram(String s) {
                    anagram = new HashMap<Character, Integer>();
            
                    for (final Character c : s.toCharArray()) {
                        if (anagram.containsKey(c)) {
                            anagram.put(c, 1 + anagram.get(c));
                        } else {
                            anagram.put(c, 1);
                        }
                    }
                }
            
                @Override
                public int hashCode() {
                    //.. elided
                }
            
                @Override
                public boolean equals(Object obj) {
                    //.. elided
                }
            }
            
            
                public class Anagrams {
                        public static void main(String[] args) {
                            System.out.println(new Anagram("abc").equals(new Anagram("bac")));
                        }
                    }
            

            【讨论】:

            • 一个建议。你可以得到 anagram.get(c) 并检查 null 而不是 containsKey (你迭代两次只是为了检查)
            【解决方案15】:

            使用位向量方法处理字谜子串的更快版本

            public boolean isAnagram(String _source1, String _source2)
            {
            
                int flag = 0, char_index = 0, counter = 0;
                if(_source2.length() < _source1.length()){
                    return false;
                }
                char[] _stringchar = _source1.toCharArray();
                char[] _tocheck = _source2.toCharArray();
                for(char character : _stringchar)
                {
                    char_index = character - 'a';
                    if((flag & (1 << char_index)) == 0)
                        flag |= (1 << char_index);
                }
            
                for(char toCheckcChar : _tocheck)
                {
                    char_index = toCheckcChar - 'a';
            
                    if((flag & (1 << char_index)) > 0)
                        counter++;
                    else
                        counter = 0;
            
                    if(counter == _source1.length())
                        return true;
            
                }
            
                return false;
            }
            

            【讨论】:

              【解决方案16】:

              原因很简单,因为替换函数创建了一个新的String 对象。它对实际字符串(在您的情况下为 s2)没有任何作用,因为在 Java 中,字符串本质上是最终的。因此,正如 cmonkey 所指出的,您总是从字符串 s2 中删除一个字符,但实际上创建的新 String 对象少了 1 个字符,s2 保持原样。

              在你的情况下让它工作的简单方法是创建一个新的字符串对象并将它分配给你自己。

              {
                  s2=s2.replace(delString,"");
                  ....
                  if(s2.empty()) return true;
                  return false;
              }
              

              【讨论】:

                【解决方案17】:

                有一次我做了一个关于字谜的求职面试测试。我将它上传到我的 github 帐户。 java代码检查一个文本文件(多行)是否是一个字谜诗或字谜文本。

                https://github.com/javocsoft/anagram_poem_checker

                希望对你有帮助!

                再见。

                【讨论】:

                  【解决方案18】:

                  只看一线 newStr=s2.replace(delStr,"");

                  你在这里做什么 替换 s2 中的 char 并分配回 newStr,意味着您没有更改 s2 中的任何内容。只需将此代码替换为以下代码即可正常工作

                  newStr=newStr.replace(delStr,"");

                  【讨论】:

                    【解决方案19】:

                    我花了一些时间来实际写下逻辑并编写代码来检查两个字符串是否是字谜。 当然是在上面的答案的帮助下!呵呵

                    public static void main(String[] args) {
                    
                        Map<Character, Integer> char_map = new HashMap<Character, Integer>();
                        Map<Character, Integer> empty_map = new HashMap<Character, Integer>();
                        String a = "HelloP";
                        String b = "HePlol";
                    
                        if (a.length() != b.length()) {
                            System.out.println("false");
                            System.exit(0);
                        }
                    
                        for (char c : a.toLowerCase().toCharArray()) {
                            empty_map.put(c, 0);
                            if (char_map.containsKey(c))
                                char_map.put(c, 1 + char_map.get(c));
                            else
                                char_map.put(c, 1);
                        }
                    
                        for (char c : b.toLowerCase().toCharArray())
                            if (char_map.containsKey(c))
                                char_map.put(c, char_map.get(c) - 1);
                    
                        System.out.println(char_map.equals(empty_map));
                    }
                    

                    【讨论】:

                    • (我不太喜欢 empty_map 这个名字。)您可以使用 old = char_map.put(c, 1); if (null != old) char_map.put(c, old + 1) 来减少每个字符的查找次数。
                    【解决方案20】:

                    我认为这适用于复杂度 O(2n)

                    public static boolean isAnagram(String str1, String str2){
                        if(str1.length() != str2.length()){ return false;}
                        int[] buffer = new int[256];
                        for(char ch : str1.toCharArray()){
                            buffer[ch]++;
                        }
                        for(char ch : str2.toCharArray()){
                            if(buffer[ch]==0) return false;
                            buffer[ch] = (buffer[ch] > 0)?(buffer[ch] - 1 ): -1 ;   
                        }
                        return true;
                    }
                    

                    【讨论】:

                      【解决方案21】:

                      这是我为使用数组而不是 HashMap 而编写的 Java 实现。这样可以节省空间,而且数组非常快。

                      public static boolean anagram(String s, String t) { 
                              if (s.length() != t.length()) return false;
                      
                              int[] arr = new int[123];
                              for (char c : s.toCharArray())
                                  arr[c]++;
                              for (char c : t.toCharArray())
                                  arr[c]--;
                              for (int i : arr)
                                  if (i != 0)
                                      return false;
                              return true;
                          }
                      

                      【讨论】:

                        【解决方案22】:
                        import java.util.Scanner;
                        
                        public class JavaProgram
                        {
                            public static void main(String[] input)
                            {
                                String str1, str2;
                                int len, len1, len2, i, j, found=0, not_found=0;
                                Scanner scan = new Scanner(System.in);
                        
                                System.out.print("Enter First String : ");
                                str1 = scan.nextLine();
                                System.out.print("Enter Second String : ");
                                str2 = scan.nextLine();
                        
                                len1 = str1.length();
                                len2 = str2.length();
                        
                                if(len1 == len2)
                                {
                                    len = len1;
                                    for(i=0; i<len; i++)
                                    {
                                        found = 0;
                                        for(j=0; j<len; j++)
                                        {
                                            if(str1.charAt(i) == str2.charAt(j))
                                            {
                                                found = 1;
                                                break;
                                            }
                                        }
                                        if(found == 0)
                                        {
                                            not_found = 1;
                                            break;
                                        }
                                    }
                                    if(not_found == 1)
                                    {
                                        System.out.print("Strings are not Anagram to Each Other..!!");
                                    }
                                    else
                                    {
                                        System.out.print("Strings are Anagram");
                                    }
                                }
                                else
                                {
                                    System.out.print("Both Strings Must have the same number of Character to be an Anagram");
                                }
                            }
                        }
                        

                        【讨论】:

                        • 您应该先测试您的代码,然后再将其作为答案发布。
                        【解决方案23】:
                        public class Anagram {
                            public boolean isAnagram(
                                    String left, 
                                    String right) {
                                if (left.length() == right.length()) {
                                    Map<Character, Integer> map = new HashMap<>();
                                    char[] a = left.toCharArray(), b = right.toCharArray();
                                    for (int i = 0; i < a.length; i++) {
                                        accumulate(map, a[i]);
                                        accumulate(map, b[i]);
                                    }
                                    for (char c : map.keySet()) {
                                        if (map.get(c) > 0) {
                                            return false;
                                        }
                                    }
                                    return true;
                                } else {
                                    return false;
                                }
                            }
                        
                            private void accumulate(
                                    Map<Character, Integer> map, 
                                    char key) {
                                if (map.containsKey(key)) {
                                    map.put(key, Math.abs(map.get(key) - 1));
                                } else {
                                    map.put(key, 1);
                                }
                            }
                        }
                        

                        【讨论】:

                          【解决方案24】:

                          这是我从你的角度来看的解决方案

                          private static boolean isAnagram(String s1, String s2){
                              int count = 0;
                              boolean flag = false;
                          
                              if(s1.length() != s2.length()){
                                  return false;
                              }
                              //checks whether both word's letters are the same
                              for (int i = 0; i < s1.length(); i++){
                                  for (int j = 0; j < s2.length(); j++){
                                      if(s1.charAt(i) == s2.charAt(j)){
                                          count++;
                                          break;
                                      }
                                  }
                              }
                              //if count equals to one of the Strings length then it is an anagram
                              if(count == s2.length() ){
                                  flag = true;
                              }
                              return flag;
                          }
                          

                          【讨论】:

                            【解决方案25】:
                                String str1="Mother In Law";
                                String str2="Hitler Woman";
                                char[] anag1=str1.replaceAll("\\s", "").toLowerCase().toCharArray();
                                char[] anag2=str2.replaceAll("\\s", "").toLowerCase().toCharArray();
                                Arrays.sort(anag1);
                                Arrays.sort(anag2);
                                System.out.println(Arrays.equals(anag1, anag2)? "words are anagrams":"words are not anagrams");
                            

                            【讨论】:

                              【解决方案26】:

                              我猜下面的解决方案有O(n) 的复杂性,如果有人不同,请告诉我。

                              import java.util.HashMap;
                              import java.util.Scanner;
                              
                              
                              public class Anagrams {
                              
                                  static boolean isAnagram(String word1, String word2)
                                  {
                                      if(word1.length() != word2.length()) {
                                          return false;
                                      }
                                      int flag=0;
                                      HashMap<Character,Integer> table = new HashMap<Character,Integer>();
                                      for(int i=0; i< word1.length();i++) {
                                          table.put(word1.charAt(i),1);
                                      }
                              
                                      for(int i=0; i< word2.length();i++) {
                                          if(table.containsKey(word2.charAt(i))) {
                                              continue;
                                          } else {
                                              flag=1;
                                              break;
                                          }   
                                      }
                                      return flag == 0;
                                  }
                              
                                  public static void main(String[] args) {
                                      System.out.println("Enter your string");
                                      Scanner sc= new Scanner(System.in);
                                      String word1= sc.nextLine();
                                      String word2=sc.nextLine();
                              
                                       boolean result = isAnagram(word1,word2);
                                       if(result) {
                                           System.out.println("The words are Anagrams");
                                       } else{
                                           System.out.println("The words are not Anagrams");   
                                       }
                                  }
                              }
                              

                              【讨论】:

                              • 调用地图 'table' :(。在不需要时使用 continue 和 break。嗯。
                              • @goroncy 如果你想让它变得更好,我希望你修改和发布。 “table”只是一个随机名称,我没有在某些实际产品中使用此代码。只是在练习。
                              • 是的。继续和中断仍然存在。
                              • @SahilMadan 我对您的代码进行了基本重构。我认为您可以完成剩下的工作。
                              【解决方案27】:
                              public static boolean isAnagram(String s1, String s2) {
                                  boolean aux = true;
                                  if (s1.length() != s2.length()){
                                      aux = false;
                                  }else{ 
                                      for (int i = 0; i < s1.length(); i++)
                                          if(s2.toUpperCase().indexOf(s1.toUpperCase().substring(i, i+1)) == -1) aux = false;
                                  }
                                  return aux;
                              }
                              

                              【讨论】:

                                【解决方案28】:
                                public class SampleAnagram {
                                
                                    public static void main(String ...s) {
                                
                                
                                        String s1 = "work";
                                        String s2="kwro";
                                
                                        System.out.println(s1.charAt(0));
                                
                                        int s1L = s1.length();
                                        int s2L = s2.length();
                                
                                        int totalCount = 0;
                                
                                            for(int i=0;i<s1L;i++) {
                                
                                                for(int j=0;j<s2L;j++) {
                                
                                                if(s1.charAt(i)==(s2.charAt(j))) {
                                
                                                    totalCount = totalCount+1;
                                                }
                                            }
                                        }
                                
                                            System.out.println(totalCount);
                                
                                
                                            if(s1.length()==totalCount && s2.length()==totalCount) {
                                
                                                System.out.println("given the input as anagram");
                                            }
                                
                                    }
                                
                                
                                
                                }
                                

                                【讨论】:

                                  【解决方案29】:

                                  这是另一个建议,不初始化 int[256],而是初始化英文字母的 int[26]。

                                  public static void main(String[] args) {
                                      System.out.println(isAnagram("restful", "fluster"));
                                  }
                                  
                                  static boolean isAnagram(String s1, String s2) {
                                      if (s1.length() != s2.length()) {
                                          return false;
                                      }
                                      int[] countArray = new int[26];
                                      for (int i = 0; i < s1.length(); i++) {
                                          countArray[getIndex(i, s1)]++;
                                          countArray[getIndex(i, s2)]--;
                                      }
                                      for (int i = 0; i < countArray.length; i++) {
                                          if (countArray[i] != 0) {
                                              return false;
                                          }
                                      }
                                      return true;
                                  }
                                  
                                  public static int getIndex(int position, String value) {
                                      return value.charAt(position) - 'a';
                                  }
                                  

                                  最好的 乔治·佐普里迪斯

                                  【讨论】:

                                    【解决方案30】:
                                    public static boolean isAnagram(String s1, String s2) {
                                        if (s1.length() != s2.length()) {
                                            return false;
                                        }
                                        Map<Character, Integer> frequencies = new HashMap<>();
                                        for (int i = 0; i < s1.length(); i++) {
                                            if (frequencies.containsKey(s1.charAt(i))) {
                                                frequencies.put(s1.charAt(i), frequencies.get(s1.charAt(i)) + 1);
                                            } else {
                                                frequencies.put(s1.charAt(i), 1);
                                            }
                                        }
                                        for (int i = 0; i < s2.length(); i++) {
                                            if (frequencies.containsKey(s2.charAt(i))) {
                                                int frequency = frequencies.get(s2.charAt(i));
                                                if (--frequency == 0) {
                                                    frequencies.remove(s2.charAt(i));
                                                } else {
                                                    frequencies.put(s2.charAt(i), frequencies.get(s2.charAt(i)) - 1);
                                                }
                                            }
                                        }
                                        return frequencies.isEmpty();
                                    }
                                    

                                    【讨论】:

                                    • 该算法时间复杂度为O(N),空间复杂度为O(N)
                                    猜你喜欢
                                    • 2021-09-13
                                    • 2011-11-03
                                    • 2012-05-25
                                    • 2011-01-17
                                    • 2010-09-08
                                    • 2010-12-01
                                    • 2012-11-03
                                    • 2016-11-15
                                    • 2019-02-02
                                    相关资源
                                    最近更新 更多