2013-03-20 65 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 :("); 
}