清除一个定义元素的数组 - 页 29

 
Sergey Dzyublik:
本质上,你是在使用一个静态的HashSet数据结构,用一个初始的数据数组来解决碰撞问题。
但实施起来却让人大开眼界......。

与其调用带有100-500个不必要参数的函数("FindValueInSortArray"),通常使用类,这些参数作为类的字段(如果编译器没有猜到要进行隐式内联,则在传递参数 时获得收益)。
如果需要使用一对大小相同且有一个使用目的的数组(int p1[]; int p2[];),通常会使用结构数组(索引访问优势,减少缓存丢失的机会)。

是的,我知道。我同意,我自己也很害怕自己的实施。但我的目标是算法,而不是实现。正如他们所说--"跪着组装"(大约一个半小时),以检查算法的正确性和速度。记得这个主题讨论的是(我引用)"刷新垃圾值数组的最快方法"。

虽然我对自己的算法有很多抱怨,因为它远非普遍适用。我可以看到改进算法的方法,但代码将变得更加复杂。遗憾的是时间问题。

ZZY HashSet第一次听到,因为我在理论上不强。我很清楚,我没有发明任何新东西,一切都在我之前被发明了。:))当要删除的项目阵列具有均匀分布时,这种算法的优势就很明显了。如果分布与均匀性有很大不同,这个实现在速度上可能不如这个分支中已有的其他实现。

 
Taras Slobodyanik:

将金额的计算改为CRC32 )

谢谢你。当然,这更正确。

但据我所知,改用CRC32并没有发现任何错误。:)

 

让我告诉你,我个人对现代计算机的能力印象深刻,尤其是MQL5。

毕竟,在一个有一百万个元素的数组中搜索大约一千个不同的值,删除它们(大约10万个单元)并重新包装清洁的数组,只需要1/40秒(!!)。

 
优化的
附加的文件:
 
nicholi shen :

这一切都非常简单!:))

但是,这种算法会不加控制地消耗内存。

因此,举例来说,如果你把

arr[i]= rand ()% 10000 ;
....
Value2[i]= rand ()% 10000 ;

与 .

arr[i]= rand ()* rand ();
....
Value2[i]= rand ()* rand ();

情况则完全不同。

2018.11 . 19 23 : 25 : 57.593 ArrayDeleteValue21 (NZDUSD,D1)  вариант nicholi shen: Контрольная сумма = 3902843984.813025 ; элементов - 999983 ; время выполнения -  603551 микросекунд
2018.11 . 19 23 : 25 : 57.980 ArrayDeleteValue21 (NZDUSD,D1)  вариант Nikitin     : Контрольная сумма = 3902843984.813025 ; элементов - 999983 ; время выполнения -  383847 микросекунд
2018.11 . 19 23 : 25 : 58.043 ArrayDeleteValue21 (NZDUSD,D1)  вариант fan9        : Контрольная сумма = 3902843984.813025 ; элементов - 999983 ; время выполнения -   61414 микросекунд
2018.11 . 19 23 : 25 : 58.074 ArrayDeleteValue21 (NZDUSD,D1)  вариант Semko       : Контрольная сумма = 3902843984.813025 ; элементов - 999983 ; время выполнения -   28430 микросекунд
附加的文件:
 
项目 中又增加了ArrayDeleteValue 的几个人,权利编辑。我以前错过了谁。
 
Nikolai Semko:

谢谢你。这当然是正确的方法。

但据我所知,改用CRC32并没有发现任何错误。:)

是的,但现在那些只亲眼看到一种算法结果的人,可以确保其他人得到同样的结果)

 
请写下这个主题。没有闪烁其词或说脏话。谢谢你。
 
nicholi shen:

这不是一个坏主意,但如果数组或向量中存在负值,你会得到一个数组超出范围的错误

此外,带有过滤标志的数组的大小 可能达到2 147 483 647,这太多了

当然,你可以把32个BOOL变量的设置换成像这样的比特掩码来减少32倍的大小。

int array_filter(int &a[],const int &b[]) //nicholishen
{
   int e=ArraySize(a);
   int c[];
   int d =b[ArrayMaximum(b)]+1;
   ArrayResize(c, b[ArrayMaximum(b)]/32 + 1);
   ArrayInitialize(c, 0);
   int i=0;
   int ii=0;
   while(i<ArraySize(b))
   {     
     ii=b[i]/32;
     c[ii]|=(1<<(b[i]-(ii*32)));
     i++; 
   } 
   
   int g=0, h=0, f=0;
   for(g=0; g<e; g++){
      f = a[g];
      ii=f/32;
      if(f >= d || !(c[ii] & (1<<(f-(ii*32)))) )
      {
         a[h]=f;
         h++;
      }
   }
   return ArrayResize(a, h);
}


但它仍然太大,速度会下降一半左右。

 
Nikolai Semko:

这一切都非常简单!:))

但是,这种算法会不加控制地消耗内存。

因此,举例来说,如果你把

与 .

情况则完全不同。

你的版本也很好,但不幸的是你也有一个弱点。在 "国内 "条件下,即大小为~100的小阵列和小矢量~5-10的小阵列

你的算法将比这里介绍的所有算法都要慢,尽管微秒的差别是如此的微不足道,可能并不重要,但在较大的数组 上,它是最好的。

P.S 我认为,该功能应该是通用的,有必要根据输入数据将一些不同的算法结合在一起。