كيفية إرجاع مجموعة تقاطع روبي مع العناصر المكررة؟ (مشكلة مع bigrams في النرد معامل)

StackOverflow https://stackoverflow.com/questions/1600168

سؤال

وأنا أحاول أن معامل النصي النرد، ولكن أواجه قليلا من مشكلة مع تقاطع مجموعة.

def bigram(string)
  string.downcase!
  bgarray=[]
  bgstring="%"+string+"#"
  bgslength = bgstring.length
  0.upto(bgslength-2) do |i|
    bgarray << bgstring[i,2]
   end
   return bgarray
 end

def approx_string_match(teststring, refstring)
  test_bigram = bigram(teststring) #.uniq
  ref_bigram = bigram(refstring)   #.uniq

  bigram_overlay = test_bigram & ref_bigram

  result = (2*bigram_overlay.length.to_f)/(test_bigram.length.to_f+ref_bigram.length.to_f)*100

  return result
end

والمشكلة هي، كما ويزيل مكررة، وأحصل على مثل هذه الاشياء:

string1="Almirante Almeida Almada"
string2="Almirante Almeida Almada"

puts approx_string_match(string1, string2) => 76.0%

ويجب أن إرجاع 100.

والأظافر طريقة UNIQ ذلك، ولكن هناك فقدان المعلومات، وهو ما قد يؤدي مباريات غير المرغوب فيها في مجموعة البيانات معين أعمل.

وكيف يمكنني الحصول على التقاطع مع كل المتكرر؟

هل كانت مفيدة؟

المحلول

وكما قال Yuval F يجب عليك استخدام multiset. ومع ذلك، هناك nomultiset في المكتبة القياسية روبي، يأخذ في البحث في هنا و هنا .

وإذا كان الأداء ليس حاسما للتطبيق الخاص بك، فإنك لا تزال تستطيع ان تفعل ذلك usingArray مع رمز قليلا.

def intersect  a , b  
    a.inject([]) do |intersect, s|
      index = b.index(s)
      unless index.nil?
         intersect << s
         b.delete_at(index)
      end
      intersect        
    end
end

a=  ["al","al","lc" ,"lc","ld"]
b = ["al","al" ,"lc" ,"ef"]
puts intersect(a ,b).inspect   #["al", "al", "lc"]

نصائح أخرى

هذا الرابط أعتقد يجب أن لا تستخدم مجموعات روبي بل MULTISETS، بحيث ان كل bigram يحصل على حساب عدد المرات التي تظهر. ربما يمكنك استخدام هذه الأحجار الكريمة لMULTISETS. وهذا ينبغي أن تعطي السلوك الصحيح لbigrams المتكررة.

وأنا غازل مع هذا، بناء على الاجابة منpierr، لفترة من الوقت، وانتهى الأمر ذلك.

a = ["al","al","lc","lc","lc","lc","ld"]
b = ["al","al","al","al","al","lc","ef"]
result=[]
h1,h2=Hash.new(0),Hash.new(0)
a.each{|x| h1[x]+=1}
b.each{|x| h2[x]+=1}
h1.each_pair{|key,val| result<<[key]*[val,h2[key]].min if h2[key]!=0}
result.flatten

و=> ["al", "al", "lc"]

وهذا قد يكون نوعا من تتقاطع مولتيست من a وb ولكن لا تأخذ كلمة بلدي لذلك لأنني لم نجرب ذلك ما يكفي للتأكد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top