I have been cracking my head at achieving something very simple in C in order to make my one of the programs (not written by me) in our computational physics project more dynamic: comparing two different arrays element by element in an if conditional.
为了使我的计算物理项目中的一个程序(不是由我编写)更加动态,我一直在努力实现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).
The array a[ ] has a varying number of significant elements every time we run our program; for example, right now, we are using this subroutine for only elements [1] through [4]. However, in other cases, we will want to have fewer or more elements, say, up to 3 elements or up to 5 elements, respectively.
每次运行程序时,数组a []都有不同数量的重要元素;例如,现在,我们仅将这个子程序用于元素[1]到[4]。但是,在其他情况下,我们希望分别拥有更少或更多的元素,例如最多3个元素或最多5个元素。
So essentially, I want to be able to rewrite the if statement above so that it is dynamic... in other words, if there are N elements considered, then it will do:
基本上,我希望能够重写上面的if语句,使其成为动态...换句话说,如果考虑了N个元素,那么它将会:
if (a_tmp[1]==a[1] && ... && a_tmp[N]==a[N]){}
if(a_tmp [1] == a [1] && ... && a_tmp [N] == a [N]){}
So this if conditional should vary whenever our number N of elements of interest is changed (N is defined as a #define in the header of this file, which I just named header.h).
因此,每当我们感兴趣的元素的数量N改变时,条件应该变化(N被定义为该文件的头部中的#define,我将其命名为header.h)。
I would greatly appreciate your support on this task. Thank you.
非常感谢您对此任务的支持。谢谢。
4 个解决方案
#1
13
Your best bet is to rewrite it as a function that returns true or false (1 or 0):
最好的办法是将其重写为返回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;
}
Note that it is usually bad practice to compare doubles for equality - you are better off comparing their difference, and making sure the absolute value is less than some tolerance.
请注意,将双精度数比较为平等通常是不好的做法 - 您最好比较它们的差异,并确保绝对值小于某个容差。
Also note you are comparing elements 1 through n - C arrays start at 0 though.
另请注意,您正在比较元素1到n - C数组从0开始。
You would use the above with
你可以使用上面的
if (compareArrays(a, a_tmp, N)) {
where the value N
is #define
'd per your question.
根据您的问题,值N定义为#defined'd。
If you want to be "clever" and avoid a loop, you can write the following - it will stop ("short-circuiting") as soon as you reach the right number of comparisons. It is still a Bad Idea to compare doubles for equality but I will leave that for another time (see comment in code above for a solution).
如果你想“聪明”并避免循环,你可以编写以下内容 - 一旦达到正确的比较次数,它就会停止(“短路”)。将双打比较为平等仍然是一个坏主意,但我会将其留下另一次(请参阅上面的代码中的注释以获得解决方案)。
if(a[1]==a_temp[1] && (2 > N || (a[2]==a_temp[2] && (3 > N || (a[3]==a_temp[3]))))) {
This makes the "and the rest" true
as soon as you have compared the right number of terms - so it will stop evaluating terms (as you need). I am not convinced this is either faster, or better code - but it is "dynamic"... You can obviously make this expression as long as you would like; I just wrote the first three terms so you get the idea. I DO NOT RECOMMEND IT.
一旦你比较了正确数量的术语,这就使“和其他”成立了 - 因此它将停止评估术语(根据需要)。我不相信这是更快或更好的代码 - 但它是“动态的”...你可以显然只要你愿意做这个表达;我刚刚写了前三个术语,所以你得到了这个想法。我不推荐它。
As for the comparison of doubles, you might consider replacing
至于双打的比较,你可以考虑更换
if(a == b)
with
if(closeEnough(a, b))
where you define the macro
在哪里定义宏
#define closeEnough(a, b) (fabs((a)-(b)) < 1e-10 * (fabs(a) + fabs(b)))? 1 : 0
This will make sure that your doubles don't have to be "exactly equal" - depending on how you arrived at them, they will almost never be, and the relative tolerance of 1 part in 10^10 is usually plenty for most practical comparisons.
这将确保你的双打不必“完全相等” - 取决于你如何到达它们,它们几乎永远不会,并且10 ^ 10中1部分的相对容差通常对于大多数实际比较来说是足够的。
#2
5
If it must be at compile time, there is nothing in the standard that provides for a repeating macro like that. As in another (question), for bounded N, you can prepare N macros that expand to your desired comparison.
如果它必须在编译时,标准中没有任何内容可以提供像这样的重复宏。与另一个(问题)一样,对于有界N,您可以准备扩展到所需比较的N个宏。
While yet another alternative is memcmp
另一种选择是memcmp
memcmp( data, data2, array_len_in_bytes );
#3
2
An implementation might be to loop over all the elements and set a flag when a difference is detected
实现可能是遍历所有元素并在检测到差异时设置标志
int i, N;
int is_equal = 1;
for (i=1; i<N; ++i) {
if (a[i] != a_tmp[i]) {
is_equal = 0;
break;
}
}
if (is_equal)
printf("Arrays are equal");
#4
-1
Today i came across same kind of problem statement,i googled for solution for an hour and end up with no solution,the above all approaches are not correct solutions for the stated problem
今天我遇到了同样的问题陈述,我搜索了一个小时的解决方案,最终没有解决方案,上述所有方法都不是解决上述问题的正确方法
The Better way to resolve above Problem is
解决上述问题的更好方法是
Sort the two arrays either in ascending or descending order, Then compare both the arrays.
按升序或降序对两个数组进行排序,然后比较两个数组。
#include<stdio.h>
void sort_it(int a[], int size)
{
int i,j,temp=0;
for(i=0;i<size;++i)
{
for(j=i+1;j<size;++j)
{
if(a[i]>a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
};
int compare(int size,int a[],int b[])
{
int i,j,is_equal;
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)`enter code here`
{
if(a[i]!=b[j])
{
is_equal=0;
}
else
is_equal=1;
}
}
return is_equal;
};
int main()
{
int size=4,i,is_equal;
int a[]={1,2,5,4};
int b[]={1,7,4,2};
sort_it(a,size);
sort_it(b,size);
is_equal=compare(4,a,b);
if(is_equal)
printf("arrays are equal\n");
else
printf("arrays are not equal\n");
return (0);
}
#1
13
Your best bet is to rewrite it as a function that returns true or false (1 or 0):
最好的办法是将其重写为返回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;
}
Note that it is usually bad practice to compare doubles for equality - you are better off comparing their difference, and making sure the absolute value is less than some tolerance.
请注意,将双精度数比较为平等通常是不好的做法 - 您最好比较它们的差异,并确保绝对值小于某个容差。
Also note you are comparing elements 1 through n - C arrays start at 0 though.
另请注意,您正在比较元素1到n - C数组从0开始。
You would use the above with
你可以使用上面的
if (compareArrays(a, a_tmp, N)) {
where the value N
is #define
'd per your question.
根据您的问题,值N定义为#defined'd。
If you want to be "clever" and avoid a loop, you can write the following - it will stop ("short-circuiting") as soon as you reach the right number of comparisons. It is still a Bad Idea to compare doubles for equality but I will leave that for another time (see comment in code above for a solution).
如果你想“聪明”并避免循环,你可以编写以下内容 - 一旦达到正确的比较次数,它就会停止(“短路”)。将双打比较为平等仍然是一个坏主意,但我会将其留下另一次(请参阅上面的代码中的注释以获得解决方案)。
if(a[1]==a_temp[1] && (2 > N || (a[2]==a_temp[2] && (3 > N || (a[3]==a_temp[3]))))) {
This makes the "and the rest" true
as soon as you have compared the right number of terms - so it will stop evaluating terms (as you need). I am not convinced this is either faster, or better code - but it is "dynamic"... You can obviously make this expression as long as you would like; I just wrote the first three terms so you get the idea. I DO NOT RECOMMEND IT.
一旦你比较了正确数量的术语,这就使“和其他”成立了 - 因此它将停止评估术语(根据需要)。我不相信这是更快或更好的代码 - 但它是“动态的”...你可以显然只要你愿意做这个表达;我刚刚写了前三个术语,所以你得到了这个想法。我不推荐它。
As for the comparison of doubles, you might consider replacing
至于双打的比较,你可以考虑更换
if(a == b)
with
if(closeEnough(a, b))
where you define the macro
在哪里定义宏
#define closeEnough(a, b) (fabs((a)-(b)) < 1e-10 * (fabs(a) + fabs(b)))? 1 : 0
This will make sure that your doubles don't have to be "exactly equal" - depending on how you arrived at them, they will almost never be, and the relative tolerance of 1 part in 10^10 is usually plenty for most practical comparisons.
这将确保你的双打不必“完全相等” - 取决于你如何到达它们,它们几乎永远不会,并且10 ^ 10中1部分的相对容差通常对于大多数实际比较来说是足够的。
#2
5
If it must be at compile time, there is nothing in the standard that provides for a repeating macro like that. As in another (question), for bounded N, you can prepare N macros that expand to your desired comparison.
如果它必须在编译时,标准中没有任何内容可以提供像这样的重复宏。与另一个(问题)一样,对于有界N,您可以准备扩展到所需比较的N个宏。
While yet another alternative is memcmp
另一种选择是memcmp
memcmp( data, data2, array_len_in_bytes );
#3
2
An implementation might be to loop over all the elements and set a flag when a difference is detected
实现可能是遍历所有元素并在检测到差异时设置标志
int i, N;
int is_equal = 1;
for (i=1; i<N; ++i) {
if (a[i] != a_tmp[i]) {
is_equal = 0;
break;
}
}
if (is_equal)
printf("Arrays are equal");
#4
-1
Today i came across same kind of problem statement,i googled for solution for an hour and end up with no solution,the above all approaches are not correct solutions for the stated problem
今天我遇到了同样的问题陈述,我搜索了一个小时的解决方案,最终没有解决方案,上述所有方法都不是解决上述问题的正确方法
The Better way to resolve above Problem is
解决上述问题的更好方法是
Sort the two arrays either in ascending or descending order, Then compare both the arrays.
按升序或降序对两个数组进行排序,然后比较两个数组。
#include<stdio.h>
void sort_it(int a[], int size)
{
int i,j,temp=0;
for(i=0;i<size;++i)
{
for(j=i+1;j<size;++j)
{
if(a[i]>a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
};
int compare(int size,int a[],int b[])
{
int i,j,is_equal;
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)`enter code here`
{
if(a[i]!=b[j])
{
is_equal=0;
}
else
is_equal=1;
}
}
return is_equal;
};
int main()
{
int size=4,i,is_equal;
int a[]={1,2,5,4};
int b[]={1,7,4,2};
sort_it(a,size);
sort_it(b,size);
is_equal=compare(4,a,b);
if(is_equal)
printf("arrays are equal\n");
else
printf("arrays are not equal\n");
return (0);
}