为什么我的程序是,数组中任意两个元素之间的最小差异,给出相反的结果

Why is my program for, minimum difference between ANY TWO elements in an array, giving opposite result?

本文关键字:结果 之间 程序 我的 数组 元素 任意两 为什么      更新时间:2023-10-16

这听起来像是一个重复的问题,但这并不是因为我没有找到问题的答案,尽管经历了下面列出的几个参考/相关问题(还有更多未列出)。

数组中的最小差分

找出数组中元素之间的最小差异

查找两个数组之间的最小差异

查找两个数组之间的最小差异

将数组划分为两个大小相等的子集,其值总和差异最小

http://www.geeksforgeeks.org/find-the-minimum-distance-between-two-numbers/

http://programmingpraxis.com/2013/10/15/find-the-minimum-difference/#comment-9146

https://www.daniweb.com/programming/software-development/threads/391082/distance-between-two-closest-elements-in-an-array

以下是我的程序和我自己的尝试,试图找到"数组中两个元素之间的最小差异,任何两对",然后让多对数字在数字上给出相同的最小差异。我尝试更改循环以不同的方式计算它们,并尝试更改 if 条件子句以获得不同的结果,但最终得到以下代码:

#include <iostream>                     //input output stream   
#include <cstdlib>
#include "math.h"                       //to be able to use math functions if any

using namespace std;
int main()
{
    
    int x=0,y=0,number1 = 0,number2 = 0,size1=0,mindiff = 0;
    int index = 0, count = 0, diff = 0;
    cout<<"enter the size of array you want nn";
    cin>>size1;
    int arr1[size1];
    cout<<"nn please enter elements of array nn";
    
    for (int i =0;i<size1;i++)
    {
        cin>>arr1[i];
    }
    for ( x=0;x<size1;x++ )
    {
        diff = 0;
        for ( y=0;y<size1;y++ )
        {
            diff = abs(arr1[x] - arr1[y]);
            if (diff<mindiff)
            {
                mindiff = diff;
                //index = x+1;
                number1 = arr1[x];
                number2 = arr1[y];
            }
        }
            
        }   

cout<<"nthe elements amongst which the minimum difference was given are "<<number1<<" & "<<number2<<endl;
cout<<"the difference between them is "<<abs(mindiff)<<endl;
    
system("pause");
return 0;
}

//end of program

以上所有参考资料以及更多内容,但找不到任何遵循我观点的人。我知道我可能在这里做了一些非常愚蠢/错误的事情,因为我得到了最大的差异而不是最小的差异。我哪里出错了?无论如何,每次发现较低的差异时,我都必须继续分配新的最小值,如 if 条件语句中写的那样正确???

以下是输出

输入所需的数组大小

6

请输入数组的元素

1234345789

其中给出最小差值的元素是 1 和 34345它们之间的区别是34344

按任意键继续 . . .

使用 abs(x) 函数来确保 diff 是正数。否则,arr1[x]:5 和 arr1[y]:10 (5-10=-5) 之间的差值将小于 arr1[x]:5 和 arr1[y]:4 (5-4=1) 之间的差值。

http://www.cplusplus.com/reference/cstdlib/abs/

您还希望确保永远不会使用相同的索引进行检查,即 x=y。

您可以通过考虑底层模拟来稍微改进您的算法(实际上将比较减半):

#include <iostream>
#include <limits>
using std::cout;
// I'll use a struct to return the values
struct dif_t {
    int first;
    int second;
    int dif;
};
dif_t min_difference( const int *x, size_t n ) {
    dif_t min{0,0,0};
    min.dif = std::numeric_limits<int>::max();
    for ( size_t i = 0; i < n; ++i ) {
        //remember that abs(x[i]-x[j])=abs(x[j]-x[i]) and x[i]-x[i]=0
        for ( size_t j = i + 1; j < n; ++j ) {
            //          ^^^^^^^
            int dif = abs( x[i] - x[j] );
            if ( dif < min.dif ) {
                min.dif = dif;
                min.first = x[i];
                min.second = x[j];
            }
        }
    }
    return min;
}
int main() {
    // I'll skip the input part
    int numbers[] = { 1, 20, 34345, 89, 7, 88 };
    dif_t edif = min_difference(numbers, sizeof(numbers)/sizeof(int));
    std::cout << "The elements with the minimum difference are:n"
        << edif.first << " and " << edif.second << 'n'
        << "The difference between them is:n" << edif.dif << 'n';
    return 0;
}

如果你想找到所有具有相同最小差值的对,你可以像这样修改前面的程序:

#include <iostream>
#include <limits>
#include <vector>
#include <utility>
using std::cout;
using std::vector;
using std::pair;

struct dif_t {
    vector<pair<int,int>> pairs;
    int dif;
};
dif_t min_difference( const vector<int> &x ) {
    dif_t min;
    min.dif = std::numeric_limits<int>::max();
    for ( size_t i = 0; i < x.size(); ++i ) {
        for ( size_t j = i + 1; j < x.size(); ++j ) {
            int dif = abs( x[i] - x[j] );
            if ( dif > min.dif ) continue;
            // if the difference is less then the minimum, empties the container
            if ( dif < min.dif ) {
                min.dif = dif;
                min.pairs.clear();
            }
            // add the couple to the vector
            min.pairs.push_back(std::make_pair(x[i], x[j]));
        }
    }
    return min;
}
int main() {
    vector<int> numbers = { 1, 2, 4, 34345, 34346, 6, 89, 7, 88 };
    dif_t edif = min_difference(numbers);
    cout << "The elements with the minimum difference are:n";
    // loop for each couple in the container
    for ( auto & c : edif.pairs ) {
        cout << c.first << " and " << c.second << 'n';
    }       
    cout << "The difference between them is:n" << edif.dif << 'n';
    return 0;
}

哪些输出:

The elements with the minimum difference are:
1 and 2
34345 and 34346
6 and 7
89 and 88
The difference between them is:
1

如果元素的数量更大,正如其他人指出的那样,您可以在计算差值之前对向量进行排序,因此您将最大限度地减少所需的比较。

// this will change the original vector
dif_t min_diff_sorted( vector<int> &x ) {
    // erase the reference symbol  ^ if you want to sort a copy of the vector 
    dif_t min;
    min.dif = std::numeric_limits<int>::max();
    // usually sorting algorithms have N*logN complexity 
    std::sort( x.begin(), x.end() );
    // now that the vector is sorted we can compare the adiacent elements only.
    // This time I'll use two iterators to access the elements of the vector
    // ix will iter from the beginning of the vector to the last - 1 element
    // jx points to the element adjacent (+1) to ix
    for ( auto ix = x.begin(), jx = ix + 1;
            jx != x.end();      // stop condition
            ix = jx, jx++ ) {
        // the inner part doesn't change, it's only executed N-1 times 
        // instead of N*(N-1)/2                 
        int dif = abs( *ix - *jx );
        if ( dif > min.dif ) continue;
        if ( dif < min.dif ) {
            min.dif = dif;
            min.pairs.clear();
        }
        min.pairs.push_back(std::make_pair(*ix, *jx));
    }
    return min;
}

您可以在开始时将 mindiff 计算为 abs(arr1[0]-arr1[1]),然后在循环中继续计算它:

 // check whether array size is >=2 or not
    mindiff = abs(arr1[0]-arr1[1]);
    for ( x=0;x<size1;x++ )
    {
        for ( y=0;y<size1;y++ )
        {
           // do not calculate the difference of same number
            if(x!=y){
                diff = abs(arr1[x] - arr1[y]);
                if (diff<=mindiff)
                {
                    mindiff = diff;
                    number1 = arr1[y];
                    number2 = arr1[x];
                    cout<<number1<< ","<<number2<<endl;
                }
           }
        }
      }   
 cout<<"nthe elements amongst which the minimum difference was given are "<<number1<<" & "<<number2<<endl;
cout<<"the difference between them is "<<abs(mindiff)<<endl;

从 Beta 那里得到建议,并查看我发现与我的代码观点一致的唯一答案,我想出了下面对我自己的代码进行以下微小但关键的编辑。变化不大,但是非常重要的和本质的变化。PFB 该代码表明我有一个逻辑错误,即在退出最内层循环以进行下一次迭代以比较绝对差值之前,我没有在变量中临时加载差值。

#include <iostream>                             //input output stream   
#include <cstdlib>
//#include <vector>         not used            //to enable usage and implementation of vectors
#include "math.h"                               //to be able to do complex math functions if any
//#include <algorithm>      not used            //to be able to use max_element() and distance() functions on iterator.

using namespace std;
int main()
{
/*
first different variables for loop counters and 
size of array is taken in advanced instead of calculating during the program to reduce program time
*/
    int x=0,y=0,number1 = 0,number2 = 0,size1=0,mindiff = 0;
    int index = 0, count = 0, diff = 0;
    cout<<"enter the size of array you want nn";
    cin>>size1;
    int arr1[size1];
    cout<<"nn please enter elements of array nn";
    for (int i =0;i<size1;i++)
    {
        cin>>arr1[i];
    }
    for ( x=0;x<size1;x++ )
    {
        for ( y=0;y<size1;y++ )
        {
        if (x!=y)
/*
now load the difference in a variable named diff
and use a comparisional conditional statement to select
value of minimum difference
*/
            {
            diff = abs(arr1[x] - arr1[y]);
                if(count == 0)
                {
                    mindiff = diff;
                }
            else
                {
                    if (diff<mindiff)
                    {
                    cout<<diff<<" minimum difference "<<"n";
                    mindiff = diff;
                    //index = x+1;
                    number1 = arr1[x];
                    number2 = arr1[y];
                    }
                }
            count++;
            }
        }
    }

cout<<"nthe elements amongst which the minimum difference was given are "<<number1<<" & "<<number2<<endl;
cout<<"the difference between them is "<<abs(mindiff)<<endl;
cout<<endl<<endl;
system("pause");
return 0;
}

这让我意识到编码的观点确实适用于这种情况。当然,它可能很慢且效率低下,但这是一个结果。感谢所有人的时间。