获取数组中元素索引的快速方法是什么?

时间:2010-08-17 08:10:14

标签: c# java .net

我在接受采访时被问到这个问题。虽然采访是针对网点位置的,但他在java的背景下问我这个问题,因为我在简历中也提到了java。

如何在数组中找到值为X的元素的索引?

我说从第一个元素迭代到最后一个元素并检查值是否为X将给出结果。他询问了一种涉及较少次迭代的方法,我说使用二进制搜索,但这只能用于排序数组。我试着在Array类中使用IndexOf函数。但我身边没有回答这个问题。

有没有快速的方法来获取数组中具有值X的元素的索引?

10 个答案:

答案 0 :(得分:16)

只要没有关于数组的知识(它是否已经排序?升序或降序等等),就无法在不检查每个元素的情况下找到元素。

此外,这正是indexOf所做的事情(使用列表时)。

答案 1 :(得分:11)

  
    

如何在数组中找到值为X的元素的索引?

  

这会很快:

int getXIndex(int x){
    myArray[0] = x;
    return 0;
}

答案 2 :(得分:9)

更快找到它的一种实用方法是并行处理。

将数组划分为N个部分,并将每个部分分配给一个线程,该线程遍历其部分的元素,直到找到值。 N应该最好是处理器的核心数。

答案 3 :(得分:3)

如果无法进行二进制搜索(因为数组没有排序)并且您没有某种高级搜索索引,我认为唯一的方法不是O(n)如果项目在数组中的位置是项目本身的函数(例如,如果数组是[10, 20, 30, 40],则元素n的位置为(n / 10) - 1)。

答案 4 :(得分:2)

也许他想测试你对Java的了解。

有一个名为Arrays的Utility Class,这个类包含各种操作数组的方法(如排序和搜索)

http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html

在2行中,您可以得到O(n * log n)结果:

    Arrays.sort(list); //O(n * log n)
    Arrays.binarySearch(list, 88)); //O(log n)

答案 5 :(得分:1)

Puneet - in .net its:

string[] testArray = {"fred", "bill"};
var indexOffset = Array.IndexOf(testArray, "fred");

[edit] - 现在正确阅读了问题,:) linq的另一个选择是:

string[] testArray = { "cat", "dog", "banana", "orange" };
int firstItem = testArray.Select((item, index) => new
{
    ItemName = item,
    Position = index

}).Where(i => i.ItemName == "banana")
  .First()
  .Position;

这当然会找到第一次出现的字符串。后续的重复将需要额外的逻辑。但那么循环的方法也是如此。

吉姆

答案 6 :(得分:1)

这是一个关于数据结构和算法的问题(尽管是一个非常简单的数据结构)。它超越了你正在使用的语言。

如果数组是有序的,你可以使用二进制搜索获得O(log n),并为边界情况获得它的修改版本(不使用always(a + b)/ 2作为支点,但它是一个非常复杂的怪癖)。

如果没有订购阵列那么......祝你好运。

他可以问你有什么方法可以在Java中找到一个项目。但无论如何他们并不快。它们可以更简单易用(比for-each - compare - return)。

还有另一个解决方案是创建一个辅助结构来进行更快速的搜索(比如散列图),但是,如果创建它并使用它一次比进行简单的线性搜索更昂贵。

答案 7 :(得分:0)

取一个完全未排序的数组,只是内存中的数字列表。机器可以做的就是查看内存中的个别数字,并检查它们是否是正确的数字。这是“密码破解者问题”。没有比从头开始搜索直到达到正确值更快的方法。

答案 8 :(得分:0)

你确定这个问题吗?我的问题有点类似于你的问题。

给定一个排序数组,有一个元素“x”,其值与索引相同,找到该元素的索引。

例如:

         //0,1,2,3,4,5,6,7,8,9, 10     
int a[10]={1,3,5,5,6,6,6,8,9,10,11};

在索引6处,值和索引相同。

对于这个数组a,答案应该是6。

这不是一个答案,如果在原始问题中遗漏了某些内容,这将澄清这一点。

答案 9 :(得分:0)

如果您只有 信息,它是一个未排序的数组,在索引和值之间没有关联,并且没有辅助数据结构,那么您必须检查每个元素,看它是否包含您想要的信息。

然而,采访是为了将小麦与谷壳分开,因此认识到他们想要了解你如何解决问题非常重要。因此,我们的想法是提出问题,看看是否(或可能)可用的更多信息,以及可以提高搜索效率的信息。

如下问题:


1 /数据是否经常变化?

如果没有,那么您可以使用额外的数据结构。

例如,保持最初为true的dirty标志。当你想找到一个项目并且它是真的时,构建那个将大大加速搜索的额外结构(排序的数组,树,哈希或其他),然后将dirty标志设置为false,然后使用找到该项目的结构。

如果要查找项目并且dirty标志为false,只需使用该结构,无需重建它。

当然,对数据的任何更改都应将dirty标志设置为true,以便下一次搜索重建结构。

这将极大地加速(通过摊销)对数据的查询,这些查询的阅读频率远高于写入数据。

换句话说,更改后的第一次搜索会相对较慢,但后续搜索会更快。

您可能希望将数组包装在一个类中,以便您可以正确控制dirty标志。


2 /我们是否允许使用与原始数组不同的数据结构?

这与上面给出的第一点类似。如果我们将数组中的数据结构修改为包含数组的任意类,您仍然可以获得所有优势,例如对每个元素的快速随机访问。

但是,只要数据发生变化,我们就获得更新数据结构中额外信息的能力。

因此,我们可以在下次搜索时使用dirty标记并执行大型更新,而不是每次使用更改额外信息数组已更改。

通过在所有更改中分摊成本(每次更改费用较低),可以消除更改后第一次搜索的缓慢响应。


第3。列表中通常包含多少项?

这实际上比大多数人意识到的更重要。

除非您的数据集相对较大且性能实际上很重要,否则所有关于优化的讨论都会毫无用处。

例如,如果你有100个项目的数组,那么即使使用脑死亡的冒泡排序也是可以接受的,因为它与你能找到的最快排序之间的时间差异往往是无关紧要的(除非你当然需要每秒数千次这样做。)

对于这种情况,找到给定值的第一个索引,只要您的数组保持在一定的大小范围内,它就可以完全接受进行顺序搜索。


底线是你在那里证明自己的价值,面试官(通常)在那里指导你。除非他们是虐待狂,否则他们很乐意向他们提出问题,试图缩小问题的范围。

提出问题(因为您可能会对数据进行排序。即使您无法出现,也应该对您的方法留下深刻印象。解决方案。

事实上(我过去已经这样做了),他们可能会拒绝所有可能的方法(不,它没有排序,不,不允许其他数据结构,等等)只是看看你能走多远。

也许,也许,就像 Kobayashi Maru,它可能不是关于获胜,它可能是你如何应对失败: - )