stupidity
stupidity

Reputation: 437

Finding the smallest number in a set of Data

I have a set of Data in the following form:

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

My goal is to find the row which has the smallest value for the c column.

I did the following:

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;

} 

However, the output was the last point in the data. (As of typing this question, I realised that ref1 will always be the Array[0][2] as the new line is read. So now I'm totally lost!)

How to save one point as a reference point, such that it is compared to the rest of the data, and it changes to a smaller value each time it is compared to a smaller point?

UPDATE: I fixed this by taking ref1=Array[0][2]; out of the for loop.

Upvotes: 2

Views: 1165

Answers (4)

Pete Becker
Pete Becker

Reputation: 76498

On a different note, the input loop control is incorrect:

while(!in.eof()) {

eof() doesn't get triggered until a read has failed. In practice, this means that the input loop executes one extra time, and you get nonsense values the last time through.

The correct test is

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

If any of the extractors fails (hopefully because in is at the end of the input, the while loop will end.

Upvotes: 1

Jason
Jason

Reputation: 32538

To certify that you've found the smallest value in a set of values, change your for-loop to the following:

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];
}

Basically you start off by setting smallest_val to the largest possible value that it can possible have using std::numeric_limits<int>::max(). Now every value in the array will have to be at least as large as smallest_value or smaller (nothing can be larger). When you loop through the array, once you hit a value less than the value currently in smaller_value, you will properly re-assign the value in smaller_value to that new lower value. By starting off with the largest possible that can be represented by the int type, you avoid the problem you're encountering where your smallest values are relative to each other. Using mathematical induction, that type of method is unnecessary for what you're attempting to-do here.

Upvotes: 3

Umut Tabak
Umut Tabak

Reputation: 1942

You should set a reference as I do outside the loop and update the smallest, btw, do not mix floats with doubles however here is a sample code:

#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;

} 

With data file

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

Upvotes: 3

VoidStar
VoidStar

Reputation: 571

The problem here is that you never compare to your smallest. You assign the lowest value between ref1 and ref2 without considering the previous iterations. Also, ref1 is always the first value in your data so if the last value is bigger than the first, the smallest will always be the last. Changing the loop to what Jason posted will solve your problem.

Upvotes: 0

Related Questions