2010-09-17 139 views
4

检查给定字符串中所有字母的最佳逻辑是什么?检查字符串是否包含字母表中的所有字母

如果所有的26个字母在提供的字符串中可用,我想检查并执行如此操作。例如。用五打酒壶装箱。

  1. 会使用哈希有用吗?
  2. 或者使用位图吗?或者其他方式?

顺便说一下,我的代码将在Java中。

+3

“包装我的盒子有五个瞌睡liqor壶”?谨慎解释? :) – MAK 2010-09-17 10:31:41

+1

这是一个[pangram](http://en.wikipedia.org/wiki/Pangram),也是少数几个真正有意义的短片之一。 – 2010-09-17 13:41:50

+0

噢,当你完成了水罐后,*运送给我六十十夸脱的罐子和十二个黑色的水罐。* – 2010-09-17 14:05:16

回答

5

尚未全面优化:

public static void main(String... a) { 
    String s = "Pack my box with five dozen liquor jugs."; 
    int i=0; 
    for(char c : s.toCharArray()) { 
     int x = Character.toUpperCase(c); 
     if (x >= 'A' && x <= 'Z') { 
      i |= 1 << (x - 'A'); 
     } 
    } 
    if (i == (i | ((1 << (1 + 'Z' - 'A')) - 1))) { 
     System.out.println("ok"); 
    } 
} 
+0

因此...使用“int”而不是BitSet。它有足够的位。在Java中,“int”将始终有32位,与C不同。 – 2010-09-17 10:36:07

+0

不会使用“0x3FFFFFF”会更快吗?'不包含任何变量,所以它会在编译时被计算并作为常数存储| – st0le 2010-09-17 10:40:51

+0

的'右侧。 (这里假设一个带有优化器的编译器。) – Blrfl 2010-09-17 10:46:41

3

我会去找一个位图。如果每次将位图中的条目设置为1时增加计数器,只要看到所有字母,就可以尽早返回。我希望这不是执行密码要求。

1

保留boolean大小为26的数组。数组的每个位置表示是否存在特定字符(a在0处,b在1处等)。最初所有都设置为false。现在,对字符串逐个字符进行单次扫描,并将该字符的值设置为true。最后,检查所有26个索引是否包含true。

+0

如果一个字符丢失,OP的要求将允许你破坏,所以你不需要检查索引到底。 – Filburt 2010-09-17 11:28:54

+0

@Filburt:我不明白你的意思。我的检查结果是这样的'boolean ret = true; for(int i = 0; i <26 && ret; i ++)ret&= seen [i]; return ret;'。 – MAK 2010-09-17 12:22:31

+1

你不需要再进行第二次扫描,只需打开一个计数器即可增加计数器,即... {count + =(!letters [i]);字母[i] ++} ... return 26 == count; – Cercerilla 2010-09-17 13:39:43

1

26个布尔值的数组就足够了,每个条目都代表字母表中的字母。当找到该字母时,您可以将条目设置为true。

1

我会去26个字母的筛选算法。只是我的$ .02。

编辑:代表26个字母的26个值的数组。然后扫描字符串,检查每个字母,当你遇到它。最后,检查这26个字母是否被检查过。

+0

你能否详细说明一下? – st0le 2010-09-18 04:17:05

6

使用BitMap,我假设你的意思是不区分大小写。

更新:托马斯的解决方案比以下更高效。 :)使用那个。

// 
    String test = "abcdefeghjiklmnopqrstuvwxyz"; 

    BitSet alpha = new BitSet(26); 
    for(char ch : test.toUpperCase().toCharArray()) 
     if(Character.isLetter(ch)) 
      alpha.set(ch - 65); 

    System.out.println(alpha.cardinality() == 26); 
+1

是的,但这样更具可读性和可维护性。此外,mabye此操作不需要高效。 – 2010-09-17 11:35:18

+0

将生长为非拉丁字符的字符集。 – 2010-09-18 09:00:10

+0

这个答案不正确。例如,以下测试字符串将错误地报告“false”:'abcdefeghjiklmnopqrstuvwxyzäöü',以下内容将错误地报告“true”:'abcdefeghjiklmnopqrstuvwäöü'。请注意,Unicode代码点0 .. 0xffff有47444(!)不同的“大写”字符。 – 2016-09-02 08:45:38

0

你可以遍历您的字符串为您要检查的每个字母。当你找到你正在寻找的信件时,继续下一步。如果你不这样做,就放弃。下面是一些伪代码:

found = true; 
for (letter in letters) { 
    if (!string.contains(letter)) { 
     found = false; 
     break; 
    } 
} 

这样你就不需要存储每个字母的信息,但你必须一次又一次地进行搜索的字符串的每个字母。你最终使用的将取决于你的要求:它应该快吗?它应该使用小内存吗?你的决定。 :)

0
public static void main(String[] args) { 

    String A ="asdfsdafasdf"; 
    String B ="abcdefghijklmnopqrstuvwxyz"; 
    String C ="ASDFGFHWER"; 
    String result = "NO"; 

    String letters[] = {A,B,C}; 
    int length = letters.length; 

    for(int j=0; j< length; j++){ 
     String letter = letters[j].toLowerCase(); 
     int letterLength = letter.length(); 
     for(char i='a'; i<'z'+1; i++){ 
      if(letter.contains (""+i)){ 
       result ="YES"; 
      } else{ 
       result = "NO"; 
      } 
     } 
     System.out.println(result); 
    } 
} 
1
public class Pangram { 
    public static boolean isPangram(String test){ 
     for (char a = 'A'; a <= 'Z'; a++) 
      if ((test.indexOf(a) < 0) && (test.indexOf((char)(a + 32)) < 0)) 
       return false; 
     return true; 
    } 

    public static void main(String[] args){ 
     System.out.println(isPangram("the quick brown fox jumps over the lazy dog"));//true 
     System.out.println(isPangram("the quick brown fox jumped over the lazy dog"));//false, no s 
     System.out.println(isPangram("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));//true 
     System.out.println(isPangram("ABCDEFGHIJKLMNOPQSTUVWXYZ"));//false, no r 
     System.out.println(isPangram("ABCDEFGHIJKL.NOPQRSTUVWXYZ"));//false, no m 
     System.out.println(isPangram("ABC.D.E.FGHI*J/KL-M+NO*PQ R\nSTUVWXYZ"));//true 
     System.out.println(isPangram(""));//false 
     System.out.println(isPangram("Pack my box with five dozen liquor jugs."));//true 
    } 
} 
0

这不是一个最佳的解决方案,但很容易理解:)!

import java.io.*; 
import java.util.*; 

public class Solution { 

public static void main(String[] args) { 
    Scanner in = new Scanner(System.in); 
    String s = in.nextLine().toUpperCase(); 
    char[] sarray = s.toCharArray(); 
    char[] alphabets = {'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'}; 
    Set<Character> set = new HashSet<Character>(); 
    for(int i=0;i<sarray.length;i++){ 
     for(int j=0;j<alphabets.length;j++){ 
      if(sarray[i] == alphabets[j]){ 
       set.add(sarray[i]); 
       break; 
      } 
      continue; 
     } 
    } 
    if(set.size() == 26){ 
     System.out.println("pangram"); 
    }else{ 
     System.out.println("not pangram"); 
    } 

} 

}

1

试试这个很容易和简单易懂

import java.util.*; 

public class Pnagram{ 
    public static void main(String[] args){ 
     Scanner sc=new Scanner(System.in); 
     String Str=sc.nextLine(); 
     Set<Character> set = new HashSet<Character>(); 

     for(char c:Str.toUpperCase().toCharArray()){ 
      if(Character.isLetter(c)) 
      set.add(c); 
     } 
     if(set.size()==26) 
      System.out.println("pnagram"); 
     else 
      System.out.println("not pnagram"); 
    } 
} 
0

说明

首先,我将所有的字符串字符转换为大写。

在ASCII表

你可以找到大写字符范围,即A == 65和Z == 65 90之间

所以,for循环应该从65月底开始在90.

检查字符串是否包含当前的ASCII字符。

我整数转换为char,把“”是字符串

if !text.contains((char)i + "") == true 

这意味着,如果该字符串没有当前的char i,我会return false

你可以把它即使使用char i更好地循环

static boolean isPangram(String text) { 
    //change all chars to upper case 
    text = text.toUpperCase(); 
    //Loop from A to Z 
    for(int i = 65 ; i < 91 ; i++){ 
     //if text not contains return false 
     if(!text.contains((char)i + "")){ 
      return false; 
     } 
    } 
    return true; 
} 
+0

请添加说明 – Billa 2017-11-26 07:57:50

+0

说明做兄弟^ _ ^ – AmrDeveloper 2017-11-26 08:11:10

0

不是一个最佳的解决方案,但它的工作原理。

String a= new String("the quick brown fox jumps over the lazy dog"); 
     int n=a.length(); 
     int[] b= new int[123]; 
     char x; 
     boolean flag=true; 
     for(int i=0;i<n;i++)  
    { 

     if(a.charAt(i)==' ') 
      continue; 
     x=Character.toLowerCase(a.charAt(i)); 
     b[(int)x]++; 

    } 
    for(int i=97;i<123;i++) 
    { 
     if(b[i]==0) 
      { 
       flag=false; 
       break; 
      } 
    } 
    if(!flag) 
     System.out.print("No"); 
     else 
     System.out.print("yes"); 
相关问题