为了让我的计算物理项目中的一个程序(不是由我编写)更加动态,我一直在为实现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).
每次运行程序时,数组a []都有不同数量的重要元素;例如,现在,我们仅将这个子程序用于元素[1]到[4]。但是,在其他情况下,我们希望分别拥有更少或更多的元素,例如最多3个元素或最多5个元素。
基本上,我希望能够重写上面的if语句,使其成为动态...换句话说,如果考虑了N个元素,那么它会做:
if (a_tmp[1]==a[1] && ... && a_tmp[N]==a[N]){}
因此,只要我们感兴趣的元素的数量N发生变化,条件就会发生变化(N在此文件的标题中被定义为#define,我只是将其命名为header.h)。
非常感谢您对此任务的支持。谢谢。
答案 0 :(得分: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;
}
请注意,将双打比较为相等通常是不好的做法 - 您最好比较它们的差异,并确保绝对值小于某个容差。
另请注意,您正在比较元素1到n - C数组从0开始。
你可以使用上面的
if (compareArrays(a, a_tmp, N)) {
根据您的问题,值N
为#define
。
如果你想“聪明”并避免循环,你可以编写以下内容 - 一旦达到正确的比较次数,它就会停止(“短路”)。 仍然一个错误的想法来比较双打的相等性,但我会将其留下另一次(请参阅上面的代码中的注释以获得解决方案)。
if(a[1]==a_temp[1] && (2 > N || (a[2]==a_temp[2] && (3 > N || (a[3]==a_temp[3]))))) {
一旦您比较了正确的术语数量,这就会使“和其他人”true
- 所以它将停止评估术语(根据您的需要)。我不相信这是更快或更好的代码 - 但它是“动态”...你可以显然只要你愿意做这个表达;我刚刚写了前三个术语,所以你得到了这个想法。我不推荐它。
对于双打的比较,您可以考虑替换
if(a == b)
与
if(closeEnough(a, b))
您定义宏
#define closeEnough(a, b) (fabs((a)-(b)) < 1e-10 * (fabs(a) + fabs(b)))? 1 : 0
这将确保你的双打不必“完全相等” - 取决于你如何到达它们,它们几乎永远不会,并且10 ^ 10中1部分的相对容差通常是足够的最实际的比较。
答案 1 :(得分:5)
如果它必须在编译时,标准中没有提供像这样的重复宏。与另一个(question)一样,对于有界N,您可以准备N个宏,扩展到您想要的比较。
另一种选择是memcmp
memcmp( data, data2, array_len_in_bytes );
答案 2 :(得分:2)
实现可能是遍历所有元素并在检测到差异时设置标志
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");
答案 3 :(得分:0)
一个简单的实现是两个数组之间的线性比较,它只是遍历数组长度并检查if (a[i] != b[i])
,如果是,则返回false
并停止迭代。
请参见以下示例:
#include <stdio.h>
int compareArrays(int a[], int b[], int n)
{
for (int i=0; i<n; ++i)
{
if (a[i] != b[i])
{
return -1;
break;
}
}
return 0;
}
int main()
{
int arr1[4] = {3, 4, 5, 7};
int arr2[4] = {3, 4, 5, 7};
int arr3[4] = {1, 5, 3, 7};
int arr4[4] = {3, 4, 5, 19};
printf("Should be True %d\n", compareArrays(arr1, arr2, 4));
printf("Should be False %d\n", compareArrays(arr3, arr4, 4));
return 0;
}
您应该得到:
Should be True 0
Should be False -1
答案 4 :(得分:-1)
今天我遇到了同样的问题陈述,我搜索了一个小时的解决方案并最终没有解决方案,上述所有方法都不是解决所述问题的正确方法
解决上述问题的更好方法是
按升序或降序对两个数组进行排序,然后比较两个数组。
#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);
}