Map partial key match method

Just starting out? Need help? Post your questions and find answers here.
User avatar
ljgww
User
User
Posts: 14
Joined: Fri Nov 02, 2007 6:37 pm
Location: Canada

Map partial key match method

Post by ljgww »

Consider this code

Code: Select all

NewMap txt.s()

AddMapElement(txt(),"abcd")
txt()="abcd"
AddMapElement(txt(),"bcde")
txt()="bcde"
AddMapElement(txt(),"cdef")
txt()="cdef"

; finding exact key
If FindMapElement(txt(),"cdef")
  Debug "cdef found"
  Debug MapKey(txt())
Else
  Debug "cdef not found"
  Debug MapKey(txt())
EndIf

; finding partial key
If FindMapElement(txt(),"bc")
  Debug "BCDE found"
  Debug MapKey(txt())
Else
  Debug "BCDE not found"
  Debug MapKey(txt())
EndIf

; finding exact key
If FindMapElement(txt(),"abcd")
  Debug "abcd found"
  Debug MapKey(txt())
Else
  Debug "abcd not found"
  Debug MapKey(txt())
EndIf
output

Code: Select all

cdef found
cdef
BCDE not found
cdef
abcd found
abcd
The target here is to provide partial key and find closest element in the map where key partially matches.

Is there any technique that allows finding closest map element by providing incomplete/partial key?

meaning, any faster technique apart from sequentially searching thru the list of map keys

As example shows, only exact key matches are taken in account and current element pointer shows last successful find (by exact key match).
User avatar
NicTheQuick
Addict
Addict
Posts: 1227
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Map partial key match method

Post by NicTheQuick »

A normal hash based map like Purebasic uses it can not do this.
You have to implement an algorithm that can do this or have to use external librarys that are doing this for you. Maybe also a memory based SQLite approach could help you but this seems a bit overkill to me and I am also not familiar with SQLite and if the LIKE command works with it.

Wildcard searching can potentially give you more than one result. So 'FindMapElement()' would select more than one element which is stricly spoken not really possible.
I only know about Suffix trees and the Knuth-Morris-Pratt algorithm but I am not sure if this can be adopted to a list of strings.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
User avatar
ljgww
User
User
Posts: 14
Joined: Fri Nov 02, 2007 6:37 pm
Location: Canada

Re: Map partial key match method

Post by ljgww »

Ty NickTheQuick for prompt answer.

After I posted a question I asked myself is this thing really available in some other languages like Python, JavaScript or C# who have "dictionary" like structures. And it seems to me that this is somewhat of gray area in other languages too. So far of a few languages I queried only Perl has regex on hash key, the rest like PureBasic will need an function (algorithm) to do this.

The gray area extends not that one can match more than one element (current PB Map system allows one reference to a element - current element so it is understandable that we cannot return multiple results) it actually asks for a way how to define key matching.
For example: are one is searching for a key from the left side or from the middle of the key, or some other 'like' mechanism or as in Perl provide a regex as matching method.

Hence this is not trivial task to achieve. Thank you for brainstorming.
ebs
Enthusiast
Enthusiast
Posts: 530
Joined: Fri Apr 25, 2003 11:08 pm

Re: Map partial key match method

Post by ebs »

An in-memory SQLite database should work.
A query like "SELECT * FROM [TABLE] WHERE KEY LIKE 'BC%' would return all elements with keys starting with 'BC'.
User avatar
ljgww
User
User
Posts: 14
Joined: Fri Nov 02, 2007 6:37 pm
Location: Canada

Re: Map partial key match method

Post by ljgww »

ebs wrote:An in-memory SQLite database should work.
A query like "SELECT * FROM [TABLE] WHERE KEY LIKE 'BC%' would return all elements with keys starting with 'BC'.
While I am pondering how not to use SQL way...

Just a question here: LIKE 'BC%' would be I guess 'left match'. (would need to go into SqlLite and see exactly what LIKE does)

At any rate, thank you too for contributing to the possible solution.

Update: All seems to be explained here: https://www.sqlitetutorial.net/sqlite-like/
Last edited by ljgww on Mon May 18, 2020 2:43 pm, edited 1 time in total.
Marc56us
Addict
Addict
Posts: 1479
Joined: Sat Feb 08, 2014 3:26 pm

Re: Map partial key match method

Post by Marc56us »

Is there any technique that allows finding closest map element by providing incomplete/partial key?
meaning, any faster technique apart from sequentially searching thru the list of map keys
The sequential search is not necessarily very slow and ForEach and FindString in PB allows to browse a Map or List very quickly and simply.

Code: Select all

NewMap txt.s()

AddMapElement(txt(),"abcd") : txt()="abcd"
AddMapElement(txt(),"bcde") : txt()="bcde"
AddMapElement(txt(),"cdef") : txt()="cdef"

ForEach txt()
    If FindString(txt(), "bc")
        Debug "Found in '" + txt() + "'"
    EndIf
Next

Code: Select all

Found in 'abcd'
Found in 'bcde'
:wink:
User avatar
ljgww
User
User
Posts: 14
Joined: Fri Nov 02, 2007 6:37 pm
Location: Canada

Re: Map partial key match method

Post by ljgww »

Marc56us wrote:
Is there any technique that allows finding closest map element by providing incomplete/partial key?
meaning, any faster technique apart from sequentially searching thru the list of map keys
The sequential search is not necessarily very slow and ForEach and FindString in PB allows to browse a Map or List very quickly and simply.

Code: Select all

NewMap txt.s()

AddMapElement(txt(),"abcd") : txt()="abcd"
AddMapElement(txt(),"bcde") : txt()="bcde"
AddMapElement(txt(),"cdef") : txt()="cdef"

ForEach txt()
    If FindString(txt(), "bc")
        Debug "Found in '" + txt() + "'"
    EndIf
Next

Code: Select all

Found in 'abcd'
Found in 'bcde'
:wink:
He he. Yes something along this example shall be OK. This would be 'anywhere in the key match'.

I was looking for the 'left match' but nevertheless this is fine idea (also gives some surprising but logical results). It is interesting example how our thinking and computer actions may differ.

For the left match I would likely go with iteration + break out from the loop to make it O(log(n)) on average, which would be OK even for a bit larger maps (essentially I am not expecting of working with extremely large sets of data so memory iteration would be fast enough). I just need beginning of the block as I assume (which may be wrong assumption) that Map Keys are sorted.

Brings to the next question are Map keys inherently sorted?, or I need to iterate whole set (making it O(n) effectively)
User avatar
ljgww
User
User
Posts: 14
Joined: Fri Nov 02, 2007 6:37 pm
Location: Canada

Re: Map partial key match method

Post by ljgww »

Brings to the next question are Map keys inherently sorted?, or I need to iterate whole set (making it O(n) effectively)
Seems that they are not. They seem to keep sequence of how they were added. Gosh.
Marc56us
Addict
Addict
Posts: 1479
Joined: Sat Feb 08, 2014 3:26 pm

Re: Map partial key match method

Post by Marc56us »

If need left match, this is faster

Code: Select all

NewMap txt.s()

AddMapElement(txt(),"abcd") : txt()="abcd"
AddMapElement(txt(),"bcde") : txt()="bcde"
AddMapElement(txt(),"cdef") : txt()="cdef"

Search$ = "bc"
Nb_char = Len(Search$)

ForEach txt()
    If Left(txt(), Nb_char) = Search$
        Debug "Found in '" + txt() + "'"
    EndIf
Next
As far as I know, the keys aren't sorted.
User avatar
ljgww
User
User
Posts: 14
Joined: Fri Nov 02, 2007 6:37 pm
Location: Canada

Re: Map partial key match method

Post by ljgww »

Cool.
Thank you Marc56us
User avatar
idle
Always Here
Always Here
Posts: 5098
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Map partial key match method

Post by idle »

you want a trie instead of a map.

viewtopic.php?f=12&t=74786
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
ljgww
User
User
Posts: 14
Joined: Fri Nov 02, 2007 6:37 pm
Location: Canada

Re: Map partial key match method

Post by ljgww »

idle wrote:you want a trie instead of a map.

viewtopic.php?f=12&t=74786
Thank you for this, Idle. Programming is endless amusement and this is one of best examples. It is also a discovery path - one starts a naive journey somewhere and the on the way steps on something, which, when researched deeper opens an whole area of similar issues and sometimes it grows larger to unexplored lands.

I would need to find some time to get deeper in this subject (and learn more). (Geo)Spatial trees is an area I know nothing about. At a glance - It's not likely solution for my problem (it is still a big question what is the nature of a problem I have) , but nevertheless it could be useful for someone else, who would use this thread to research alternatives to key finding means and ways. Sooner or later it turns out it is some kind of indexing problem. Then there is waging - is is worth making whole new paradigm to solve a simple problem, or problem is not simple and warrants making a library to solve it (and possibly related problems).

In fact, when I mentioned what I am looking for, a friend of mine said: I wrote my indexing system specifically to solve that problem you have encountered. So...

As it starts looking to me, there are many algorithmic approaches depending on specific need. Spatial tree is one of fine ideas. Time permitting I will check out your code too (takes a bit of a time to understand if one was blissfully ignorant like me).

Cheers!
User avatar
idle
Always Here
Always Here
Posts: 5098
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Map partial key match method

Post by idle »

what you've described is exactly what a prefix trie is for, otherwise you'd be looking at a DAG or something else that works.
Personally I think Tries are the the missing link, theoretically they're better than a hash table but they're hard to generalise, which is probably why you don't see them used as a standard data structure. If a Trie isn't quite what you need, perhaps you can describe the problem a bit more.
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
ljgww
User
User
Posts: 14
Joined: Fri Nov 02, 2007 6:37 pm
Location: Canada

Re: Map partial key match method

Post by ljgww »

idle wrote:what you've described is exactly what a prefix trie is for, otherwise you'd be looking at a DAG or something else that works.
Personally I think Tries are the the missing link, theoretically they're better than a hash table but they're hard to generalise, which is probably why you don't see them used as a standard data structure. If a Trie isn't quite what you need, perhaps you can describe the problem a bit more.
I am sure you're right (especially that I did not go deeper on this subject, hence I do not consider myself competent to argue this), but this is also balancing between using something large, complex and more efficient, or using something simple and maybe not that good but fairly OK given circumstances. It also goes to time to learn a new thing, and time one has to finish something. If whatever (occam razor) solution is not good enough given other circumstances, there is chance to improve on it later.

One thing I am trying also to understand Trie <> Tree. Is this trie a tree or it goes to trying? (English is not my first language so I may be missing something here)
User avatar
ljgww
User
User
Posts: 14
Joined: Fri Nov 02, 2007 6:37 pm
Location: Canada

Re: Map partial key match method

Post by ljgww »

Note this too (a lesson after trying to find some other bug in my code):

viewtopic.php?f=12&t=75388
Post Reply