问题
I try to break down the decoding algorithm wanted question into smaller questions. This is Part I.
Question:
- two strings: s1 and s2
- part of s1 is identical to part of s2
- space is separator
- how to extract the identical part(s)?
example 1:
s1 = "12 November 2010 - 1 visitor"
s2 = "6 July 2010 - 100 visitors"
the identical parts are "2010", "-", "1" and "visitor"
example 2:
s1 = "Welcome, John!"
s2 = "Welcome, Peter!"
the identical parts are "Welcome," and "!"
example 3: (to clarify the "!" example)
s1 = "Welcome, Sam!"
s2 = "Welcome, Tom!"
the identical parts are "Welcome," and "m!"
Python and Ruby preferred. Thanks
回答1:
EDIT: Updated this example to work with all the examples, including #1:
def scan(s1, s2):
# Find the longest match where s1 starts with s2
# Returns None if no matches
l = len(s1)
while 1:
if not l:
return None
elif s1[:l] == s2[:l]:
return s1[:l]
else:
l -= 1
def contains(s1, s2):
D = {} # Remove duplicates using a dict
L1 = s1.split(' ')
L2 = s2.split(' ')
# Don't add results which have already
# been processed to satisfy example #1!
DProcessed = {}
for x in L1:
yy = 0
for y in L2:
if yy in DProcessed:
yy += 1
continue
# Scan from the start to the end of the words
a = scan(x, y)
if a:
DProcessed[yy] = None
D[a] = None
break
# Scan from the end to the start of the words
a = scan(x[::-1], y[::-1])
if a:
DProcessed[yy] = None
D[a[::-1]] = None
break
yy += 1
return list(D.keys())
print contains("12 November 2010 - 1 visitor",
"6 July 2010 - 100 visitors")
print contains("Welcome, John!",
"Welcome, Peter!")
print contains("Welcome, Sam!",
"Welcome, Tom!")
Which outputs:
['1', 'visitor', '-', '2010']
['Welcome,', '!']
['Welcome,', 'm!']
回答2:
For example 1
>>> s1 = 'November 2010 - 1 visitor'
>>> s2 = '6 July 2010 - 100 visitors'
>>>
>>> [i for i in s1.split() if any(j for j in s2.split() if i in j)]
['2010', '-', '1', 'visitor']
>>>
For both
>>> s1 = "Welcome, John!"
>>> s2 = "Welcome, Peter!"
>>> [i for i in s1.replace('!',' !').split() if any(j for j in s2.replace('!',' !').split() if i in j)]
['Welcome,', '!']
>>>
Note: Above codes will not work for example 3, which is OP just added
回答3:
s1 = "12 November 2010 - 1 visitor"
s2 = "6 July 2010 - 100 visitors"
l1 = s1.split()
for item in l1:
if item in s2:
print item
This splits on whitespace.
A solution that also splits on word boundaries (in order to catch the ! in example 2) doesn't work in Python because re.split() won't split on zero-length matches.
The third example, making even any substring of the words a potential match, is making things a lot more complicated because of the many possible variations (for 1234, I'd have to check against 1234, 123, 234, 12, 23, 34, 1, 2, 3 and 4, and with each extra digit, the number of permutations increases exponentially.
回答4:
The complete Ruby solution:
def start_similar(i, j)
front = ''
for ix in (0...([i.size, j.size].min))
if i[ix] == j[ix] then
front += i[ix].chr
else
break
end
end
return front
end
def back_similar(i, j)
back = ''
for ix in (0...([i.size, j.size].min)).to_a.reverse
dif = i.size < j.size ? j.size - i.size : i.size - j.size
ci = i[ i.size < j.size ? ix : ix + dif ]
cj = j[ i.size > j.size ? ix : ix + dif ]
if ci == cj then
back = ci.chr + back
else
break
end
end
return back
end
def scan(x, y)
a, b = x.split(' '), y.split(' ')
result = []
for i in a do
for j in b do
result << start_similar(i, j)
result << back_similar(i, j)
end
end
return result.uniq.select do |r| not r.empty? end
end
puts scan(
"12 November 2010 - 1 visitor",
"6 July 2010 - 100 visitors"
).inspect
# ["1", "2010", "0", "-", "visitor"]
puts scan(
"Welcome, John!",
"Welcome, Peter!"
).inspect
# ["Welcome,", "!"]
puts scan(
"Welcome, Sam!",
"Welcome, Tom!"
).inspect
# ["Welcome,", "m!"]
来源:https://stackoverflow.com/questions/2712466/how-to-detect-identical-parts-inside-string