我同意Joachim Isaksson's answer 的观点,即一般情况——哎呀,即使是不太一般的情况——也很难解决。但我想提出一种策略来解决具有指定起始元素的分子树图的相对狭窄情况。 [请注意,这相当于我在处理此答案时发布的Peter de Rivaz's answer。]
首先让我们定义一种形式或语言来描述该图独有的分子图——该图只能形成一个字符串。这将允许我们比较两个字符串以确定两个图表是否相同,从而将您的问题简化为创建两个正确的字符串进行比较。 (这种方法还具有比直接图比较算法更易于直观调试的优点。)我通常看到以 H2O 和 H2 等形式描述的分子SO4,但这种方法不保留分子的图形特性,因此不能用于比较(H2O 可能是水或其他一些其元素的排列非常奇怪)。所以让我们根据这些规则使用类似 Lisp 的东西来描述分子:
- 每个图(包括子图)以
( 开头,以) 结尾
- 任何具有子节点的节点 A 都是新图中列出的第一个节点,并且该图按特定顺序列在其父图中(稍后确定)
- 任何没有子节点的节点 A 都按特定顺序列在其父图中(稍后确定)
有了这些起始规则,我们现在可以用更多类似图形的术语来描述 H2O:
-
O 是图的根,因此它会启动一个新图:(O)
-
H 是 O 的第一个孩子,但它没有孩子,所以它按原样列在其父级中,而不是作为子图的开头:(OH)
-
H 是 O 的第二个孩子,但它没有孩子,所以它按原样列在其父级中,而不是作为子图的开头:(OHH)
所以
变成(OHH)。
在这种情况下排序无关紧要,因为两个Hs 是无子元素并且在元素上是等价的。
让我们尝试一种奇怪的、非理性的 H2O 形式来测试这种方法:
-
O 是图的根,因此它开始一个新图:(O)
-
H 是 O 的第一个孩子。它有一个孩子,所以它开始一个新的图表:(O(H))
-
H 是 H 的第一个孩子,但它没有孩子,所以它按原样列在其父级中,而不是作为子图的开头:(O(HH))
我们知道到目前为止,我们的方法可以处理简单的情况,例如 H2O,其中排序不是问题,但 H2SO4如果没有一致地对来自S 的O 元素进行排序,sub> 将无法工作。在计算子图(如果有的话)之前,不可能给一个子图一个有意义的命令,所以我们将添加一个最终规则来执行:
- 每个图(包括子图)以
( 开头,以) 结尾
- 任何具有子节点的节点 A 都是新图中列出的第一个节点,并且该图按特定顺序列在其父图中(参见步骤 4)
- 任何没有子节点的节点 A 都按特定顺序列在其父图中(参见步骤 4)
- 访问完所有子节点并创建子图(如果有)后,按字母顺序排列父节点中的子节点/子子图
使用这个新规则重新访问 H2O 会产生相同的输出,因为这两个 Hs 在字母顺序上是等效的,并且它们没有子级。所以让我们试试 H2SO4:
-
S 是图的根,因此它开始一个新图:(S)
-
O 是 S 的第一个孩子。它有孩子,所以它开始一个新的图表:(S[unsorted:](O))
'H' 是O 的第一个孩子。它没有孩子。没有其他子要处理,因此不需要在此级别进行排序:(S[unsorted:](OH))
O 是S 的第二个孩子。这个没有孩子:(S[unsorted:](OH)O)
O 是S 的第三个孩子。它有孩子,所以它开始一个新的图表:(S[unsorted:](OH)O(O))
'H' 是O 的第一个孩子。它没有孩子。没有其他子要处理,因此不需要在此级别进行排序:(S[unsorted:](OH)O(OH))
O 是S 的第四个孩子。这个没有孩子:(S[unsorted:](OH)O(OH)O)
- 最后,按字母顺序对
S 的孩子进行排序:(S(OH)(OH)OO)(请注意,我在字母比较中对子图进行了特殊处理,但这不是必需的。)
最终结果是(S(OH)(OH)OO)
让我们尝试 H2SO4 的变体,看看它会产生什么。请注意,这并不能证明该方法是好的,只是演示图表中的变化如何产生不同的结果。
-
S 是图的根,因此它开始一个新图:(S)
-
O 是S 的第一个孩子。它有孩子,所以它开始一个新的图表:(S[unsorted:](O))
-
O 是第一个孩子。它没有孩子。 (S[unsorted:](O[unsorted:]O))
-
H 是第二个孩子,没有孩子。 (S[unsorted:](O[unsorted:]OH))
- 现在对
O 的孩子进行排序:(S[unsorted:](OHO)
-
O 是 S 的第二个孩子。它有孩子,所以它开始一个新的图表:(S[unsorted:](O))
-
H 是第一个孩子。它没有孩子。 (S[unsorted:](OHO)(O[unsorted:]H))
-
O 是第二个孩子,没有孩子。 (S[unsorted:](OHO)(O[unsorted:]HO))
- 现在对
O 的孩子进行排序:(S[unsorted:](OHO)(OHO))
- 最后,按字母顺序对
S 的孩子进行排序:(S(OHO)(OHO))
这个 H2SO4 ((S(OHO)(OHO))) 与前一个 ((S(OH)(OH)OO)) 不同。
我没有试图正式证明这种方法可以保证有效,甚至没有正式描述它,也没有试图解释广泛的分子细节,如债券计数等。不过,至少,我希望这能鼓励您尝试解决图形比较问题。我认为这是可行的。