2

我正在尝试从随机字母中生成 5 个字母的单词。一切正常,但是当我单击按钮生成单词时,生成这些单词大约需要 2 分钟,而在这 2 分钟内,我的按钮仍然处于点击状态(蓝色),这看起来不太好。我想放处理环,但这也行不通。下面是我的方法的一些编码

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;

请帮助我,我的大学项目需要它。提前致谢

4

4 回答 4

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 :(");
}
于 2013-03-20T05:45:46.937 回答
1

我不会评论您的算法效率低下(尝试找到更好的东西!:))。我将简单地为看起来冻结的 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();
    }
}
于 2013-03-20T05:21:51.317 回答
0

我猜你最花时间的是第二个循环(因为dictLinesArray很大)

尝试更改dictLinesArray为 Set and use containsdictLinesSet初始化应该只进行一次(在某些初始化函数中)。

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


for(int i =0;i<a; i++){
    if (dictLinesSet.contains(array2Letters[i])){
         dictString2Lettes += array2Letters[i] +"," ;
    }
}
于 2013-03-20T05:23:22.087 回答
0

一些想法,我希望他们有所帮助。

在您的构建中,您实际上是在做一些不太理想的数据管理。由于字符串是不可变的,因此每次通过最内层循环(即 wordLen^5 次迭代)时,您将创建 6 个字符串对象(= 符号右侧),并创建第七个(= 符号左侧) . 字符串在 Java 中是不可变的,与笔记本电脑/台式机开发相比,移动应用程序更关注内存。因此,对于 5 个字长,您将创建 21,875 个对象。对于 8 的 wordLen,您正在创建 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);
于 2013-03-20T05:29:41.420 回答