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]になることに気付きました。したがって、今では完全に失われています!)

1つのポイントを参照ポイントとして保存して、残りのデータと比較し、小さいポイントと比較するたびに小さい値に変更するにはどうすればよいですか?

更新: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

HTH

于 2012-08-13T14:06:08.673 に答える
1

別の注意点として、入力ループ制御は正しくありません。

while(!in.eof()) {

eof()は、読み取りが失敗するまでトリガーされません。実際には、これは、入力ループが1回余分に実行され、最後に意味のない値を取得することを意味します。

正しいテストは

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

いずれかのエクストラクタが失敗した場合(in入力の最後にあることが望ましいため、whileループは終了します。

于 2012-08-13T14:53:31.220 に答える
0

ここでの問題は、最小のものと決して比較しないことです。以前の反復を考慮せずに、ref1 と ref2 の間の最小値を割り当てます。また、ref1 は常にデータの最初の値であるため、最後の値が最初の値よりも大きい場合、最小値が常に最後になります。ループをジェイソンが投稿したものに変更すると、問題が解決します。

于 2012-08-13T13:58:47.203 に答える