【问题标题】:C# binary tree loop troubleC#二叉树循环问题
【发布时间】:2017-05-15 13:59:07
【问题描述】:

我正在创建一个循环来从数组中搜索一个值。如果我找到它,将打印该位置,如果它不是“没有这样的数字”将被打印。 但是,如果我有几个相同的号码,我将只收到一个,然后我就结束了循环。如果数组中的数字相同,我如何获得控件? 我最好的尝试以无限循环或从一开始就完成的循环结束。

static public void Searching(int[] arr)
{
    string x = "yes";

    Console.WriteLine("Enter please searching number");
    while (x == "yes")
    {
        bool found = false;
        int target = Convert.ToInt32(Console.ReadLine());
        int searchkey = target;
        int mid = 0, first = 0, last = arr.Length - 1;
        while (!found && first <= last)
        {
            mid = (first + last) / 2;

            if (target == arr[mid])
                found = true;


            else
            {
                if (target > arr[mid])
                {
                    first = mid + 1;
                }

            if (target < arr[mid])
            {
                last = mid - 1;
            }
        }
    }
    String foundmsg = found
                ? "Item " + searchkey + " was found at position " + mid
                : "Item " + searchkey + " was not found";
    Console.WriteLine(foundmsg);
    Console.WriteLine("would you like to find another number?");
    x = Console.ReadLine();

        }

    }

【问题讨论】:

  • 我猜英语不是你的第一语言。老实说,我不确定您为什么要使用循环。如果您将数字数组转换为字符串,然后使用.IndexOf(inputNumber),您将得到您想要的。我错过了语言障碍吗?
  • 你可能想改写你的第一句话,因为很多人觉得这个词令人反感。
  • 我刚刚编辑了它(也做了代码格式化等),但现在有一个待编辑的。我的编辑超出了窗口-_-
  • @cdove 没关系,我知道我可以使用那个函数,但那是我的课堂任务,所以我应该只使用循环。
  • 乍一看,您的代码对我来说还不错。您可以包含导致您进入无限循环的 input 吗?编辑:你是说如果你有多次相同的数字,你想输出每个匹配数字的位置?

标签: c# loops infinite-loop binary-search


【解决方案1】:

如果您希望返回数组中找到特定值的所有位置,则创建一个列表(如List&lt;int&gt;),当您在数组中找到数字时,将位置添加到列表中。这样您就可以在不中断循环的情况下搜索整个数组。

然后,当您完成执行时,列表中将有一个或多个项目,否则列表将为空。如果列表中有项目,则显示这些项目。如果列表中没有项目,则返回“未找到”消息。

例如,

var indexes = new List<int>();
for(var index = 0; index < source.Length; index++)
{
    if(source[index] == target) indexes.Add(index);
}

完成后,您将获得匹配列表或空列表。

许多嵌套循环会让人感到困惑。您有一个处理控制台输入的外部循环。使其更易于阅读的一种方法是将部分隔离到一个函数中。例如,

List<int> GetIndexesOfMatchingNumbers(int[] source, int target)
{
    var indexes = new List<int>();
    for(var index = 0; index < source.Length; index++)
    {
        if(source[index] == target) indexes.Add(index);
    }
}

您可以从“主”函数中调用此函数。它在功能上完全相同,但它减少了您在阅读代码时必须遵循的逻辑量。这使得它更容易理解,即使对于编写它的人来说也是如此。

【讨论】:

  • 根据经验,我将方法保持在 15 行或更少(不计算空格或仅带大括号的行)。无论我们是新手还是经验丰富的人,阅读我们自己的代码或其他人的代码,它只是让大脑更容易处理。通常很容易阅读一个简短的函数并告诉它在做什么。然后我们给这个函数起一个清晰的名字,很容易知道我们在做什么——无论是在函数本身还是我们调用函数的地方。
【解决方案2】:

您可以尝试使用Array.BinarySearch 来查找一些项的索引,然后从索引开始移动向后和向前:

  int[] source = new[] { 1, 2, 3, 4, 4, 4, 4, 5, 15, 20 };

  int searchkey = 4;

  int first = -1;
  int last = -1;

  int index = Array.BinarySearch(source, searchkey);

  if (index >= 0) {
    first = index;
    last = index;

    for (int i = index - 1; i >= 0; --i)
      if (source[i] != toFind)
        break;
      else
        first = i;

    for (int i = index + 1; i < source.Length; ++i)
      if (source[i] != toFind)
        break;
      else
        last = i;

    if (first == last)
      Console.Write($"{searchkey} found at {first} position");
    else
      Console.Write($"{searchkey} found at [{first}..{last}] positions");
  }
  else
    Console.Write($"{searchkey} is not found"); 

【讨论】:

    【解决方案3】:

    不要循环这个。 C# 有内置函数来帮助你。

    static public void Searching(int[] arr)
        {
            string x = "yes";
    
            Console.WriteLine("Please enter a number for which to search...");
            int target = Convert.ToInt32(Console.ReadLine());
    
            string Response = "Result of search is:"
            +  arr.IndexOf(target) != -1 
            ? arr.IndexOf(target).ToString() : "Not Found";
           //indexOf finds the first index of obj. in array
            Console.WriteLine(Response);
         }
    

    这应该满足您的“当我找到一个倍数时,我只收到一个”的要求。你总是会第一次出现。

    如果您需要所有实例并使用循环,那也没什么不同。

    static public void Searching(int[] arr)
        {
            string x = "yes";
    
            Console.WriteLine("Please enter a number for which to search...");
            int target = Convert.ToInt32(Console.ReadLine());
            string result = string.Empty
            for(int i =0; i < arr.Length; i++)
                  if (i = target)
                  { result += i.ToString() + ", " }
            }
            if(result != string.Empty)
            {
               result = result.SubString(0, result.Length - 2);
               //removes extra space and colon
            } else {
               result = "Not Found";
            }
            Console.WriteLine("Result of search is:"
            + result);
         }
    

    【讨论】:

    • 我相信 1)这是给学校的,2)他正在尝试进行二分搜索。 IndexOf 不是二分搜索。
    • IndexOf 找到第一个实例。他是说这个数字可能不止一次出现在数组中,他需要返回每个数字的位置。
    • 但这不满足要求(隐藏在 cmets 中):“但这是我的课堂任务,所以我应该只使用循环”
    • 是的,在他添加之前我正在写这个答案。
    猜你喜欢
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2015-05-16
    • 1970-01-01
    • 2016-02-03
    • 2017-12-07
    • 2012-08-18
    • 2011-07-24
    相关资源
    最近更新 更多