所以我有一个看起来像这样的字符串:
data="ABCABDABDABBCBABABDBCABBDBACBBCDB"
我正在随机拿出10个字符片:
start=int(random.random()*100)
end = start+10
slice = data[start:start+10]
但我现在要做的是计算“差距”的数量'或者'洞'根本没有切掉。
slices_indices = []
for i in xrange(0,100):
start=int(random.random()*100)
end= 10
slice = data[start:end]
...
slices_indices.append([start,end])
例如,运行几次后。我报道了这个数额:
ABCAB DABD ABBCBABABDB C ABBDBACBBCDB
但是留下了两个差距'切片。有没有' Pythonic'找到这些差距的方法?所以基本上我正在寻找count_gaps
赋予切片索引的函数。
例如上面,
count_gaps(slices_indices)
会给我两个
提前致谢
答案 0 :(得分:0)
有几个,虽然都涉及到一些混乱
您可以将删除的字符串与原始字符串进行比较,并计算出您未点击的字符。
这是一种非常迂回的方式,但如果你在字符串中有两次相同的10个字符,它将无法正常工作。例如1234123或其他什么。
更好的解决方案是存储您使用的i的值,然后退回数据字符串,将当前位置与您使用的i的值进行比较(加10)。如果不匹配,则完成工作。
例如(伪代码)
# Make an array the same length as the string
charsUsed = array(data.length)
# Do whatever
for i in xrange(0,100)
someStuffYouWereDoingBefore()
# Store our "used chars" in the array
for(char = i; char < i+10; char++)
if(char <= data.length) # Don't go out of bounds on the array!
charsUsed[i] = true
然后看看哪些字符未被使用,只需遍历charsUsed数组并计算你想要计算的数量(连续间隙等)
编辑以回应更新的问题: 我仍然使用上面的方法来制作“使用了哪些字符”数组。然后你的count_gaps()函数只需要遍历数组来“找到”间隙
例如(伪......某事。这甚至不是模糊的Python。希望你能得到这个想法) 这个想法主要是看当前位置是否为假(即未使用),最后一个位置是否为真(使用),这意味着它是“新”缺口的开始。如果两者都是假的,我们就处于差距的中间,如果两者都是真的,我们就处于“使用过的”字符串的中间
function find_gaps(array charsUsed)
{
# Count the gaps
numGaps = 0
# What did we look at last (to see if it's the start of a gap)
# Assume it's true if you want to count "gaps" at the start of the string, assume it's false if you don't.
lastPositionUsed = true
for(i = 0; i < charsUsed.length; i++)
{
if(charsUsed[i] = false && lastPositionUsed = true)
{
numGaps++
}
lastPositionUsed = charsUsed[i]
}
return numGaps
}
另一种选择是再次单步执行charsUsed数组并将连续值“分组”到一个较小的距离,然后计算你想要的值...基本上相同的东西,但采用不同的方法。在这个例子中,我只是忽略我不想要的组和我所做的组的“休息”,只计算我们不想要的组和我们所做的组之间的界限。
答案 1 :(得分:0)
这是一个混乱的任务,但我认为套装是要走的路。我希望下面的代码是不言自明的,但如果有部分你不明白,请告诉我。
#! /usr/bin/env python
''' Count gaps.
Find and count the sections in a sequence that weren't touched by random slicing
From http://stackoverflow.com/questions/26060688/merging-arrays-slices-in-python
Written by PM 2Ring 2014.09.27
'''
import random
from string import ascii_lowercase
def main():
def rand_slice():
start = random.randint(0, len(data) - slice_width)
return start, start + slice_width
#The data to slice
data = 5 * ascii_lowercase
print 'Data:\n%s\nLength : %d\n' % (data, len(data))
random.seed(42)
#A set to capture slice ranges
slices = set()
slice_width = 10
num_slices = 10
print 'Extracting %d slices from data' % num_slices
for i in xrange(num_slices):
start, end = rand_slice()
slices |= set(xrange(start, end))
data_slice = data[start:end].upper()
print '\n%2d, %2d : %s' % (start, end, data_slice)
data = data[:start] + data_slice + data[end:]
print data
#print sorted(slices)
print '\nSlices:\n%s\n' % sorted(slices)
print '\nSearching for gaps missed by slicing'
unsliced = sorted(tuple(set(xrange(len(data))) - slices))
print 'Unsliced:\n%s\n' % (unsliced,)
gaps = []
if unsliced:
last = start = unsliced[0]
for i in unsliced[1:]:
if i > last + 1:
t = (start, last + 1)
gaps.append(t)
print t
start = i
last = i
t = (start, last + 1)
gaps.append(t)
print t
print '\nGaps:\n%s\nCount: %d' % (gaps, len(gaps))
if __name__ == '__main__':
main()
答案 2 :(得分:0)
我使用某种位图。例如,扩展您的代码:
data="ABCABDABDABBCBABABDBCABBDBACBBCDB"
slices_indices = [0]*len(data)
for i in xrange(0,100):
start=int(random.random()*len(data))
end=start + 10
slice = data[start:end]
slices_indices[start:end] = [1] * len(slice)
我在这里使用了list
,但如果您的数据相当大,您可以使用任何其他适当的数据结构,可能更紧凑。
因此,我们用零初始化位图,并用选定的数据块标记。现在我们可以使用itertools
中的内容,例如:
from itertools import groupby
groups = groupby(slices_indices)
groupby
返回一个迭代器,其中每个元素都是一个元组(element, iterator)
。要算出差距,你可以做一些简单的事情,比如:
gaps = len([x for x in groups if x[0] == 0])