วิธีแฮชสตริงใน python ให้ตรงกันภายใน 1 ตัวอักษร?

ฉันได้อ่านเกี่ยวกับการแฮช LSH แล้วและฉันสงสัยว่าอะไรคือการใช้งานที่ดีที่สุดในการจับคู่สตริงภายใน 1 อักขระ

test = {'dog':1, 'cat': 2, 'eagle': 3} 

test['dog']
>> 1

ฉันอยากจะส่งคืน 1 ด้วยถ้าฉันค้นหา test['dogs'] หรือ test['dogg'] ฉันรู้ว่ามันจะคืนค่า 1 เช่นกันหากฉันต้องค้นหา "log" หรือ "cog" แต่ฉันสามารถเขียนวิธีการเพื่อแยกผลลัพธ์เหล่านั้นได้

ฉันจะเพิ่มเติมวิธีนี้ให้กับสตริงทั่วไปเพื่อส่งคืนการจับคู่ภายในอักขระ X ได้อย่างไร

string1 = "brown dogs"
string2 = "brown doggie"

สมมติว่ามีเพียง string1 เท่านั้นที่ถูกเก็บไว้ในพจนานุกรมของฉัน การค้นหา string2 จะส่งกลับ string1

ขอบคุณ


person nyc0202034    schedule 13.02.2013    source แหล่งที่มา
comment
ในระยะสั้นคุณไม่สามารถ ตารางแฮชเป็นเครื่องมือที่ผิดสำหรับสิ่งนี้   -  person    schedule 13.02.2013
comment
นั่นจะไม่ได้ผล เพราะสิ่งที่คุณกำลังอธิบายไม่ใช่ความสัมพันธ์ที่เท่าเทียมกัน   -  person SLaks    schedule 13.02.2013
comment
คุณกำลังพยายามรับค่าของคีย์ที่คล้ายกับคีย์ที่กำหนดมากที่สุดหรือไม่? ถูกต้องไหม?   -  person freakish    schedule 13.02.2013
comment
@SLaks ฉันไม่รู้ว่าความสัมพันธ์ที่เท่าเทียมกันเกี่ยวข้องกับเรื่องนั้นอย่างไร   -  person freakish    schedule 13.02.2013
comment
@freakish: การเปรียบเทียบคีย์ (ฟังก์ชันแฮช) สำหรับตารางแฮชจะต้องเป็นความสัมพันธ์ที่เท่าเทียมกัน   -  person SLaks    schedule 13.02.2013
comment
@SLaks ตกลง แต่การเปรียบเทียบโดยความคล้ายคลึง คือ ความสัมพันธ์ที่เท่าเทียมกัน ( ขึ้นอยู่กับคำจำกัดความของ ความคล้ายคลึง แม้ว่า ) ฉันเดาว่าเราต้องการข้อมูลเพิ่มเติมสำหรับคำถามนั้น   -  person freakish    schedule 13.02.2013
comment
ฉันแน่ใจว่าคุณสามารถใช้คลาสการแมปแบบ LSH ใน Python ได้ มันเป็นภาษาสำหรับวัตถุประสงค์ทั่วไป หากคุณมีปัญหาในการทำให้มันใช้งานได้ ให้กลับมาพร้อมกับปัญหาที่เป็นรูปธรรม   -  person martineau    schedule 13.02.2013
comment
@freakish: ไม่มันไม่ใช่ abc == abd และ abz == xbz แต่ abc != xbz   -  person SLaks    schedule 13.02.2013


คำตอบ (3)


คุณสามารถกำหนดความคล้ายคลึงกันระหว่าง 2 สตริงด้วยความยาวของจุดเริ่มต้นที่ทั้งสองมีร่วมกัน (เช่น 3 สำหรับ doga และ dogs เป็นต้น) นี่เป็นเรื่องง่ายๆ แต่อาจเหมาะกับความต้องการของคุณ

ด้วยสมมติฐานนี้ คุณสามารถกำหนดสิ่งนี้:

>>> test = {'dog':1, 'cat': 2, 'eagle': 3}
>>> def same_start(s1, s2):
    ret = 0
    for i in range(min(len(s1), len(s2))):
        if s1[i] != s2[i]:
            break
        ret += 1
    return ret

>>> def closest_match(s):
    return max(((k, v, same_start(k, s)) for k, v in test.iteritems()), key=lambda x: x[2])[1]

>>> closest_match('dogs')  # matches dog
1
>>> closest_match('cogs')  # matches cat
2
>>> closest_match('eaogs') # matches eagle
3
>>> 
person Emmanuel    schedule 13.02.2013

บางทีคุณอาจลองใช้ฟังก์ชัน Soundex เป็นคีย์พจนานุกรมของคุณ

person LAK    schedule 13.02.2013

เนื่องจากความสัมพันธ์ของคุณไม่ใช่ 1:1 คุณอาจกำหนดประเภท dict ของคุณเองด้วย __getitem__ ที่นิยามใหม่ ซึ่งอาจส่งคืนรายการของรายการที่เป็นไปได้ นี่คือสิ่งที่ฉันหมายถึง:

class MyDict(dict):
  def __getitem__(self, key):
    l = []
    for k, v in self.items():
      if key.startswith(k): # or some other comparation method
        l.append(v)
    return l

นี่เป็นเพียงแนวคิด อาจควรกำหนดวิธีการเขียนตามคำบอกอื่น ๆ ด้วยเช่นกันเพื่อหลีกเลี่ยงข้อผิดพลาดหรือการวนซ้ำไม่สิ้นสุดที่อาจเกิดขึ้นได้ นอกจากนี้ @Emmanuel's answer อาจมีประโยชน์มากที่นี่หากคุณต้องการส่งคืนเพียงรายการเดียวแทนที่จะเป็นรายการ และด้วยวิธีนี้ จะได้ไม่ต้องกำหนดทุกอย่างใหม่

person tomcaa    schedule 13.02.2013