1

I have a data file in which first column varies from -180 to +180 with a width of 5, while the second column is some corresponding value. i need to find minima from second column for one corresponding value of first say -180,print that,then subsequently find minima for -175 from second column print that and so...I have code for finding minima when i have only one column. How do I include this loop

#include<iostream>
#include<fstream>
#include<string>

using namespace std;

int main()
{
    ifstream myfile("ma3.txt");
    if(myfile.is_open())
    {       
      int arrSize=0.0;
      double arr[2000];
      double min=0;

      while(true)
      {
         double x,y;
         myfile>>x;
         if(myfile.eof()) break;
         arr[arrSize++]=x;        
      }
      //for(int i=0; i<arrSize; ++i)
      //   cout<<arr[i]<<"";
      //cout<<endl;

      min=arr[0];
      for(int i=0;i<arrSize;i++)
      {
         {          
             if(arr[i]<min)
             {
                min=arr[i];
             }
         }
      }

      cout<<"Smallest element:";
      cout<<min;
      cout<<endl;
    }
    else
    {
       cout<<"Unable to open file";
    }

    return 0;
} 

The input data:

-180 431.845 
-180 434.337 
-180 436.819 
-180 439.289 
-180 469.936 
-180 472.152 
-180 474.343 
-180 476.509 
-180 478.649 
-180 480.761 
-180 482.846 
-180 484.902 
-180 486.929 
-180 488.926
-175 387.566 
-175 384.891 
-175 382.216 
-175 379.541 
-175 376.868 
-175 374.197 
-175 371.53 
-175 368.867 
-175 366.209 
-175 363.557 
-175 360.912 
-175 358.275 
-175 355.648 
-175 353.03 
-175 350.422 
-175 347.826 
-175 345.243 
-175 342.673 
-175 340.117 
-175 337.576 
-175 335.05 
-175 332.541 
-175 330.05 
-175 327.576
Thomas Sablik
  • 16,127
  • 7
  • 34
  • 62
  • Can you provide an example of the input? – Marius Bancila Apr 05 '18 at 07:05
  • Are you allowed to use other containers like maps and vectors? – Thomas Sablik Apr 05 '18 at 07:05
  • How do i attach the data file. The input is like -180 431.845 -180 434.337 -180 436.819 -180 439.289 -180 469.936 -180 472.152 -180 474.343 -180 476.509 -180 478.649 -180 480.761 -180 482.846 -180 484.902 -180 486.929 -180 488.926-175 387.566 -175 384.891 -175 382.216 -175 379.541 -175 376.868 -175 374.197 -175 371.53 -175 368.867 -175 366.209 -175 363.557 -175 360.912 -175 358.275 -175 355.648 -175 353.03 -175 350.422 -175 347.826 -175 345.243 -175 342.673 -175 340.117 -175 337.576 -175 335.05 -175 332.541 -175 330.05 -175 327.576 – Masoom Singh Apr 05 '18 at 07:07
  • @ThomasSablik It actually is a vector I just named it array for convenience. – Masoom Singh Apr 05 '18 at 07:11
  • @MasoomSingh No, you are using arrays, not vectors. To use containers you need the corresponding header file, e.g. `#include ` or `#include ` – Thomas Sablik Apr 05 '18 at 07:19
  • @moooeeeep I went through the string but I didnt get what you are suggesting.How do I impliment that here? – Masoom Singh Apr 05 '18 at 07:23
  • @ThomasSablik okay I agree but I thought you were talking about data format. – Masoom Singh Apr 05 '18 at 07:23
  • @ThomasSablik thanks for the edit. – Masoom Singh Apr 05 '18 at 07:28
  • Are the x values always grouped together and ascending? – acraig5075 Apr 05 '18 at 07:49
  • @acraig5075 yes,for every one value of column 1 there are about 720 values in column 2 from which I need to find minima. About ascending..well its a loop from -180 to +180. – Masoom Singh Apr 05 '18 at 07:55

2 Answers2

2

Use an associative container to track multiple minima. For example an ordered std::map<int, double> seems convenient for this task:

The general structure of the solution could look like this:

#include <iostream>
#include <map>
int main() {
    std::map<int, double> mins;
    int x1;
    double x2;
    // TODO: read from file instead
    // TODO: read lines using `std::getline()` 
    //       and parse values using `std::stringstream` instead
    while (std::cin >> x1 >> x2) {
        // check if x1 is already being tracked
        if (mins.find(x1) != mins.end()) {
            // unknown key: just insert current value
            mins[x1] = x2;
        }
        else {
            // TODO: update value as needed
        }
    }
    // TODO: print key-value pairs in map
}

For reference:

moooeeeep
  • 31,622
  • 22
  • 98
  • 187
  • could you please explain what you are doing in the if loop? – Masoom Singh Apr 05 '18 at 07:40
  • @MasoomSingh The container `mins` is initially empty. Because you need to do another thing depending on whether you already know a key or not, you need the conditional (`find` checks if the key is already known). Then you either insert the current value or update the minimum value. – moooeeeep Apr 05 '18 at 07:45
  • I am sorry but I am not aware of term 'key' that you mentioned. Is there any other way of doing this? Else I would have to first understand this :-( – Masoom Singh Apr 05 '18 at 07:51
  • @MasoomSingh This is terminology from [associative data structures](https://en.wikipedia.org/wiki/Associative_arrays) (a.k.a. _key-value store_). In your case, the _key_ is the first column value, the _value_ is the second column value. You should really try to understand this, because it is essential for what happens here. – moooeeeep Apr 05 '18 at 07:55
  • so what should be the condition in else? – Masoom Singh Apr 05 '18 at 08:02
  • In the body comes a conditional assignment to `mins[x1]`. Just set it to the smaller value of `x2` and `mins[x1]`. – moooeeeep Apr 05 '18 at 08:05
  • I am sorry but the concept is totally new for me. Thanks though. – Masoom Singh Apr 05 '18 at 08:13
1

This can also be done simply and sequentially while reading the data, and without storing it in any container. Because the values of x are grouped together just print out the lowest value when a change occurs in the first column. Something like this (untested):

bool first = true;
int x = 0;
double y = 0;
double minY = 0;
int prevX = 0;


while (myfile >> x >> y)
{
    if (x == prevX)
    {
        if (y < minY)
            minY = y;
    }
    else
    {
        if (!first)
            cout << prevX << " smallest element: " << minY << "\n";

        minY = y;
        prevX = x;
        first = false;
    }
}

if (!first)
    cout << prevX << " smallest element: " << minY << "\n";
acraig5075
  • 10,588
  • 3
  • 31
  • 50
  • 1
    It completely worked as I wanted and I understood even the numeric limits concept. Thanks a lot. You saved my day. – Masoom Singh Apr 05 '18 at 08:15