在C中比较两个数组,逐个元素

Lig*_*gXI 6 c arrays

为了使我的计算物理项目中的一个程序(不是由我编写)更加动态,我一直在努力实现C中非常简单的事情:在if条件下逐个元素地比较两个不同的数组.

#include <math.h>
#include <stdio.h>
#include "header.h"
const   int nParam = 10;
double  a[nParam], a_tmp[nParam];
double values[10000];

double FitParam(double x){
    int xindex;
    double value;

    xindex=(int) x;

    if (a_tmp[1]==a[1] && a_tmp[2]==a[2] && a_tmp[3]==a[3] && a_tmp[4]==a[4]){ 
        value=values[xindex];
        return(value);
    }

// code continues... (very long subroutine and there is recursion for
// the subroutine so this if statement above is very important).
Run Code Online (Sandbox Code Playgroud)

每次运行程序时,数组a []都有不同数量的重要元素; 例如,现在,我们仅将这个子程序用于元素[1]到[4].但是,在其他情况下,我们希望分别拥有更少或更多的元素,例如最多3个元素或最多5个元素.

基本上,我希望能够重写上面的if语句,使其成为动态...换句话说,如果考虑了N个元素,那么它将会:

if (a_tmp[1]==a[1] && ... && a_tmp[N]==a[N]){}

因此,每当我们感兴趣的元素的数量N改变时,条件应该变化(N被定义为该文件的头部中的#define,我将其命名为header.h).

非常感谢您对此任务的支持.谢谢.

Flo*_*ris 13

最好的办法是将其重写为返回true或false(1或0)的函数:

int compareArrays(double a[], double b[], int n) {
  int ii;
  for(ii = 1; ii <= n; ii++) {
    if (a[ii] != b[ii]) return 0;
    // better:
    // if(fabs(a[ii]-b[ii]) < 1e-10 * (fabs(a[ii]) + fabs(b[ii]))) {
    // with the appropriate tolerance
  }
  return 1;
}
Run Code Online (Sandbox Code Playgroud)

请注意,将双精度数比较为平等通常是不好的做法 - 您最好比较它们的差异,并确保绝对值小于某个容差.

另请注意,您正在比较元素1到n - C数组从0开始.

你可以使用上面的

if (compareArrays(a, a_tmp, N)) {
Run Code Online (Sandbox Code Playgroud)

其中值N#define"根据您的问题天.

如果你想"聪明"并避免循环,你可以编写以下内容 - 一旦达到正确的比较次数,它就会停止("短路").它还是一个坏主意来比较平等的双打,但我会留到另一个时间(见上一个解决方案中的代码注释).

if(a[1]==a_temp[1] && (2 > N || (a[2]==a_temp[2] && (3 > N || (a[3]==a_temp[3]))))) {
Run Code Online (Sandbox Code Playgroud)

true只要您比较了正确的术语数量,这就会使"和其余部分" - 所以它将停止评估术语(根据您的需要).我不相信这是更快或更好的代码 - 但它 "动态的"...你可以显然只要你愿意做这个表达; 我刚刚写了前三个术语,所以你得到了这个想法.我不推荐它.

至于双打的比较,你可以考虑更换

if(a == b)
Run Code Online (Sandbox Code Playgroud)

if(closeEnough(a, b))
Run Code Online (Sandbox Code Playgroud)

在哪里定义宏

#define closeEnough(a, b) (fabs((a)-(b)) < 1e-10 * (fabs(a) + fabs(b)))? 1 : 0
Run Code Online (Sandbox Code Playgroud)

这将确保你的双打不必"完全相等" - 取决于你如何到达它们,它们几乎永远不会,并且10 ^ 10中1部分的相对容差通常对于大多数实际比较来说是足够的.


dwe*_*ner 5

如果它必须在编译时,标准中没有任何内容可以提供像这样的重复宏.与另一个(问题)一样,对于有界N,您可以准备扩展到所需比较的N个宏.

而另一个替代方案是memcmp

memcmp( data, data2, array_len_in_bytes );
Run Code Online (Sandbox Code Playgroud)

参考