有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用基本Java检查两个字符串是否是彼此的字谜

我正在用JavaNetbeans编写以下代码,这对于普通的字谜来说非常有效。但是,如果这两个文本字段包含包含重复字母的单词,那么代码将无法工作。可能有什么问题,我如何解决?我对Java非常熟悉,还不能理解数组

String s1= t1.getText(); 
String s2= t2.getText();  
int b=0,c=0;
if(s1.length()!=s2.length())
   System.out.print("No");
else {
   for(int i=0;i<s1.length();i++) {
      char s = s1.charAt(i);
      for(int j=0;j<s2.length();j++) {
         if(s==s2.charAt(j)){
            b++;
         } 
      }
      if(b==0)
         break;
   }
   if(b==0)
      System.out.print("No");
   else 
      System.out.print("YES");
} 
System.out.print(b);

共 (5) 个答案

  1. # 1 楼答案

    您想要比较排序的字符。这是一条单行线:

    return Arrays.equals(s1.chars().sorted().toArray(),
        s2.chars().sorted().toArray());
    

    Arrays.equals()为您比较长度和所有元素

  2. # 2 楼答案

    因为您似乎是一个初学者,这里有一个解决方案,它不涉及来自其他类或流的函数。它只涉及数组的使用以及char也可以表示int的事实

    public static void main(String[] args) throws ParseException {
        String s1= "anagram"; 
        String s2= "margana";  
        // We make use of the fact that a char does also represent an int.
        int lettersS1[] = new int[Character.MAX_VALUE];
        int lettersS2[] = new int[Character.MAX_VALUE];
        if(s1.length()!=s2.length())
           System.out.print("No");
        else {
           // Loop through the String once
           for(int i = 0; i<s1.length() ;++i) {
               // we can just use the char value as an index
               // and increase the value of it. This is our identifier how often 
               // each letter was aviable in the String. Alse case insensitive right now
               lettersS1[s1.toLowerCase().charAt(i)]++;
               lettersS2[s2.toLowerCase().charAt(i)]++;
           }
           // set a flag if the Strings were anagrams
           boolean anag = true;
           // We stop the loop as soon as we noticed they are not anagrams
           for(int i = 0;i<lettersS1.length&&anag;++i) {
               if(lettersS1[i] != lettersS2[i]) {
                   // If the values differ they are not anagrams.
                   anag = false;
               }
           }
           // Depending on the former loop we know if these two strings are anagrams
           if(anag) {
               System.out.print("Anagram");
           } else {
               System.out.print("No anagram");
           }
        } 
    }
    
  3. # 3 楼答案

    这里是我的解决方案,我们计算第一个字符串中每个字符的外观,然后从第二个字符串的计数中减去它。最后,检查字符计数是否不是0,则两个字符串不是字谜

    public static boolean isAnagram(String a, String b){
        //assume that we are using ASCII
        int[] charCnt = new int[256];
        for(int i = 0; i < a.length(); i++){
            charCnt[a.charAt(i)]++;
        }
        for(int i = 0; i< b.length(); i++){
            charCnt[b.charAt(i)]--;
        }
        for(int i = 0; i<charCnt.length; i++){
            if(charCnt[i] != 0) return false;
        }
        return true;
    }
    
  4. # 4 楼答案

    基于发生计数器的另一种解决方案:

    static boolean areAnagrams(CharSequence a, CharSequence b) {
        int len = a.length();
        if (len != b.length())
            return false;
    
        // collect char occurrences in "a"
        Map<Character, Integer> occurrences = new HashMap<>(64);
        for (int i = 0; i < len; i++)
            occurrences.merge(a.charAt(i), 1, Integer::sum);
    
        // for each char in "b", look for matching occurrence
        for (int i = 0; i < len; i++) {
            char c = b.charAt(i);
            int cc = occurrences.getOrDefault(c, 0);
            if (cc == 0)                        
                return false;            
            occurrences.put(c, cc - 1);
        }
        return true;
    }
    

    虽然此解决方案不如“排序和比较”优雅,但它可能更有效地处理长字符串,因为它在O(n)而不是O(n logn)中运行,并且在第二个字符串的某个位置未找到匹配项时立即返回


    走出“基本Java”领域,我修改了算法来处理surrogate pairs。这里收集和匹配的不是char码,而是int码点:

    static boolean areAnagrams(CharSequence a, CharSequence b) {
        int len = a.length();
        if (len != b.length())
            return false;
    
        // collect codepoint occurrences in "a"
        Map<Integer, Integer> ocr = new HashMap<>(64);
        a.codePoints().forEach(c -> ocr.merge(c, 1, Integer::sum));
    
        // for each codepoint in "b", look for matching occurrence
        for (int i = 0, c = 0; i < len; i += Character.charCount(c)) {
            int cc = ocr.getOrDefault((c = Character.codePointAt(b, i)), 0);
            if (cc == 0)                        
                return false;            
            ocr.put(c, cc - 1);
        }
        return true;
    }
    
  5. # 5 楼答案

    我想用更简单的理由来解释:两个字符串如果排序后完全匹配,那么它们就是字谜。 因此,在Java中,它类似于:

        String s1 = "cat";
        String s2 = "tac";
        boolean isAnagram = false;
        if (s1.length() == s2.length()) {
            char[] s1AsChar = s1.toCharArray();
            char[] s2AsChar = s2.toCharArray();
            Arrays.sort(s1AsChar);
            Arrays.sort(s2AsChar);
            isAnagram = Arrays.equals(s1AsChar, s2AsChar);
        }