理解同构字符串算法

时间:2015-07-16 22:31:22

标签: python dictionary data-structures

我理解下面的代码来查找字符串是否是同构的。该代码分别使用两个哈希t_dictdef isIsomorphic(s, t): s_dict = {} t_dict = {} for i in range(len(s)): if s[i] in s_dict.keys() and s_dict[s[i]] != t[i]: return False if t[i] in t_dict.keys() and t_dict[t[i]] != s[i]: return False s_dict[s[i]] = t[i] t_dict[t[i]] = s[i] return True 。我假设字符串长度相同。

s_dict()

现在,如果我修改上面的代码,只使用一个哈希def isIsomorphic(s, t): s_dict = {} for i in range(len(s)): if s[i] in s_dict.keys() and s_dict[s[i]] != t[i]: return False s_dict[s[i]] = t[i] return True ,那么它也会给我有限的测试用例提供所需的结果。修改后的代码如下:

new ProductView

上述修改后的代码失败的测试用例是什么?我对同构字符串的理解是错误的吗?

4 个答案:

答案 0 :(得分:5)

一个简单的例子,您的代码不适用于s =' ab',t =' aa'。

基本上你必须有两种同构的方式。您的代码只检查了可以从s修改t,但不是相反。

答案 1 :(得分:2)

这看起来很有趣。只是为了踢,这是我使用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

而不是建立列表,我觉得我可以做更多的事情:

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

但我没有机会对此进行测试。但是,它确实有可能提前退出,而不是必须构建所有列表并在最后进行比较。它也跳过了几组不需要的排序,除了我们从dicts中拉出来,所以很好。非常确定list.sort比保存到collections.OrderedDict要快。我想。

答案 2 :(得分:0)

这是Python中同构字符串问题的解决方案:

解决方案1(最快的解决方案):

def isometric_strings_translate(str1: str, str2: str) -> bool:
    trans = str.maketrans(str1, str2)
    return str1.translate(trans) == str2

解决方案2(使用设置):

def isometric_strings_set(str1: str, str2: str) -> bool:
    return len(set(zip(str1, str2))) == len(set(str1))

解决方案3(使用字典):

def isometric_strings_dict(str1: str, str2: str) -> bool:
    map = {}
    for s1, s2 in zip(str1, str2):
        if map.setdefault(s1, s2) != s2:
            return False
    return True

Here you can view full code.

答案 3 :(得分:0)

在没有地图或词典的情况下进行思考可以帮助您理解:

def isIso(x,y):
  if len(x) != len(y):
    return False
  for i in range(len(x)):
    count = 0
    if x.count(x[i]) != y.count(y[i]):
      return False
  return True