【问题标题】:How to get numbers in a certain range in a list? [closed]如何获取列表中某个范围内的数字? [关闭]
【发布时间】:2014-02-02 02:40:08
【问题描述】:

我有一个整数列表

2,5,6,9,45,48,54,76,97,102,134,203,234,245,267,289,299

我想得到一个从 31 到 255 的数字列表。如何在 C# 中编码?

【问题讨论】:

  • 这是我能想象到的最简单的编程问题之一。您是否已经尝试编写一些代码?使用for循环和if语句可以轻松解决...除非您尝试自己编程,否则您不会学习编程。
  • 随着列表的排序,您可以使用二分搜索在 log(n) 时间内找到最小和最大元素索引,然后在该范围内进行迭代。请先尝试一下。
  • @Prince 因为列表是排序的(升序),所以不需要二分查找,显然最后一个和第零个元素分别是max和min。
  • @ps06756 我说元素索引不是元素; OP 想要一系列元素(最小值 = 31,最大值 = 255)。恕我直言,这样做非常有意义。您还能如何利用排序列表?

标签: c# list


【解决方案1】:

希望这会奏效。刚刚测试了一下,效果很好。

int[] x = {2,5,6,9,45,48,54,76,97,102,134,203,234,245,267,289,299};

List<int> y = new List<int>();

for (int i = 0; i < x.Length; i++)
{
    if ( (x[i] >= 31) && (x[i] <= 255) )
    {
         y.Add(x[i]);
    }
}

所以我为x 使用了一个数组。然后我创建了一个名为y 的列表。我会使用循环来检查值是否满足条件。如果有,我会将它们添加到y 列表中。

foreach (int k in y)
{
    Console.WriteLine(k);
}

使用此循环只是为了确保它有效(可选)。

下次请在发布问题之前表现出努力。此外,这是一个简单的算法,所以它都是关于循环的。只要您了解数组和循环的基础知识,即使是初学者程序员也应该知道这一点。欢迎使用 Stack Overflow。

Ansible 的回答(更高效)

但是因为这是一个有序数组,我们可以通过在超过上限后停止搜索来提高效率。我们知道这些数字都不会在我们的范围内。我们可以通过简单地打破 for 循环来做到这一点。

int[] x = {2,5,6,9,45,48,54,76,97,102,134,203,234,245,267,289,299};

List<int> y = new List<int>();

for (int i = 0; i < x.Length; i++)
{
    if ( (x[i] >= 31) && (x[i] <= 255) )
    {
         y.Add(x[i]);
    }
    else if (x[i] > 255)
    {
       // We are past the upper bound, we are okay to stop the for loop now.
       break;
    }
}

但除此之外,我们还可以通过对下限进行二分搜索来提高效率。这样做不是从数组的开头开始遍历所有值,而是从中间开始。我们可以通过查看值 97(在数组中间)知道我们的下限必须在数组的前半部分。这已经将我们正在进行的搜索量分成了一半。我们可以继续这样做,将数组切成两半,直到找到我们正在寻找的值。

将它们放在一起看起来像这样。

int[] x = {2,5,6,9,45,48,54,76,97,102,134,203,234,245,267,289,299};

List<int> y = new List<int>();

int lowerBoundIndex = binarySearch(array, 0, x.length, 31);

for (int i = lowerBoundIndex; i < x.Length; i++)
{
    if ( (x[i] >= 31) && (x[i] <= 255) )
    {
         y.Add(x[i]);
    }
    else if (x[i] > 255)
    {
       // We are past the upper bound, we are okay to stop the for loop now.
       break;
    }
}

public int binarySearch(int[] array, int lowerbound, int upperbound, int key) {
    int position;

    // To start, find the subscript of the middle position.
    position = (lowerbound + upperbound) / 2;

    while (!IsTargetIndex(array, position, key) && (lowerbound <= upperbound)) {
        if (array[position] > key) // If the number is > key, ..
        { // decrease position by one.
            upperbound = position - 1;
        } else {
            lowerbound = position + 1; // Else, increase position by one.
        }
        position = (lowerbound + upperbound) / 2;
    }


    if (lowerbound <= upperbound) {
        return position;
    } 

    return -1;
}

public boolean IsTargetIndex(int[] array, int position, int key)
{
    int current = array[position];
    int previous;
    if (position == 0)
        previous = -1;
    else
        previous = array[position -1];

    if ((previous < key) && (current >= key))
    {
        return true;
    }

    return false;
}

二分搜索取自这里,但我不得不修改它,因为我们不是在寻找精确匹配,而是第一个大于或等于下限的项目。这是在 IsTargetIndex 中完成的。

这可能会也可能不会过分。如果您的阵列很小,那么这可能不会带来很大的性能提升。但是想象一下,如果您的阵列有数百万个节点,那么这可能会节省大量时间。

下次请在发布问题之前表现出努力。此外,这可以通过一个简单的算法来完成,所以这都是关于循环的。只要您了解数组和循环的基础知识,即使是初学者程序员也应该知道这一点。欢迎使用 Stack Overflow。

【讨论】:

  • 您可以使用二进制搜索来查找第一个元素,因为它们已排序。或者至少你应该在 x[i] > 255 时添加一个中断,这样我们就不会搜索其余的数字。
  • @ansible 哦,我听说过二进制搜索,但我不知道其中的代码。老实说,我不是一个编程专业人士,所以是的,我试图坚持初学者可以理解的任何内容。我一直在编程,但从未成为专业级别的人。
  • 没问题,建议对您的答案进行编辑以包含这些内容。二分搜索的基本思想并不太复杂,而且是一个非常巧妙的想法。
  • Aww 我在获得批准之前就下线了 :( 哦,那么我会为你编辑它。编辑:完成添加了你的 @ansible
猜你喜欢
  • 2020-02-19
  • 2019-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-31
  • 2013-11-16
  • 2020-04-03
相关资源
最近更新 更多