[300技术分哦]怎样以最快的速度找一个数组中没有的最小数字

Waiting4you 2010-09-17 04:48:48
有一个BYTE类型的数组(这个数组中的数字当然只会是0~256啦),怎样以最快的速度找到一个该数组中没有的最小BYTE数字

例如
BYTE array[]={0,1,2,4,5,6,7,8,9};
怎样写BYTE GetNew(array, sizeof(array))函数,其返回值为3,即不属于array中的最小数字
...全文
317 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
hong_qi 2010-09-20
  • 打赏
  • 举报
回复
我的思路:先扫描一遍,看数组中有没有0,没有,继续扫描有没有1,如此继续,最多扫描256遍。
samchoy 2010-09-19
  • 打赏
  • 举报
回复
同意小僵,小僵也好久不见了啊,是不是也该散300分意思一下?
僵哥 2010-09-19
  • 打赏
  • 举报
回复
在数据不曾排序的前提条件下,对数据进行完整扫描是省不了的。因此,只要你想省,则免不了会增加工作量。通常在这种情况下,都是往O(N)复杂度靠拢,如果找不到O(N)的算法,则只能是O(N)+M,M<=256。

30楼的是一种方法,只是这种方法相对只是增加程序的复杂度。将256字节的数组改为了8字节。但是并没有减少必要的步骤。复杂程度完全等于O(N)+M,M<=256。在计算机指令序列里面位操作指令的指令周期并不等于0,即便是使用了预运算得到了一个位操作结果,那么也增加一个寻址操作过程,这是完全不必要的浪费。给人的感觉无非是一个为了运用位操作而使用位操作,整一个画蛇添足。
ThinkX 2010-09-19
  • 打赏
  • 举报
回复
四楼的做法:
unsigned int GetNew(const unsigned char* p, unsigned int len)
{
unsigned char flags[256];
memset(flags, 0, sizeof(flags));
for (unsigned int i = 0; i < len; i++)
flags[p[i]] = 1;

for (unsigned int i = 0; i < sizeof(flags); i++) {
if (flags[i] == 0)
return i;
}
return -1;
}

GetNew的返回值不能使用BYTE,要用更长的类型
僵哥 2010-09-19
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 waiting4you 的回复:]
to wangguanghui19841230
我也是这个想法,用32个字节的256位来表示这个集合,就是感觉这个位操作有点不够快的说。我在想直接用模板的方法在编译器时间取得1在1~8位上时的数值(就是1,2,4,8,16...这些)来代替0x01 << (Num %8) 操作。用查表法直接代替

C/C++ code
for(int j=0;j<8;++j)
{
if……
[/Quote]
内存的使用有必要从256字节节约到32字节吗?然后再用一个位操作来换取这些空间?
EagleFew 2010-09-19
  • 打赏
  • 举报
回复
嗯!

貌似有涉嫌抄袭4楼的说法!

跟4楼的想法差不多了。
Waiting4you 2010-09-19
  • 打赏
  • 举报
回复
to wangguanghui19841230
我也是这个想法,用32个字节的256位来表示这个集合,就是感觉这个位操作有点不够快的说。我在想直接用模板的方法在编译器时间取得1在1~8位上时的数值(就是1,2,4,8,16...这些)来代替0x01 << (Num %8) 操作。用查表法直接代替
  for(int j=0;j<8;++j)
{
if (!(a[i]<<j) &0x01)
return i * 8 + j;
}

操作,应该会快得多。

感谢大家,明天结贴
科多兽 2010-09-19
  • 打赏
  • 举报
回复
看到自己写的代码,太烂了。
科多兽 2010-09-19
  • 打赏
  • 举报
回复
这个让我想起了位图排序法,呵呵,记得在 编程遗珠 书籍的第一章有的.看过,忘记了,自己写下.


BYTE GetNew(BYTE array[],int n);
void SetBit(BYTE a[],BYTE Num)
{
a[Num/8] |= 0x01 << (Num %8) ;
}
BYTE GetMinByte(BYTE a[],int n)
{

for(int i=0;i<n;++i)
{
for(int j=0;j<8;++j)
{
if (!(a[i]<<j) &0x01)
return i * 8 + j;
}
}
}
BYTE GetNew(BYTE array[],int n);
{
BYTE Result[8] = {0};
for(int i=0;i<n;++i)
SetBit(Result,array[i]);
return GetMinByte(Result,8);
}
int main(int argc,char *argv[])
{
BYTE array[]={0,1,2,4,5,6,7,8,9};
printf("最小的数值是:%ud",GetNew(array,sizeof(array)));
return 0;
}

hemiya 2010-09-18
  • 打赏
  • 举报
回复

zzbinfo,僵哥,死牛之祭,正常思路.
怕沙特独特.
paste 2010-09-18
  • 打赏
  • 举报
回复
僵哥 跟 牛死哥 的应该是相当快没有嵌套循环。。 4楼貌似说的也是这个意思。
zzbinfo 2010-09-18
  • 打赏
  • 举报
回复
我又来了,超级无敌赖皮法,这个不是算法,认真的大牛绕路
BYTE GetNew2(BYTE array[], int size)
{
BYTE Ret =0;
AnsiString Temp = "";
for(int i = 0;i<size;i++)
{
Temp = Temp + IntToStr(array[i])+",";
}
for(int i = 0;i<size;i++)
{
if(!Temp.Pos(IntToStr(i)+","))
{
Ret = i;
break;
}
}
return Ret;
}

void __fastcall TForm1::btn2Click(TObject *Sender)
{
BYTE array[]={0,1,4,2,3,6,7,8,9};
ShowMessage(GetNew2(array, sizeof(array)));
}
EagleFew 2010-09-18
  • 打赏
  • 举报
回复
还是有问题。

char org[256] = {-1};
改成
memset(org, -1, sizeof(org));
EagleFew 2010-09-18
  • 打赏
  • 举报
回复
写错了!

努力争取上星星。如果该算法正确, 请楼主给俺200分。 如果不正确,俺就不要分了。
EagleFew 2010-09-18
  • 打赏
  • 举报
回复
努力争取上星星。如果该算法正确, 请楼主给俺200分。 如果不正确,俺就要分了。
思路:
1. 根据现有的数据来产生一个新的数组, 该数组中的元素是未出现在现有数组中的。
2. 从新的数组中找出最小的一个元素,就得到了目标元素

不知道理解正确了楼主的意思木有?!

unsigned char GetNew(unsigned char *array, size_t t, unsigned char &min)
{
char org[256] = {-1};
// 根据现有的数据生成一个新的数组,该数组中的元素未出现在现有的数组中。
for ( int i = 0; i < t; i++ )
{
org[array[i]] = 0;
}

// 查找出第一个值等于-1的元素, 该值就是最小的一个元素。
for ( int i = 0; i < 256; i++ )
{
if ( org[i] == -1 )
{
min = i;
return 1;
}
}

return 0;
}
僵哥 2010-09-18
  • 打赏
  • 举报
回复
没很仔细看楼上的代码。
提供一个思路,即利用散列来完成。

bool GetNew(unsigned char array[],size_t size, unsigned char &FoundByte)
{
bool Found[256] = {0};
for (int i = 0; i < size; i++) {
Found[array[i]] = true;
}
for (int i = 0; i < 256; i++) {
if (!Found[i]) {
FoundByte = i;

return true;
}
}
return false;
}
dfdscx 2010-09-18
  • 打赏
  • 举报
回复
杯具。。算法都还给老师了。
Waiting4you 2010-09-18
  • 打赏
  • 举报
回复
怕沙特和zzbinfo提供的代码和思路非常棒,期待更多,嘻嘻
这个需求有点类似于求一子集的补集(好像是这么叫的),只是还有个要求是取补集中最小值。
BORLANDSUN 2010-09-17
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 paste 的回复:]
C/C++ code

unsigned char GetNew(unsigned char *array, int n) {
for (int i = 0; i < n; i++) {
for (int j = i; j < (n - i); j++)
if (*(array + i) > *(array + j)) {
……
[/Quote]
有道理。
samchoy 2010-09-17
  • 打赏
  • 举报
回复
然后灰常热情的顶一下
加载更多回复(16)

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧