Android Question Find closest match between 2 numbers ?

G-ShadoW

Active Member
Licensed User
Like in title said, how to find closest match between 2 numbers
Expert help needed

I have a txt file that contains lines like this...

B4X:
45.2722;18.847421239;023546;31052015;12;3
43.342171;17.45648532;123546;12051995;12;24
46.954171;16.154645;223546;31062022;11;6
43.132171;15.8474;023546;26111976;14;3
and I have 2 textboxes with ( texbox -> Edittext )

first textbox look's like this
45.295768


second texbox
18.8512348


to separate strings in text lines I use " ; "

so basicly first line in this example ist closest match, but how I can get this line of text file ?
and when I find closest match, I need to select that whole line and insert it in texbox 3 ?

the lenght of first and second number in txt file is not smaller than xx.xxxx but it can be bigger xx.xxxxxxxx
 

thedesolatesoul

Expert
Licensed User
Split>Cast>Compare

closestLine = 0
Loop over all the lines
lineparse = Regex.Split(";",linetext)
Dim uBound as Float = lineparse(0)
Dim lBound as Float = lineparse(1)
Dim dist_from_ubound = txt_from_1 - uBound
Dim dist_from_lbound = txt_from_2 - uBound
'Apply algorithm to determine whatever is closest.
Dim closestLine = getClosestLine(currentLineNum, dist_from_ubound, dist_from_lbound)

...
something like that
 

G-ShadoW

Active Member
Licensed User
I know how to find exact "match" in first line with first number but to compare 2 strings for line and find the closest one, I dont have idea...

B4X:
Sub btnChk_Click
If File.Exists(File.DirRootExternal, "log.txt") = True Then
        Dim reader As TextReader       
    reader.Initialize(File.OpenInput(FilePath,FileName))
    Dim line As String
    line = reader.ReadLine
    Do While line <> Null
      If line.Contains("=")=False Then  'eliminate the lines that have the =signs for esthetics
          MyList.add(line)
      End If
          line = reader.ReadLine
    Loop               
    reader.Close  
 
End If
For i=0 To MyList.Size-1
      Dim MyLine As String =MyList.Get(i)
      If MyLine.SubString2(0, MyLine.IndexOf(";")) =txt1.text Then
        Dim arrLine() As String = Regex.Split(";",MyLine)
        txt2.text= arrLine(1)
        txt3.text= arrLine(2)
        txt4.text= arrLine(3)
        txt5.text= arrLine(4)
        Exit
      End If
    Next
End Sub
 

thedesolatesoul

Expert
Licensed User
First take your points into float
B4X:
Dim p1_x as Float = arrLine1(0)
Dim p1_y as Float = arrLine1(1)

Dim p2_x as Float = EditText1.Text
Dim p2_y as Float = EditText2.Text
Now calculate the distance:
B4X:
Dim distanceNew as Float = (p1_x - p2_x)^2 + (p1_y - p2_y)^2
Now if you hold this new distance and compare it with the previous one in the loop, the smallest distance is the one that is closest.
 

RandomCoder

Well-Known Member
Licensed User
Lets see what you have attempted and I'll help. A small sample with the data file and your attempt(s) will be fine.

There's a wise old saying...
"Give a man a fish and you'll feed him for a day; teach a man to fish and you feed him for a life time".

Being given the answer isn't always the solution, but I'll gladly help. The problem really isn't that difficult. TDS has already given a method to calculate the distance, store this as the shortest distance then calculate the next distance and check if smaller. If it's smaller then overwrite the shortest distance with this new value (if needed also store the index/line number for later use) and continue looping through. After looping through all the values you will have obtained which was the shortest distance.
 

RandomCoder

Well-Known Member
Licensed User
Hi @G-ShadoW I've looked at the attachment and it errors immediately on entering the loop. This is because the program is looking for a ":" (colon) to separate the values but the text file uses ";" (semi-colon's) and so the code is broken at this point. My intention is to help you along the way to finding the solution and for you to hopefully get a better understanding of the way your program works.

As you are new to programming, you may not be aware of the powerful debugging features that B4A has? Please see the screenshot below...



You access this by selecting either of the Debug options in the same drop down list used to compile the App. Break points can be placed almost anywhere in your code by clicking on the left-hand edge of the screen. The "F5" key will continue running the program after stopping at a break point and "F8" will step the program one line at a time, I find this especially useful. I also add lots of Log() statements (see blue highlighted lines) whilst debugging to see exactly what's happening in the program, these statements appear in the right-hand window. As you can hopefully see from the screenshot, there's a wealth of information. I can see all the contents of the list "MyList" and the line that is extracted along with the actual value that the program will be comparing with the text value.

Please don't take these comments as condescending in any way, I am purely trying to help you in a way that will allow you to continue working through the problem and the many problems that will undoubtedly arise in the future, indeed there is something new that I struggle with most days ;). If all that you are after is the solution then I am the wrong person to be helping and please let me know.
 

G-ShadoW

Active Member
Licensed User
It was my mistake, coz I didnt check the zipped source, my full source is more than 2mb long, that's why I didnt send it.
And some of the things you wrote above I didnt know, so I'm glad that you have explained some things which I didnt know and I'm appreciate for that.
 

RandomCoder

Well-Known Member
Licensed User
Hi @Peter Simpson I think that what @G-ShadoW is wanting, is to enter a value in the top TextBox and then locate which line is closest to this value in the list. This will require iterating through the entire list to check the distance between the values, updating which has the closest value. At least that's my understanding of what's required. I was kind of hoping to help G-Shadow find the solution as it's reasonably straight forward, he'll then have a better understanding how to solve similar problems.
@G-ShadoW how I would tackle the problem...
  • Create a variable to store the shortest distance and one to store the index of the list at which this item was found.
  • Iterate through the entire list calculating the distance between the entered text and the first value(s) on each line...
    • If the value is less than the shortest distance, update its value and store the list index.
  • When all items in the list have been checked, get the index of the closest value and read in this line.
This is obviously dependant on if I have correctly understood what is required.
 

G-ShadoW

Active Member
Licensed User
Hi @Peter Simpson I think that what @G-ShadoW is wanting, is to enter a value in the top TextBox and then locate which line is closest to this value in the list. This will require iterating through the entire list to check the distance between the values, updating which has the closest value. At least that's my understanding of what's required. I was kind of hoping to help G-Shadow find the solution as it's reasonably straight forward, he'll then have a better understanding how to solve similar problems.
@G-ShadoW how I would tackle the problem...
  • Create a variable to store the shortest distance and one to store the index of the list at which this item was found.
  • Iterate through the entire list calculating the distance between the entered text and the first value(s) on each line...
    • If the value is less than the shortest distance, update its value and store the list index.
  • When all items in the list have been checked, get the index of the closest value and read in this line.
This is obviously dependant on if I have correctly understood what is required.
that's correct
 

RandomCoder

Well-Known Member
Licensed User
PS. Don't feel that you have to struggle, if your having problems with any part I'll gladly offer advice and I'm sure that you'll come to the solution in no time!
 
Top