2013-03-20 59 views
2

我試圖生成隨機字母5個字母的單詞。一切工作正常,但是當我點擊我的按鈕,生成需要近2分鐘左右產生的那些話,併爲那些2分鐘我的按鈕保持抽頭(藍色)的話,這並不好看。我以爲把處理環,但也不起作用。下面是我的方法的一些編碼需要幫助Java中的Android應用程序

String finalWrd = searchWrd.toUpperCase(); 
     String twoLetterString = ""; 
     int wordLen = searchWrd.length();//searchWrd is a random letter entered by user 
     String[] array = finalWrd.split("");  
     for(int i =1; i<=wordLen; i++) 
      for(int j=1; j<=wordLen; j++) 
       for(int K=1; K<=wordLen; K++) 
        for(int l=1; l<=wordLen; l++){ 
         for(int m=1; m<=wordLen; m++){ 
          twoLetterString += array[i] + array[j]+ array[K]+ array[l] + array[m] +","; 
         } 

        } 

String[] array2Letters = twoLetterString.split(","); 




    int a =array2Letters.length, b = dictLinesArray.length; 

    for(int i =0;i<a; i++) 
    { 

     for(int l=0;l<b;l++) 
     { 
      if(array2Letters[i].equals(dictLinesArray[l])) 
      { 
       dictString2Lettes += dictLinesArray[l] +"," ; 
      } 
     } 
    } 


    text = dictString2Lettes; 

請幫助我,我需要它爲我的大學項目。在此先感謝

+0

+1至少你已經試過你的自我,好 – Raynold 2013-03-20 05:12:49

+1

Sooo許多循環。那就是你的問題。 – Sanchit 2013-03-20 05:14:12

+0

爲什麼會有這麼多的循環?你在做什麼? – Makoto 2013-03-20 05:14:50

回答

1

我不評論你的算法的inefficency(試圖找到更好的東西!:))。 我只是給了看起來凍結的UI解決方案:

「我的按鈕保持抽頭(藍色),這並不好看」

當您的計算需要時間來完成,你需要像的AsyncTask

http://developer.android.com/reference/android/os/AsyncTask.html

假設你在你的活動命名MyActivity:

public class MyActivity extends BaseActivity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_main_menu); 

     Button btn = (Button)findViewById(R.id.button); 
    btn.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      //execute async task 
      new FindWordsTask().execute();    
     } 
    }); 
} 

比你設置你的AsyncTask這樣的:

private class FindWordsTask extends AsyncTask<Void, Void, Void> { 

    ProgressDialog progressDialog; 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     progressDialog = ProgressDialog.show(MyActivity.this, 
       "Title", 
       "Finding words...", true); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 

     //do the computation, 
     //use here your function 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     super.onPostExecute(result); 
     progressDialog.dismiss(); 
    } 
} 
+0

這並不能解決他代碼中的低效問題。儘管如此,它會更加方便用戶使用。 – Sanchit 2013-03-20 05:23:35

+1

問題出現的問題是UI看起來凍結了!保持MainThread遠離計算總是非常重要的。 – 2013-03-20 05:24:39

+1

我同意!儘管效率低下的算法會讓他在「Finding words ...」屏幕上等待很長時間,但我仍然對用戶友好。如果我輸入「Pneumonoultramicroscopicsilicovolcanoconiosis」,該怎麼辦呢?這個程序要運行好幾年。 – Sanchit 2013-03-20 05:28:55

0

我猜是什麼把你的時間最多是第二環(因爲dictLinesArray大)

嘗試改變dictLinesArray設置並使用contains。該dictLinesSet初始化應該做的只有一次(在一些初始化函數)。

Set<String> dictLinesSet = new HashSet<String>(Arrays.asList(dictLinesArray)); 


for(int i =0;i<a; i++){ 
    if (dictLinesSet.contains(array2Letters[i])){ 
     dictString2Lettes += array2Letters[i] +"," ; 
    } 
} 
+0

它不支持dictLinesArray.contains – Happy 2013-03-20 05:47:58

+0

是的,你需要將它改爲Set。 – BobTheBuilder 2013-03-20 06:04:13

0

有些想法,我希望他們幫助。

在你的建築,你實際上是做一些低於最佳數據管理。由於字符串是不可變的,因此每次你經歷最內層的循環(這是wordLen^5迭代)時,你創建了6個總的String對象(=符號的右邊),並且創建了第七個(=符號的左邊) 。字符串是不可變的Java和內存是不是在筆記本/桌面開發移動應用更大的關注。因此,對於5字長度,您正在創建21,875個對象。對於一個字8,你正在創造229,376個對象,而且它只會變得更糟。

更好的是使用StringBuilder和存儲大功告成後的值:

你也想使twoLetterString一個字符串生成器從一開始走。

StringBuilder twoLetterStringBuilder = new StringBuilder(); 
//inside the loop 
    twoLetterStringBuilder.append(array[i]).append(array[j]). ... .append(","); 

最後,只需使用

twoLetterStringBuilder.toString().split(","); 

的AsyncTask將讓事情抱死,但這應該幫助你更有效的與你的目標和總的處理時間的創建。

所有的for循環的一些必要性的理由是有一個所有可能的排列數組?如果不只是使用:

Random r = new Random(); 
int arrayIndex = r.nextInt(wordLen); 
2

我會嘗試爲您提供一個體面的解決方案來提高算法的性能。使用@Seraphim(或類似的)答案來提高用戶的友好性。

修復您的字典數據結構。

1)讓你的字典爲Map<String,ArrayList<String>>

2)在你的字典添加詞語像這樣:

String[] oldDictionary = {"using","suing","apple","orange"}; 
HashMap<String, ArrayList<String>> map = new HashMap<>(); 
for (int i = 0; i < oldDictionary.length; i++) { 
    char[] sort = oldDictionary[i].toCharArray(); 
    Arrays.sort(sort); 
    String alphabetical = new String(sort); 
    if (map.containsKey(alphabetical)) { 
    map.get(alphabetical).add(oldDictionary[i]); 
    } else { 
    ArrayList<String> tmp = new ArrayList<>(); 
    tmp.add(oldDictionary[i]); 
    map.put(alphabetical, tmp); 
    } 
} 

您現在可以使用這個新的和改進的數據結構,超級容易找到的話。

String inputWord = "iusgn"; 
char[] sort = inputWord.toCharArray(); 
Arrays.sort(sort); 
inputWord = new String(sort); 

if (map.containsKey(inputWord)) { 
    StringBuilder sb = new StringBuilder(); 
    for (String word : map.get(inputWord)) { 
    sb.append(word + ","); 
    } 
    sb.deleteCharAt(sb.length() - 1); 
    System.out.println(sb.toString()); 
} else { 
    System.out.println("Nothing found :("); 
}