使用python查找并删除公共子字符串

使用python查找并删除公共子字符串,python,substring,bioinformatics,Python,Substring,Bioinformatics,我有两个引物序列: fiveprime = "GATTCGAAGTCCACTATC" threeprime = "TGAGTAGGACGGCACTATC" 我认为,如果您选择适当的数据结构来表示您试图查找的数据,您的问题将更容易处理。我能想到的最好的是一个 这种结构的好处是,它允许您在给定字母初始序列的情况下表示所有可能的匹配,因此,如果您有序列AABAB,它将允许从初始A到A和B的遍历,但不允许从A到G或T的遍历。这使得查找部分匹配非常有效,因为trie中的任何一点都代表了这么多字母的匹配 此

我有两个引物序列:

fiveprime = "GATTCGAAGTCCACTATC" threeprime = "TGAGTAGGACGGCACTATC"
我认为,如果您选择适当的数据结构来表示您试图查找的数据,您的问题将更容易处理。我能想到的最好的是一个

这种结构的好处是,它允许您在给定字母初始序列的情况下表示所有可能的匹配,因此,如果您有序列AABAB,它将允许从初始A到A和B的遍历,但不允许从A到G或T的遍历。这使得查找部分匹配非常有效,因为trie中的任何一点都代表了这么多字母的匹配

此数据结构类似于:

class Trie(object):
    def __init__(self):
        self.children = {}

    def add_child(self, letter):
        if letter in self.children:
            return self.children[letter]
        else:
            child = Trie()
            self.children[letter] = child
            return child

    def traverse(self, letter):
        return self.children.get(letter, None)
然后,您可以这样填充:

root = Trie()
current_positions = []
for letter in letters:
    current_positions = [
        position.add_child(letter)
        for position in current_positions
    ]
    current_positions.append(root.add_child(letter))
class TrieSearch(object):
    def __init__(self, trie, starting_index):
        self.trie = trie
        self.starting_index = starting_index
        self.ending_index = starting_index + 1

    def update(self, letter):
        """ This returns a boolean indicating
            if the search can accept the letter """
        self.trie = self.trie.traverse(letter)
        if self.trie is not None:
            self.ending_index = self.ending_index + 1
            return True
        return False

    def get_match(self, letters):
        return letters[self.starting_index:self.ending_index]

def find_matches(root, letters):
    completed_matches = []
    current_matches = []

    for index, letter in enumerate(letters):
        new_current = []

        for current in current_matches:
            if current.update(letter):
                new_current.append(current)
            else:
                completed_matches.append(current)

        new_search_trie = root.traverse(letter)
        if new_search_trie is not None:
            new_current.append(TrieSearch(new_search_trie, index))

        current_matches = new_current

    all_matches = completed_matches + current_matches
    return [match.get_match(letters) for match in all_matches]
所有这些设置完成后,您应该能够遍历此结构,直到遍历返回null。这将指示最长的当前匹配。字母的初始化将每个字母视为匹配的潜在起点,您也应该如此

然后可以搜索最长的子字符串匹配,如下所示:

root = Trie()
current_positions = []
for letter in letters:
    current_positions = [
        position.add_child(letter)
        for position in current_positions
    ]
    current_positions.append(root.add_child(letter))
class TrieSearch(object):
    def __init__(self, trie, starting_index):
        self.trie = trie
        self.starting_index = starting_index
        self.ending_index = starting_index + 1

    def update(self, letter):
        """ This returns a boolean indicating
            if the search can accept the letter """
        self.trie = self.trie.traverse(letter)
        if self.trie is not None:
            self.ending_index = self.ending_index + 1
            return True
        return False

    def get_match(self, letters):
        return letters[self.starting_index:self.ending_index]

def find_matches(root, letters):
    completed_matches = []
    current_matches = []

    for index, letter in enumerate(letters):
        new_current = []

        for current in current_matches:
            if current.update(letter):
                new_current.append(current)
            else:
                completed_matches.append(current)

        new_search_trie = root.traverse(letter)
        if new_search_trie is not None:
            new_current.append(TrieSearch(new_search_trie, index))

        current_matches = new_current

    all_matches = completed_matches + current_matches
    return [match.get_match(letters) for match in all_matches]
我将所有这些放在一起,当trie用3prime和5veprime值初始化时,输入数据是cactatcaaaaaaaa,结果是:

['CACTATC', 'ACTATC', 'CTATC', 'TATC', 'ATC', 'TC', 'CA', 'AA', 'AA', 'AA', 'AA', 'AA', 'AA', 'A']
由于您无疑是在处理大量字符串,因此可能需要回顾一些更有效的通用字符串替换算法。这是本文概述的trie方法的扩展。还有使用表而不是trie的。这两种算法都是线性复杂度算法,与longestSubstringFinder方法使用的二次方法相比,这将是一个重大改进。

问题是,longestSubstringFinder已损坏。只有当lenmatch>lenanswer:answer=match的条件为False时,才检查lenmatch>lenanswer:answer=match是否匹配。如果rangelen2:循环中的for j结束时没有发生这种情况,则只需放弃匹配

修复方法很简单:在rangelen2:循环中的forj之后添加forj


您最匹配的字符串的长度是多少?您没有在任何地方定义结构变量,但您很乐意附加到它。根据我输入的字符串,可以是任意长度。这就是为什么我要检查找到的公共子字符串的长度。然后用它来比较找到的结构是否是引物的一部分Haa yeah soz关于我刚才复制和粘贴的结构代码结构被定义为结构=[]只是你的正常列表引物的“一部分”是什么?有多少个字符必须匹配?我将尝试一下,我会告诉你一个是否成功。谢谢你的投入和时间!!我已经把代码示例放在一个要点中,你可能想回顾一下。这太好了,非常感谢你真的帮助了我。如果你想让你的代码更好,那就练习,练习,练习:你可能想看看《干净的代码》这本书,了解一些技巧:我明天第一件事就是检查这个,非常感谢你的时间和投入。