在不使用循环的情况下确定特定元素的数组索引

时间:2018-04-24 15:18:52

标签: c arrays

假设array的长度是动态的,并且元素遵循相同的模式,其中下一个元素是前一个元素的一半。例如1024,512,256,128 ......

我想直接确定元素的索引。例如,如果我有512我将输出index 1而不循环遍历元素并将它们与512进行比较然后输出1.即使不是这样:

for (int i = 0;  i < length;  ++i) {
    if (array[i] == 512) { 
        printf("%d\n", i);
        break;
    }
}

我一直在考虑使用模数位操作,如移位,但我无法使其工作。如何实现这一目标?

3 个答案:

答案 0 :(得分:3)

数组的元素是:1024 512 256 128。它们都是2的幂,所以取每个元素的log2将给出:

10, 9, 8, 7

所以你可以这样做:

if array[i]==n
        print 10-log2(n)

此解决方案仅对您指定的预定义数组有效。

#include <stdio.h>
#include <math.h>

int main(void) {
    int a[4] = {1024, 512, 256, 128};
    for(size_t i=0;i<4;i++)
        printf("%d %d\n",a[i],10-(int)log2(a[i]));
    return 0;
}

输出:

1024 0
512 1
256 2
128 3

答案 1 :(得分:0)

如果您确定给定的值是正确的(即您不需要验证),这应该有效:

3 - ( n >> 8 ) + ( n >> 10 )

live example

另一个选择是使用3个条件(但总共只有2个条件被执行),但由于分支预测,这很可能会更慢:

n > 512 ? ( n < 1024 ? 1 : 0 ) : ( n > 128 ? 2 : 3 )

如果你的数组可以是这个问题Find the highest order bit in C

中任意大小的使用方法
int hibit(unsigned int n) {
    n |= (n >>  1);
    n |= (n >>  2);
    n |= (n >>  4);
    n |= (n >>  8);
    n |= (n >> 16);
    return n - (n >> 1);
}

只是从正确的数字中减去结果。

答案 2 :(得分:0)

解决方案10-log2(n),其中n是需要确定其索引的数组元素,这给了我一个见解。我正在努力弄清楚10-log2(n)中10的含义。我意识到通用解决方案是log2(X)-log(n),其中X是数组中最大的已知元素。 数组应按降序排序,以使第0个元素为最大

实施例

Array[5]={2048, 1024, 512, 256, 128};

要查找数组元素256的索引,将log2(2048)-log2(256)=11-8=3因此,一般解决方案是log2(largest array element)-log2(base2 value you are looking for) 你必须知道最大的数组元素和数组 按降序排序 Live example here

最佳选项:index=log2(array[0]/value) 其中value是确定其索引的数组元素 index=log2(array[0]/value) live example here