Understanding isomorphic strings algorithm

后端 未结 4 1259
梦谈多话
梦谈多话 2021-01-27 08:15

I am understanding the following code to find if the strings are isomorphic or not. The code uses two hashes s_dict and t_dict respectively. I am assum

4条回答
  •  猫巷女王i
    2021-01-27 09:02

    This was kind of fun to look at. Just for kicks, here's my solution using itertools.groupby

    from itertools import groupby
    from collections import defaultdict
    
    def get_idx_count(word):
        """Turns a word into a series of tuples (idx, consecutive_chars)
    
        "aabbccaa" -> [[(0, 2), (3, 2)], [(1, 2)], [(2, 2)]]
        """
        lst = defaultdict(list)
        for idx, (grp, val) in enumerate(groupby(word)):
            lst[grp].append((idx, sum(1 for _ in val)))
        return sorted(list(lst.values()))
    
    def is_isomorphic(a, b):
        return get_idx_count(a) == get_idx_count(b)
    
    is_isomorphic('aabbcc', 'bbddcc')  # True
    is_isomorphic('aabbaa', 'bbddcc')  # False
    

    Rather than building the lists, I feel like I could do something more like:

    from itertools import groupby
    from collections import defaultdict
    
    def is_isomorphic(a, b):
        a_idxs, b_idxs = defaultdict(set), defaultdict(set)
        for idx, ((a_grp, a_vals), (b_grp, b_vals)) in enumerate(zip(groupby(a), groupby(b))):
            if sum(1 for _ in a_vals) != sum(1 for _ in b_vals):
                return False
                # ensure sequence is of same length
            if a_grp in a_idxs and b_idxs[b_grp] != a_idxs[a_grp] or\
               b_grp in b_idxs and a_idxs[a_grp] != b_idxs[b_grp]:
                return False
                # ensure previous occurrences are matching groups
            a_idxs[a_grp].add(idx)
            b_idxs[b_grp].add(idx)
            # save indexes for future checks
        return True
    

    But I haven't had a chance to test that whatsoever. It does, however, have the likelihood of exiting early, rather than having to build all the lists and comparing them at the end. It also skips a few sets of sorting that shouldn't be necessary anyway, except that we're pulling from dicts, so bleh. Pretty sure list.sort is faster than saving to to a collections.OrderedDict. I think.

提交回复
热议问题