2

我有以下形式的一组数据:

a1 b1 c1 d1
a2 b2 c2 d2
...
an bn cn dn

我的目标是找到 c 列具有最小值的行。

我做了以下事情:

const int limit=100000;
float Array[limit][4];

int main() {

  double a, b, c, d, smallest, ref1, ref2;

  ifstream in("data.dat");

  int idx=-1, point;

  while(!in.eof()) {

    idx++;
    in >> a >> b >> c >> d;

    Array[idx][0]=a; Array[idx][1]=b; Array[idx][2]=c; Array[idx][3]=d;

} \\end of while

in.close();


   int count=idx;

   for(int i=1; i<count; i++) {

        ref1= Array[0][2];
        ref2 = Array[i][2];

        if(ref2 < ref1) {ref1 = ref2; point=i;}  //I thought this will save the smallest value 

         smallest = ref1; point= i;

} \\end for


cout << "point" << Array[point][0] << Array[point][1] << .. etc.

return 0;

} 

但是,输出是数据中的最后一个点。(在输入这个问题时,我意识到 ref1 在读取新行时将始终是 Array[0][2]。所以现在我完全迷路了!)

如何将一个点保存为参考点,以便将其与其余数据进行比较,并且每次与较小的点进行比较时,它都会更改为较小的值?

更新:我通过 ref1=Array[0][2]; 解决了这个问题 出for循环。

4

4 回答 4

3

要证明您已找到一组值中的最小值,请将您的 for 循环更改为以下内容:

int smallest_val = std::numeric_limits<int>::max();

for(int i=0; i < idx; i++) 
{
    if (Array[i][2] < smallest_val)
        smallest_val = Array[i][2];
}

基本上,您首先设置smallest_val为使用std::numeric_limits<int>::max(). 现在数组中的每个值都必须至少等于smallest_value或更小(没有什么可以更大)。当您遍历数组时,一旦您找到一个小于当前值的值smaller_value,您将正确地将值重新分配smaller_value给该新的较低值。通过从int类型可以表示的最大可能开始,您可以避免遇到最小值相互关联的问题。使用数学归纳法,这种类型的方法对于您在这里尝试做的事情是不必要的。

于 2012-08-13T13:55:30.987 回答
3

您应该像我在循环之外设置一个引用并更新最小的,顺便说一句,不要将浮点数与双精度数混合,但是这里是一个示例代码:

#include <iostream>
#include <fstream>

using namespace std;


const int limit=100000;
float Array[limit][4];

int main() {

  double a, b, c, d, smallest, ref1, ref2;

  ifstream in("data.dat");

  int idx=-1, point;

  while(!in.eof()) {

    idx++;
    in >> a >> b >> c >> d;

    Array[idx][0]=a;
    Array[idx][1]=b;
    Array[idx][2]=c;
    Array[idx][3]=d;
  } //end of while

  in.close();
  int i = 0;
  int count;
  smallest = Array[i][2];
  for( i=1; i<count; i++) {
    ref2 = Array[i][2];

    if(ref2 < smallest) {
      smallest = ref2;
      point=i;
    }
  }

  std::cout << "point" << Array[point][0] << " "
            << Array[point][1] << " "
            << Array[point][2] << " "
            << Array[point][3] << std::endl;

return 0;

} 

带数据文件

1 2 3 4
2 3 8 9
1 3 5 2
1 1 1 1
2 4 2 4
3 1 0 1

高温高压

于 2012-08-13T14:06:08.673 回答
1

另一方面,输入循环控制不正确:

while(!in.eof()) {

eof() 在读取失败之前不会被触发。在实践中,这意味着输入循环会额外执行一次,而您最后一次会得到无意义的值。

正确的测试是

while(in >> a >> b >> c >> d) {

如果任何提取器失败(希望因为in在输入的末尾,while 循环将结束。

于 2012-08-13T14:53:31.220 回答
0

这里的问题是您永远不会与最小的比较。您在 ref1 和 ref2 之间分配最小值,而不考虑以前的迭代。此外, ref1 始终是数据中的第一个值,因此如果最后一个值大于第一个值,则最小值始终是最后一个。将循环更改为 Jason 发布的内容将解决您的问题。

于 2012-08-13T13:58:47.203 回答