2011-09-07 42 views
8

Tôi đang cố gắng phát triển thuật toán python để kiểm tra xem chuỗi có thể là một từ viết tắt cho một từ khác hay không. Ví dụ:Kiểm tra xem chuỗi có phải là một cách viết tắt có thể cho tên

  • fck phù hợp với fc kopenhavn vì khớp với ký tự đầu tiên của từ. fhk sẽ không khớp.
  • fco không được khớp với fc kopenhavn vì không có ai sẽ khai báo FC Kopenhavn là FCO.
  • irl là kết quả phù hợp cho in real life.
  • ifk là kết quả phù hợp cho ifk goteborg.
  • aik là kết quả phù hợp cho allmanna idrottskluben.
  • aid phù hợp với allmanna idrottsklubben. Đây không phải là sự rút gọn tên nhóm thực sự, nhưng tôi đoán thật khó để loại trừ nó trừ khi bạn áp dụng kiến ​​thức cụ thể về tên miền về cách viết tắt tiếng Thụy Điển được hình thành.
  • manu là kết quả phù hợp cho manchester united.

Thật khó để mô tả các quy tắc chính xác của thuật toán, nhưng tôi hy vọng các ví dụ của tôi sẽ hiển thị những gì tôi đang theo dõi.

Cập nhật Tôi đã sai khi hiển thị các chuỗi có các chữ cái tương ứng được viết hoa. Trong kịch bản thực tế, tất cả các chữ cái là chữ thường nên không dễ dàng như việc kiểm tra các chữ cái nào được viết hoa.

+0

Vì vậy, bạn muốn xem chuỗi có khớp với các chữ hoa trong các chuỗi đó không? Nếu vậy, hãy thử viết một cái gì đó cho nó mà: chỉ lấy các chữ in hoa của những thứ đầy đủ của bạn và tát chúng vào một từ điển (như các khóa có phiên bản đầy đủ như các giá trị), và sau đó dễ dàng tìm kiếm nó. Vì nó là, bạn đã không thực sự hỏi một câu hỏi ... –

+0

Điều tốt nhất tôi có thể nghĩ đến là để trích xuất tất cả các chữ hoa, chuyển đổi chuỗi ngắn để trường hợp trên sau đó làm kiểm tra bình đẳng. –

+0

Semi-OT: ManU có thể được coi là một sự xúc phạm đối với người hâm mộ ManUnited, mặc dù nó được sử dụng rộng rãi như là một viết tắt trong các nước không phải tiếng Anh. –

Trả lời

8

Điều này vượt qua tất cả các bài kiểm tra, bao gồm thêm một số bài tôi đã tạo. Nó sử dụng đệ quy. Dưới đây là các quy tắc mà tôi đã sử dụng:

  • Chữ cái đầu của tên viết tắt phải phù hợp với chữ cái đầu tiên của văn bản
  • Phần còn lại của chữ viết tắt (các abbrev trừ chữ cái đầu tiên) phải viết tắt cho:

    • các từ còn lại, hoặc
    • văn bản còn lại bắt đầu từ bất kỳ vị trí trong từ đầu tiên.

tests=(
    ('fck','fc kopenhavn',True), 
    ('fco','fc kopenhavn',False), 
    ('irl','in real life',True), 
    ('irnl','in real life',False),  
    ('ifk','ifk gotebork',True), 
    ('ifko','ifk gotebork',False),  
    ('aik','allmanna idrottskluben',True), 
    ('aid','allmanna idrottskluben',True), 
    ('manu','manchester united',True), 
    ('fz','faz zoo',True), 
    ('fzz','faz zoo',True), 
    ('fzzz','faz zoo',False),  
    ) 

def is_abbrev(abbrev, text): 
    abbrev=abbrev.lower() 
    text=text.lower() 
    words=text.split() 
    if not abbrev: 
     return True 
    if abbrev and not text: 
     return False 
    if abbrev[0]!=text[0]: 
     return False 
    else: 
     return (is_abbrev(abbrev[1:],' '.join(words[1:])) or 
       any(is_abbrev(abbrev[1:],text[i+1:]) 
        for i in range(len(words[0])))) 

for abbrev,text,answer in tests: 
    result=is_abbrev(abbrev,text) 
    print(abbrev,text,result,answer) 
    assert result==answer 
+0

Darn, đánh bại tôi sau 30 giây :) +1 –

+0

Xin lỗi, tất cả các chuỗi được cho là tất cả chữ thường. Tất cả đều là chữ thường trong bản gốc. –

0

thuật toán của bạn có vẻ rất đơn giản - tên viết tắt là Concatenation của tất cả các trường hợp chữ hoa. như vậy:

upper_case_letters = "QWERTYUIOPASDFGHJKLZXCVBNM" 
abbrevation = "" 
for letter in word_i_want_to_check: 
    if letter in letters: 
     abbrevation += letter 
for abb in _list_of_abbrevations: 
    if abb=abbrevation: 
     great_success() 
+3

Bạn có thể sử dụng 'string.ascii_uppercase' –

+0

Điều đó sẽ tốt hơn:/ – Dominik

0

Điều này có thể đủ tốt.

def is_abbrevation(abbrevation, word): 
    lowword = word.lower() 
    lowabbr = abbrevation.lower() 

    for c in lowabbr: 
     if c not in lowword: 
      return False 

    return True 

print is_abbrevation('fck', 'FC Kopenhavn') 
+0

Điều đó không đúng, ví dụ: thử 'print is_abbrevation ('fkc', 'FC Kopenhavn')' –

4

Dưới đây là một cách để thực hiện những gì bạn dường như muốn làm

import re  
def is_abbrev(abbrev, text): 
    pattern = ".*".join(abbrev.lower()) 
    return re.match("^" + pattern, text.lower()) is not None 

Các caret đảm bảo rằng các ký tự đầu tiên của tên viết tắt phù hợp với ký tự đầu tiên của từ, nó phải là đúng đối với hầu hết các từ viết tắt.

Chỉnh sửa: Bản cập nhật mới của bạn đã thay đổi quy tắc một chút. Bằng cách sử dụng "(|.*\s)" thay vì ".*", các ký tự viết tắt sẽ chỉ khớp nếu chúng nằm cạnh nhau hoặc nếu ký tự tiếp theo xuất hiện ở đầu từ mới.

Điều này sẽ khớp chính xác fck với FC Kopenhavn, nhưng fco sẽ không. Tuy nhiên, kết hợp aik với allmanna idrottskluben sẽ không hoạt động, vì điều đó đòi hỏi kiến ​​thức về ngôn ngữ Thụy Điển và không phải là tầm thường để làm.

Dưới đây là các mã mới với việc sửa đổi nhỏ

import re  
def is_abbrev(abbrev, text): 
    pattern = "(|.*\s)".join(abbrev.lower()) 
    return re.match("^" + pattern, text.lower()) is not None 
4

@Ocaso Protal nói trong comment how should you decide that aik is valid, but aid is not valid? và ông là đúng.

Bản ngã đi kèm trong tâm trí của tôi là làm việc với word threshold (số từ được phân cách bằng dấu cách).

words = string.strip().split() 
if len(words) > 2: 
    #take first letter of every word 
elif len(words) == 2: 
    #take two letters from first word and one letter from other 
else: 
    #we have single word, take first three letter or as you like 

bạn phải xác định logic của mình, bạn không thể tìm thấy chữ viết tắt một cách mù quáng.

Các vấn đề liên quan