【问题标题】:Populating List with binary search [closed]使用二进制搜索填充列表 [关闭]
【发布时间】:2013-03-16 15:36:10
【问题描述】:

我的列表中填满了文件名。我需要用搜索结果填充花药列表。这个搜索结果必须通过二分搜索来完成,下一个规范:关键字可以匹配文件名或者它的 Substring(0, key.Length)。 例如关键字=“汽车” 搜索结果 = "car.gif"、"carffur.pdf" 等,但不是 "mobilecar.jar"

我的二分搜索:

    class Search
{
    private const int KEY_NOT_FOUND = -1;

    public static int BinarySearch<T>(List<T> A, T key, IComparer<T> comparer, int imin, int imax)
    {
        // test if array is empty
        if (imax < imin)
            // set is empty, so return value showing not found
            return KEY_NOT_FOUND;
        else
        {
            // calculate midpoint to cut set in half
            int imid = imin + ((imax - imin) / 2);
            int compareResult = comparer.Compare(A[imid], key);
            // three-way comparison
            if (compareResult > 0)
                // key is in lower subset
                return BinarySearch<T>(A, key, comparer,imin, imid - 1);
            else if (compareResult < 0)
                // key is in upper subset
                return BinarySearch<T>(A, key, comparer, imid + 1, imax);
            else
                // key has been found
                return imid;
        }
    }
}

我的比较器类:

    class SubStringComparison : IComparer<string>
{
    public int Compare(string x, string y)
    {
        if (x.Length > y.Length && x.Substring(0, y.Length).Equals(y))
            return 0;

        return String.Compare(x, y, StringComparison.OrdinalIgnoreCase);
    }
}

用法:

private void backgroundWorkerSearch_DoWork(object sender, DoWorkEventArgs e)
    {
        SearchForFiles();
    }

    private void SearchForFiles()
    {
        List<string> files = listBoxFiles.Items.OfType<string>().ToList();
        searchResults = new List<string>();
        listBoxFiles.Dispatcher.Invoke(new Action(delegate()
            {
                while (true)
                {
                    int index = Search.BinarySearch<string>(files, textBoxFileToSearch.Text, new SubStringComparison(), 0, files.Count - 1);
                    if (index == -1)
                        break;
                    else
                        searchResults.Add(files[index]);
                }
            }));
    }

【问题讨论】:

  • 请努力并解释什么是“搜索结果必须通过二分搜索完成”。通常这是由fileNames.OrderBy(....) 完成的,但您的要求非常不清楚。
  • 我不应该使用任何内置的 .net 方法。我必须自己写。问题是,当我使用自己编写的二进制搜索时,它每次都会返回一个结果,但我也需要它返回另一个结果。
  • 你在看什么 - 允许这样做吗?请清楚说明您在“自己编写”时遇到的问题,以便我们提供帮助。
  • 家庭作业问题列表不是问题。如果您在做作业时遇到困难,那没关系:展示您到目前为止的工作,并就它提出一个明确、具体的问题。这里没有人会为你做你的工作。
  • @AlexeiLevenkov 在这里我写了代码。问题是我不知道如何返回所有匹配项。此代码在 while 循环中始终返回相同的匹配项,因此循环永远不会结束。我需要某种想法来解决它。

标签: c# algorithm binary-search


【解决方案1】:

-1 你在作业的哪一部分有问题? 是二分查找吗? 是文件名的选择吗? 是不是 BackgroundWorker 的东西没有按预期工作?

我看到您的 BackgroundWorker 有一些问题,您似乎是在 BackgroundWorker 线程中从 UI 中选择文件列表,然后创建一个将在主线程中运行的 Action,这是一种非常奇怪的方法它。

正确的方法是:

public void button1_Click(object sender)
{
    List<string> files = listBoxFiles.Items.OfType<string>().ToList();
    string key = textBoxFileToSearch.Text;
    backgroundWorkerSearch.RunWorkerAsync(new Tupple<List<string>,string>(files, key));
}

void backgroundWorkerSearch_DoWork(object sender, DoWorkEventArgs e)
{
     var state = e.Argument as Tupple<List<string>,string>;
     List<string> files = state.Item1;
     string key = state.Item2;
     // You can now access the needed data.
     List<string> searchResult = new List<string>();
     // ...
     e.Result = searchResult;
}

void backgroundWorkerSearch_RunWorkerCompleted(RunWorkerCompletedEventArgs e)
{
     List<string> searchResult = e.Result;
     // Show result in the UI thread.
} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-09
    • 2017-07-06
    • 2021-04-28
    • 2011-01-24
    • 2017-06-13
    • 1970-01-01
    相关资源
    最近更新 更多