2010-09-17 141 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"); 
相關問題