【问题标题】:Binary Search on the first element in a multiple dimensional array对多维数组中的第一个元素进行二分搜索
【发布时间】:2014-07-31 15:50:32
【问题描述】:

我的目标是只对二维数组中的第一个元素执行二进制搜索。我整天都在寻找是否可以在 .NET 中使用 BinarySearch() 但我找不到任何东西。

为了更清楚地说明这一点。想象一下,我有一个未排序的一维数组。如果我对数组进行排序,我会丢失原始索引。我想创建数组的第二个元素来保存原始索引(我可以这样做),然后按第一个元素排序,然后对第一个元素进行二进制搜索。

如果有人能把我推向正确的方向,我将不胜感激。 谢谢

【问题讨论】:

  • 我没有完全理解你...你能提供一个小的数字例子吗?
  • 感谢您的快速回复 :) 想象一下我有以下内容:{ [400,0] , [333,1], [967, 2], [723,3] } 按第一个元素排序我得到: { [333,1], [400,0] , [723,3], [967, 2] } 我现在可以尝试对第一个元素进行二分搜索: 333, 400, 723, 967 但是我不知道怎么做。

标签: c# .net binary-search


【解决方案1】:

好吧,如果我理解正确的话,你需要这样的东西:

// initialize the array and the indexes array
var a2D = new int[2][];
a2D[0] = new[] { 3, 14, 15, 92, 65, 35 }; // <-- your array (fake data here)
a2D[1] = Enumerable.Range(0, a2D[0].Length).ToArray(); // create the indexes row

// sort the first row and the second one containing the indexes
Array.Sort(a2D[0], a2D[1]);

// now a2D array contains:
//  row 0: 3, 14, 15, 35, 65, 92
//  row 1: 0,  1,  2,  5,  4,  3

// and you can perform binary search on the first row:
int columnIndexOf35 = Array.BinarySearch(a2D[0], 35);
// columnIndexOf35 = 3
// 
// a2D[0][columnIndexOf35] = 35 <- value
// a2D[1][columnIndexOf35] = 5  <- original index

【讨论】:

  • +1。这是确切的答案 - 不知道这个版本的排序存在。有关信息,请参阅Array.Sort
【解决方案2】:

根据MSDNArray.BinarySearch 方法仅适用于一维数组,因此在您的情况下无法直接使用它。您有一些选择:

  1. 将第一列提取到一个单独的数组中并对其调用Array.BinarySearch
  2. 定义实现接口 IComparable 的自定义类 Pair 并使用此类的实例构造您的数组。
  3. 自己实现二维数组的二分查找。

【讨论】:

  • 感谢您的快速回复!您建议的第一种方法我已经完成,但我无法追溯原始索引。我必须阅读更多关于 IComparable 的内容才能试一试。选项 3 是我要去的地方,源代码看起来并不难实现搜索中未使用的额外维度。但希望它没有变成那样!
  • 您当然可以使用第一个选项,但您在帖子中描述的所有操作之后。当您对第一列中的值和第二列中的原始索引进行排序后,您可以从第一列创建新数组,然后对其执行二进制搜索。结果是第一列中的索引,第二列中的相应元素将为您提供原始索引。
【解决方案3】:

看起来您想要拥有包含数据和“原始索引”的对象,而不是按数据排序/搜索对象数组。

(这个答案显示了安德烈的选项 2)

class IndexedData:IComparable
{
  public MyType Data;
  public int OriginalIndex;

  public int CompareTo(object obj) {
    // add correct checks for null,.. here
    // and return correct comparison result. 
    // I.e. if MyType is IComparable - just delegate.
    return Data.CompareTo(obj);
}

查看 MSDN 上的 IComparable 了解实现/使用详情。

【讨论】:

  • 非常感谢。这看起来很有希望!
【解决方案4】:

根据您之后打算如何处理数组,另一种解决方案可能是使用 LINQ。

var unsortedStartingArray = new[] {3, 6, 2, 1, 20, 20};
var q = unsortedStartingArray
        .Select((item, index) => new {item, index})
        .ToLookup(x => x.item, x => x.index);

var notFound = q[30]; // An empty array. Nothing found
var indexOf1 = q[1].First(); // returns 3
var multipleIndexsOf20 = q[20]; // Returns an array with 4, 5

查找的索引将是您正在搜索的值。性能方面,我估计这比我的粗略测试更快慢了大约 5 倍。

【讨论】:

    猜你喜欢
    • 2017-06-07
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 2022-01-22
    • 1970-01-01
    • 2019-11-25
    • 2016-02-17
    相关资源
    最近更新 更多