'Decodes CTC output to a string.
Extracts only sequences of codes that are allowed by self.decoder.
Labels that make illegal code sequences are dropped.
Note that, by its nature of taking only top choices, this is much weaker
than a full-blown beam search that considers all the softmax outputs.
For languages without many multi-code sequences, this doesn\'t make much
difference, but for complex scripts the accuracy will be much lower.
Args:
ctc_labels: List of class labels including null characters to remove.
merge_dups: If True, Duplicate labels will be merged
null_label: Label value to ignore.
Returns:
Labels decoded to a string.'

def StringFromCTC(self, ctc_labels, merge_dups, null_label):

    codes = self._CodesFromCTC(ctc_labels, merge_dups, null_label)
    length = len(codes)
    if (length == 0):
        return ''
    strings = []
    partials = []
    for pos in xrange(length):
        code = codes[pos]
        parts = self.decoder[code]
        partials.append([])
        strings.append('')
        for (utf8, index, num_codes) in parts:
            if (index > pos):
                continue
            if ((index == 0) or (partials[(pos - 1)].count(Part(utf8, (index - 1), num_codes)) > 0)):
                if (index < (num_codes - 1)):
                    partials[(-1)].append(Part(utf8, index, num_codes))
                elif (not strings[(-1)]):
                    if (pos >= num_codes):
                        strings[(-1)] = (strings[(pos - num_codes)] + utf8)
                    else:
                        strings[(-1)] = utf8
        if ((not strings[(-1)]) and (pos > 0)):
            strings[(-1)] = strings[(-2)]
    return strings[(-1)]
