我有一个字符数组,可能看起来像:
1 0 0 1 1 1 0 0 0 1 1 0 1
我需要开发一种搜索算法来找到阵列中最合适的洞。我不能使用线性搜索。 (问题是......我想不出任何其他方式去做)。
基本上,如果我的程序输入是3个字节长,我需要一个函数,它会在数组中找到三个0并使用该点插入数据。
答案 0 :(得分:5)
如果数组是按原样给你的(你没有创建它),因为你知道你需要的洞的大小,你可以跳过大小,当你点击{{1}时向后看看看是否有空间。
如果您正在尝试找到3个字节和0
的洞,那么您就知道它不适合a[0] == 1
。向前跳至a[0] -> a[2]
,看看是否为a[3]
;如果是,请向前看,看看是否有3个字节的空间。
这只比通过列表开始 - 结束的蛮力方法略胜一筹,但它更好。
答案 1 :(得分:0)
您可以在开始之前将其编入索引。 在进行任何搜索之前,您可以扫描数组并创建结构列表,如:
struct SuitablePlace {
int pos;
ine len;
};
然后填写它,按len字段排序,当你收到具有特定大小的区域的请求时, 你可以使用二进制搜索来找到合适的地方。
答案 2 :(得分:0)
例如,像这样吗?
#include <stdio.h>
int main(){
char data[]={1,0,0,1,1,1,0,0,0,1,1,0,1};
int dataSize = sizeof(data)/sizeof(char);
int maxPos=-1;
int maxLen=0;
int pos;
for(pos=0; pos<dataSize;){
int skip = pos + maxLen;
if(skip >= dataSize)break;
if(data[pos] == 1){
if(skip + 1 < dataSize && data[skip + 1] == 1){//add skip proc for value of 1
pos = skip + 2;
continue;
}
++pos;
} else {
int len;
if(data[skip] == 1){
pos = skip + 1;
continue;
}
for(len = 1; pos + len < dataSize && data[pos+len] == 0;++len);
if(maxLen < len){
maxPos = pos;
maxLen = len;
}
pos += len + 1;
}
}
if(maxPos == -1){
printf("no space\n");
} else {
printf("The largest space is the area of length %d from position %d.\n", maxLen, maxPos);
}
return 0;
}
<强>结果强>
The largest space is the area of length 3 from position 6.
答案 3 :(得分:0)
因此,您将获得一个长度为 n 的数组和一个数字 k ,并要求在数组中找到最接近的孔k 尽可能,但不小。
由于没有关于数组的先验信息,并且无法保证 k 和 n 之间的关系,您必须花费 O(n / k)时间搜索数组以找到合适的洞。为什么?
以这种方式思考:先验,你有 n - k 位置可以开始你最合适的洞。如果查询数组中的单个元素,则可能提取的最多信息是数组中的 k 位置无法工作:
n = 12, k = 3
array: [ ? ][ ? ][ ? ][ ? ][ ? ][ ? ][ ? ][ ? ][ ? ][ ? ][ ? ][ ? ]
^-(query here, find it is occupied)
array: [ ? ][ X ][ X ][ X ][ ? ][ ? ][ ? ][ ? ][ ? ][ ? ][ ? ][ ? ]
Now you know the locations with X's cannot fit your data.
However, you can't know anything more than that.
从这里您可以看到,无论您的搜索算法或查询数组的顺序,您都需要 O(n / k)访问来确定任何洞的位置,更不用说最合适的。
P.S。“线性搜索”一词也存在一些混淆。对大多数人来说,这相当于说算法需要线性时间 - 而你的算法必须采用线性时间。如果你对你进行“线性搜索”意味着逐项逐项搜索整个数组,那么你可以在 O(n)上稍微改进 ,但不能超过 O(n)。 ķ。如果 k 应该是问题的常量,那么它就会消失,而你仍然会留下 O(n)。