【问题标题】:Pangram using hashset in javaPangram在java中使用hashset
【发布时间】:2019-07-20 16:21:38
【问题描述】:

我正在尝试通过在 Java 中使用 set 来确定字符串是否为 pangram

我已经尝试了下面的代码。现在输出显示为不是 pangram,但它应该是 pangram。请告诉我我的解决方案有什么问题

    // Java Program to illustrate Pangram 
    import java.util.*;
    public class GFG 
    { 
        public static boolean checkPangram (String str) 
        { 
            int index = 0,count=0; 
            char s[]=str.toCharArray();
            Set<Character> hs= new HashSet<Character>();
            for(index=0;index<str.length();index++)
            {
                hs.add(s[index]); 
            }
            Iterator<Character> i=hs.iterator();
            while(i.hasNext())
            {
              count++;
              i.next();
            }
            if(count==26)
              return true;
            return false;
        } 

        // Driver Code 
        public static void main(String[] args) 
        { 
            String str = "the quick brown fox jumps over the lazy dog"; 

            if (checkPangram(str) == true) 
                System.out.print(str + " is a pangram."); 
            else
                System.out.print(str+ " is not a pangram."); 

        } 
    } 

输出应该是真或假,但我没有得到输出

【问题讨论】:

标签: java string set hashset pangram


【解决方案1】:

Iterator::hasNext 检查是否有下一个元素要迭代,但它没有移动到下一个元素。要将迭代器移动到下一个元素,您必须使用返回下一个元素的Iterator::next。将您的 while 循环更改为:

while (i.hasNext()) {
    count++;
    i.next();
}

在将String 转换为 char 数组之前,您必须删除空格,因为不应将空格考虑用于 pangram。此外,在创建 Set 时,您应该迭代直到达到 char 数组的长度 - 而不是输入字符串的长度(因为我们将删除空格):

public static boolean checkPangram(String str) {
    int index = 0, count = 0;

    char s[] = str.replaceAll("\\s+","") //remove spaces
            .toCharArray();

    Set<Character> hs = new HashSet<Character>();

    for (index = 0; index < s.length; index++) { //iterate over your charArray
        hs.add(s[index]);
    }

    Iterator<Character> i = hs.iterator();

    while (i.hasNext()) {
        count++;
        i.next();
    }

    return count == 26;  //simplified condition result to be returned

}

不过说实话,您根本不需要迭代器。您可以检查设置大小:

public static boolean checkPangram(String str) {
    char[] s = str.replaceAll("\\s+", "")
                .toCharArray();

    Set<Character> hs = new HashSet<Character>();

    for (int index = 0; index < s.length; index++) {
        hs.add(s[index]);
    }

    return hs.size() == 26;
}

【讨论】:

  • 请注意,replaceAll("\\s+", "") 只会消除空格,但句子通常也会包含标点符号,例如一个终止句点,因此您可能希望使用以下正则表达式之一:"[^a-zA-Z]+" (不是 A-Z 范围内的字符)"\\P{Alpha}+" (不是 POSIX “字母字符”) i>,或"\\P{L}+"(非 unicode 类别“字母”)。请注意,unicode 变体将保留重音字母,例如ó,这对于 pangram 检查来说是一组完全不同的问题。
【解决方案2】:

您需要学习如何调试您自己的代码。
What is a debugger and how can it help me diagnose problems?

为什么返回 false?
因为count 是 27。

为什么是count = 27
因为你也算空格。

我该如何解决这个问题?
在添加到hs之前,请致电Character.isLetter(s[index])进行检查。
参见Character的javadoc:https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html

还请注意,您不想将大写字母与小写字母视为不同,因此您应该调用例如toLowercase(),两种方式之一:

char s[]=str.toLowercase().toCharArray()

或:

hs.add(Character.toLowercase(s[index]));

【讨论】:

  • 好点,我错过了应该考虑大写/小写字符。 +1
【解决方案3】:

您的代码中有一些错误需要纠正。

str.toCharArray() 也会在 char s[] 中添加空格。因此计数将是 27,包括空格。相反,您可以在放入 HashSet 之前检查空格。也不需要使用 while 循环,因为我们可以直接获取 HashSet 大小。 但是在您的代码块中,您正在使用带有迭代器的 while 循环,因此 i.hasNext() 将始终为真,因此执行将进入无限循环。为避免这种情况,您需要使用 i.next()。

看看下面的代码,你就明白了。

package problems;

import java.util.HashSet;
import java.util.Set;

public class StringCompareTo {

    public static boolean checkPangram(String str) {
        int index = 0;
        char s[] = str.toCharArray();
        Set<Character> hs = new HashSet<Character>();
        for (index = 0; index < str.length(); index++) {
            if(!Character.isWhitespace(s[index]))
            hs.add(s[index]);
        }
        if (hs.size() == 26)
            return true;
        return false;
    }

    // Driver Code
    public static void main(String[] args) {
        String str = "the quick brown fox jumps over the lazy dog";

        if (checkPangram(str) == true)
            System.out.print(str + " is a pangram.");
        else
            System.out.print(str + " is not a pangram.");

    }
}

使用带有迭代器的while循环应该是:

Iterator<Character> i = hs.iterator();
        while(i.hasNext()){
        char temp = i.next();
          count++;
        }

【讨论】:

    【解决方案4】:

    我认为这是一个练习,但您唯一的规定是不要使用 set。你也可以这样做。 Streamslambdas 并不是真正的 advanced concepts,而只是自 Java 8 以来一直存在的 additional features

           String str = "the quick brown fox jumps over the lazy dog";
           System.out.println("The string is " + (isPangram(str) ? ""
                    : "not ") + "a pangram.");
           }
           public static boolean isPangram(String str) {
              return Arrays.stream(str.split("")).filter(
                    a -> a.matches("[A-Za-z]")).distinct().count() == 26;
    
           }
    
    

    它消除了除上下字符之外的所有字符,然后将它们放入流中并过滤掉重复项。然后它计算它们。如果计数等于 26,则为 pangram。

    【讨论】:

      【解决方案5】:
      public static void main(String[] args){
      
      String pangramTxt="The quick brown fox jumps over the lazy dog";
      checkPangram(pangramTxt);
      
      
      }
      
      public static void checkPangram(String rawTxt){
          HashSet<Character> set=new HashSet<>();
          //remove nonword characters eg space etc
          
          char[] charArr=rawTxt.replaceAll("\\W+","").toLowerCase().toCharArray();
          
          for(Character val: charArr){
              set.add(val);
          }
          
          //26 ... the alphabet
          if(set.size()==26){
           System.out.println("Text is pangram: ************");
          }
      
      }
      

      【讨论】:

      • 您好,欢迎来到 SO!请拨打tour。感谢您提供答案,但您能否添加关于您的代码如何解决问题的说明?
      猜你喜欢
      • 2021-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 1970-01-01
      • 2011-06-05
      • 2012-10-06
      • 1970-01-01
      相关资源
      最近更新 更多