C#二进制搜索不返回结果

时间:2018-09-29 10:39:57

标签: c# binary-search

代码:

using System;
using System.IO;
using System.Collections.Generic;

class MainClass {
    public static void Main (string[] args) {
        Console.WriteLine ("Get Random Names");
        // Read every line in the file.
        List<string> nameList = new List<string>();
        using (StreamReader reader = new StreamReader("test.txt"))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
        {
            nameList.Add(line);
        }
    }

        nameList.Sort();
        int startValue = 0;
        int middleValue = (nameList.Count + 1) / 2;
        int endValue = (nameList.Count + 1);

        Console.WriteLine("Enter a name to search for.");
        String name = Console.ReadLine();

        bool nameNotFound = true;
        var compareResult = String.Compare(nameList[middleValue], name);


        while (nameNotFound) { 
            if (compareResult < 0) {
              endValue = middleValue;
              middleValue = endValue / 2;
            }
            else if (compareResult > 0) {
              startValue = middleValue;
              middleValue = (endValue - startValue) / 2 + startValue;
            }
            else {
              Console.WriteLine("Name " + name + " was found.");
              nameNotFound = false;
            }
        }
}
}

问题: 我正在尝试对C#二进制搜索进行编码,以搜索具有列表名称(字符串)的文件。由于某种原因,我无法弄清楚,搜索没有返回结果。有人有什么想法吗?

解决方案: 我已经修复了代码。两个问题是我没有比较if和else if循环中的值,而我的大于和小于符号却混在一起了。

3 个答案:

答案 0 :(得分:1)

    int startValue = 0;
    int middleValue = (nameList.Count + 1) / 2; // Here you just take the line
                                                // that was in the middle of the file
    int endValue = (nameList.Count + 1);
    // [...]
    var compareResult = String.Compare(nameList[middleValue], name); // and here you check for it

    while (nameNotFound) { // A loop that never compares again
                           // (and makes me wonder how you actually exit the program)
        if (compareResult < 0) {
          endValue = middleValue;
          middleValue = endValue / 2;
        }
        else if (compareResult > 0) {
          startValue = middleValue;
          middleValue = (endValue - startValue) / 2 + startValue;
        }
        else {
          Console.WriteLine("Name " + name + " was found.");
          nameNotFound = false;
        }
    }

TL; DR是提供的代码仅检查文本文档中最中间的字符串是否与提供的名称相同

您需要(再次)比较入门者

答案 1 :(得分:1)

最后,在主算法循环中,您永远不会重新计算compareResult,因此您的程序无法分辨何时找到了某些内容。

您需要在compareResult = String.compare ...if块中添加else if

如果您不这样做,compareResult将保留您在循环之前进行的第一次比较的结果。

答案 2 :(得分:0)

尝试理解旧的答案,然后尝试重写增强的代码,如果失败,不要沮丧,请看这里:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace StackOverflowSolver
{
    class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Get Random Names");
            // Read every line in the file.
            List<string> nameList = new List<string>();
            using (StreamReader reader = new StreamReader("test.txt"))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    nameList.Add(line);
                }
            }

            nameList.Sort();

            //you can get better variables name with replacing Value with Index
            int startValue = 0;
            //int middleValue = (nameList.Count + 1) / 2;   error
            //consider you've three elements, middleValue will be 2 
            //the array index began from 0 remeber that
            int middleValue = nameList.Count / 2;
            //int endValue = (nameList.Count + 1);          error 
            int endValue = nameList.Count-1;
            Console.WriteLine("Enter a name to search for.");
            String name = Console.ReadLine();

            bool nameNotFound = true;
            while ((nameNotFound) && (endValue > startValue))//add end search condition
            {
                var compareResult = String.Compare(name, nameList[middleValue]);
                if (compareResult < 0)
                {
                    endValue = middleValue -1; //Substract 1
                    middleValue = endValue / 2;
                }
                else if (compareResult > 0)
                {
                    startValue = middleValue +1; //Add 1
                    middleValue = (endValue - startValue) / 2 + startValue;
                }
                else
                {
                    Console.WriteLine("Name " + name + " was found.");
                    nameNotFound = false;
                }
            }
            //consider to uncommit the line below
            //Console.WriteLine("Name " + name + " not found!"); //inform not found
            Console.ReadKey();
        }
    }
}

上面的代码效果很好。