C 如何实现两个双浮点数组的集合并集,但允许误差为1微秒
我试图计算包含双浮点值的两个数组的并集(它们是以毫秒为单位的时间戳),但我需要允许+/-1微秒的公差 例如: 考虑下面两个不同列表(或数组)的两个值: 在上述两个0.001微秒的数字之间有一个小的增量。因此,当我创建新的联合列表时,它们不应该都显示为唯一的,而应该被计算为一个项目,并且应该只包含第一个列表中的项目(在本例中,参考1,以059.841结尾) 以上类型的更多示例:C 如何实现两个双浮点数组的集合并集,但允许误差为1微秒,c,C,我试图计算包含双浮点值的两个数组的并集(它们是以毫秒为单位的时间戳),但我需要允许+/-1微秒的公差 例如: 考虑下面两个不同列表(或数组)的两个值: 在上述两个0.001微秒的数字之间有一个小的增量。因此,当我创建新的联合列表时,它们不应该都显示为唯一的,而应该被计算为一个项目,并且应该只包含第一个列表中的项目(在本例中,参考1,以059.841结尾) 以上类型的更多示例: [ref 21 : 1114974794.562] [dut 18 : 1114974794.560] [ref
[ref 21 : 1114974794.562] [dut 18 : 1114974794.560]
[ref 22 : 1114974827.840] [dut 19 : 1114974827.840]
[ref 23 : 1114974861.121] [dut 20 : 1114974861.120]
应将上述所有内容视为一个,因此联合列表应仅包含第一个列表中的一项:联合列表将包含ref
数组中的所有三项,而dut
数组中没有任何一项
现在考虑例子:
[ref 8 : 1114974328.641] [dut 8 : 1114974361.921]
在这里,上面列表中两个值之间的增量对于微秒来说非常重要,它小于.01微秒,因此应被视为新联合列表中的两个唯一项
下面是另一个类似于上述示例的示例:
[ref 13 : 1114974495.041] [dut 12 : 1114974528.321]
[ref 26 : 1114974960.960] [dut 23 : 1114975027.520]
[ref 27 : 1114974994.240] [dut 23 : 1114975027.780]
在新的工会名单中,他们都应该被认为是独一无二的
你能帮我吗
我制作了一个子程序,允许我检测如下公差:
unsigned int AlmostEqualRelative(double A, double B, double maxRelDiff){
double diff = fabs(A - B); // Calculate the difference.
//
if (diff < maxRelDiff) {
//printf("\n page hit [ref: %10.3f] [dut: %10.3f]",A,B);
return 1;
}
//printf("\n page miss [ref: %10.3f] [dut: %10.3f]",A,B);
return 0;
}
unsigned int-AlmostEqualRelative(双A、双B、双maxRelDiff){
double diff=fabs(A-B);//计算差值。
//
if(diff
我将maxRelDiff设为.02。假设两个列表的大小相同:
unsigned int // size of output array
union_list(const double *list1, // first list
const double *list2, // second list
double* ulist, // output list
unsigned int size) // size of input list
{
unsigned int i = 0u, j = 0u ;
for(; i < size; ++i, ++j)
{
result = is_near(list1[i], list[2]);
if (result == 1)
{
ulist[j] = list1[i] ;
}
else
{
ulist[j] = list1[i] ;
j += 1 ;
ulist[j] = list2[i];
}
}
return j ;
}
您可以这样做:
unsigned int AlmostEqualRelative(double A, double B, double maxRelDiff){
double diff = fabs(A - B); // Calculate the difference.
//
if (diff < maxRelDiff) {
//printf("\n page hit [ref: %10.3f] [dut: %10.3f]",A,B);
return 1;
}
//printf("\n page miss [ref: %10.3f] [dut: %10.3f]",A,B);
return 0;
}
首先,复制ref
数组的foo
foo
必须足够大,以存储ref
和dut
数组的元素,因为它们可能相互排斥
len=0;
for(i=0;i<length_ref;i++)
foo[len++]=ref[i];
一种方法是将
AlmostEqualRelative
函数重写为符合原型int(*compar)(const void*,const void*)
(即根据参数的相对顺序返回负、零或正)。这使得它适合传递给qsort
(3)函数
这样,您就可以将两个起始数组连接起来,qsort
这需要一点簿记和一点额外的空间,但它使用现有的代码(即,qsort
),并且除非您的数组太大以至于额外的空间成为一个问题,否则这可能是找到解决方案的最直接途径
也就是说,这在道德上等同于通过执行
catf1 f2 | sort | uniq
获得两个文件的集合并集,但是在uniq
比较中有一些模糊性。Ok,union
是C语言中的一种特殊数据结构,令人困惑。你的问题是指两个集合的并集,对吗?我想你应该澄清一下。我不太清楚你在处理什么数组。您是否有两个双精度阵列,带有计数器以指示它们的满度?或者你在使用某种链表?不过,使用AlmostEqualRelative(…)
函数,您肯定走在了正确的轨道上。尽管您可以将其设置为bool
,而不是无符号int,这只是为了提高效率和符合约定unsigned int
s也可以。如果您知道如何使用相等运算符编写常规的“union”运算,您可以使用AlmostEqual
运算符以同样的方式重写它。@Dan:是的,我有两个双精度数组。一个名为ref的数组和一个名为dut的数组,其中包含数量不等的双浮点数。不幸的是,我的两个列表的大小不一样:(Hmmm)通过为qsort()重新定义=
,这会导致A==B
,B==C
,但可能A!=C
。我认为这可能会愚弄qsort()
太多,导致“排序”数组未完全排序。“然后处理结果数组”在查找“单个示例”时变得模糊嗯,非常正确。事实上,我认为这个问题根本上是不适定的,或者至少是一个比最初出现的更复杂的问题。考虑一个数字序列(0,0.1,0.2,0.3,…,10)。这些都是完全排序的,并且每个这些都等于它的继承者,即0.15的容忍度。(OP想要的“相等”的定义,更接近于数学的概念”,但是显然0和10不应该被看作是等价的。这个问题并没有一个简单的答案。
len=0;
for(i=0;i<length_ref;i++)
foo[len++]=ref[i];
for(i=0;i<length_dut;i++)
{
flag=1;
for(j=0;j<length_ref;j++)
if(AlmostEqualRelative(dut[i],ref[j],MAXRELDIFF))
{
flag=0;
break;
}
if(flag)
foo[len++]=dut[i];
}