要求是使用二进制搜索方法对指定字符串(在下面的示例中为“yz”)搜索按字母顺序/排序的列表(字符串类型)并返回结果(每个以指定字符串开头的字符串和也是该字符串在列表中的索引)在合适的控件(如 ListBox)上。
问题是 BinarySearch 方法必须通过一个循环运行多次,以便它返回列表中的所有匹配字符串,而不仅仅是一个。这是我的主要问题。我不知道如何正确编写这个循环。如果您查看 while 循环内部,您会看到我正在尝试删除从列表中找到的结果,因此找不到并再次返回。这会导致列表中项目的索引被更改的问题。因此它为结果返回错误的索引。例如,如果您运行下面的代码,它应该返回索引:9、10、11 和 12。但是,我得到 9、10、9、10,因为随着项目被删除,列表变得更短。我可以用另一个随机字符串替换生成的字符串,而不是完全删除它,但这意味着列表不再按字母顺序排序。要使 BinarySearch 方法起作用,列表必须按字母顺序排序。
BinarySearch 方法可能没问题,不需要任何更改。问题在于循环。我应该提到这是我大学的作业,所以我不能使用任何快捷代码/内置函数。我已经尝试了几个小时,但无法弄清楚这一点。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
string searchString = "yz";
List<string> list1 = new List<string>();
private void btnSearch_Click(object sender, RoutedEventArgs e)
{
if (list1.Count != 0)
{
list1.Clear();
}
list1.Add("ant"); //0
list1.Add("bb"); //1
list1.Add("bc"); //2
list1.Add("bD"); //3
list1.Add("Be"); //4
list1.Add("j"); //5
list1.Add("RRR"); //6
list1.Add("sT"); //7
list1.Add("Uv"); //8
list1.Add("yz"); //9
list1.Add("yza"); //10
list1.Add("yzb"); //11
list1.Add("yzc"); //12
int index = BinarySearch(list1, 0, list1.Count, searchString);
while (index != list1.Count)
{
listBox1.Items.Add("Index: " + index + " File: " + list1[index]);
list1.RemoveAt(index); //Remove from list so we don't find it again
// but this changes the index of the list
index = BinarySearch(list1, 0, list1.Count, searchString);
}
}
//BinarySearch method to search an alphabetically sorted list for a specified string
public int BinarySearch(List<string> strList, int first, int last, string target)
{
int mid; // index of the midpoint
string midStr; // object that is assigned listStr[mid]
int origLast = last;
// save original value of last
while (first < last)
// test for nonempty sublist
{
mid = (first + last) / 2;
midStr = strList[mid];
int indy = midStr.IndexOf(target, StringComparison.OrdinalIgnoreCase);
if (indy == 0)
return mid;// have a match, we're only matching the beginning of the string
else
{
int order = string.Compare(target, midStr, StringComparison.OrdinalIgnoreCase);
if (order < 0)
last = mid; // search lower sublist. Reset last
else
first = mid + 1; // search upper sublist. Reset first
}
}
return origLast; // target not found
}
}