2

I have a two .txt files. t1.txt contains two columns with coordinates. t2.txt contains three columns (coordinates and some value). I want to extract a third column from t2.txt for coordinates from t1.txt. Right now my code is looking for the same number in both .txt files. Unfortunately, coordinates are not the same, and I have to find the closest coordinates. How to change my code? I tried to find some information, but I am a very beginner and nothing helps me.

My code:

#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

double** alokujPamiec(int,int);
void  deleteAlokujPamiec(double**&);

int main()
{

 int liczba=0;
 fstream plik1("t1.txt",ios::out | ios::in);  // 2 columns
 fstream plik2("t2.txt", ios::out | ios::in); //3 columns
 ofstream plik5("wynik.txt");
  plik5 << setprecision(5) << fixed; // precision
 int p1=0,p2=0;
 char buff[255];
 if(plik1.is_open()){
    while(plik1.getline(buff,255)){
      p1++; // number of lines
    }
}else cout <<"Error in opening file 1"<<endl;

if(plik2.is_open()){
  while(plik2.getline(buff,255)){
   p2++; 
  }
}else cout <<"Error in opening file 2"<<endl;

cout << "lines in t1.txt" << "\t" <<p1<<endl;
cout << "lines in t2.txt" << "\t" <<p2<<endl;

plik1.close();
plik2.close();

fstream plik3("t1.txt",ios::out | ios::in);  
fstream plik4("t2.txt", ios::out | ios::in);

double** dane1 = alokujPamiec(p1, 2);
double** dane2 = alokujPamiec(p2, 3);
int h=1;
cout <<"Loading data...."<<endl;

if(plik4.is_open()){
for(int i=0;i<p2;i++)
{
    for(int j=0;j<3;j++){
            plik4>>dane2[i][j];
            }   
    }
}else cout << "Error 4"<<endl;

if(plik3.is_open()){ 
    for(int i=0;i<p1;i++)
{
    for(int j=0;j<2;j++){
            plik3>>dane1[i][j];
            }
    }
 }else cout << "Error 3"<<endl; 

 cout <<"Comparison and writing... "<<endl;      

 for(int i=0;i<p1;i++)
   {
      for(int j=0;j<p2;j++)
            {
               if(dane1[i][0]==dane2[j][0] && dane1[i][1]==dane2[j][1])
                   {
                  plik5<<dane1[i][0]<<"\t"<<dane1[j][1]<<"\t"<<dane2[j][0]<<"\t"<<dane2[i][1]<<"\t"<<dane2[i][2]<<endl;  
                  liczba++;                        
                  }
            } 
    }

    cout <<"Number of found objects"<<"\t"<<liczba<<endl;

    plik3.close();
    plik4.close();
    plik5.close();

    deleteAlokujPamiec(dane1);
    deleteAlokujPamiec(dane2);
    getchar();
    return 0;
    }

    double ** alokujPamiec(int iloscWierszy, int iloscKolumn)
    {
     double** tab2d = new double*[iloscWierszy];
      double*  dumm  = new double[iloscWierszy*iloscKolumn];

          for ( int i = 0; i < iloscWierszy; i++ )
             tab2d[i] = dumm + i*iloscKolumn;
       return tab2d;
      }

      void deleteAlokujPamiec(double**& tab2d) {
       delete [] tab2d[0];
       delete [] tab2d;
       tab2d = 0;
      }
raquela
  • 268
  • 2
  • 8

2 Answers2

4

The right approach for solving a complicated problem is to break it down. Divide it into several smaller problems, and solve each one individually. When you've solved them all, you have your final result.

Start by defining what "closest" coordinate means. The answer is, of course, the Pythagorean theorem. Given two coordinates, (x1, y1) and (x2, y2), the distance between them is sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)). Your existing code already uses doubles for coordinates, so this will work out quite well, just by plugging in this formula into your code, directly.

So that solves the problem of what "closest" means. The smaller the number, the smaller is the result of the expression. If the result is 0, both coordinates are the same. If you have one coordinate, then a pair of other coordinates, the closest one of the pair is the one whose pythagorean distance is the numerically smaller one.

Next problem: you have one set of coordinates, (x1, y1). Now you have a entire list of other coordinates, that you loaded from another file. How do you find the coordinate from the other file that's closest to (x1, y1)? This now becomes a trivial, simple programming task with a classical solution: loop over each coordinate from the other file. Each coordinate from the other file becomes your (x2, y2). Plug it into the Pythagoren theorem to get the distance, and have your loop keep track of the closest coordinate, to date. The classical solution is to compute the distance to the first coordinate from the other file in advance. Get its distance, then loop over the remaining coordinates, calculating each one's distance, and saving it, and the coordinate, if the calculating distance is smaller, and replace the saved coordinate with this one. Trivial.

At the end of the loop you're left with the coordinate that was closest to (x1, y1). This is now a simple, trivial programming task to implement.

The final step for your solution is to simply do this for every coordinate from the first file. Again, this is now a trivial programming task of simply looping over each coordinate from the first file, and executing the above steps for each one of them; thusly finding each coordinate's closest coordinate from the other file.

Mission accomplished.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • You should note that the Pythagoras theorem is only valid because we assume the coordinate are very close so a flat surface is a good enough approximation to a sphere. Also, since I assume that the coordinates are in fact the same with a small error, then just comparing each value with a reasonable epsilon should be good enough. – Liran Funaro May 10 '17 at 12:06
  • This is basically what I would have done. Depending on the output needed, I would either use a threshold (epsilon) to find all coordinates in `t2.txt` that were within the 'epsilon' distance of `t1.txt` or, (as @Sam) has pointed out, keep track of the closest point and kick out just the one. – James Poag May 10 '17 at 12:07
  • Okay, thank you for your suggestions! The errors are small, so I think I will try to use both ways. – raquela May 10 '17 at 12:20
0

Don't rely on comparing doubles with an equal sign: What is the most effective way for float and double comparison?

Also, if(dane1[i][0]==dane2[j][0] & dane1[i][1]==dane2[j][1]) should have && and not &

Community
  • 1
  • 1
James Poag
  • 2,320
  • 1
  • 13
  • 20