轨道
/
Factor
Factor
/
练习
/
诗歌俱乐部
诗歌俱乐部

诗歌俱乐部

学习练习

简介

一个不相交集(并查集结构)维护一组值,把它们划分成互不重叠的组,并能快速回答一个问题:这两个值是否在同一组?它位于disjoint-sets词汇表中。

构建不相交集

<disjoint-set>构建一个空结构。值,也就是原子,可以用add-atom一次添加一个,也可以用add-atoms从一个序列中添加。每个原子一开始都单独成组。

<disjoint-set> ( -- disjoint-set )
add-atom       ( atom disjoint-set -- )
add-atoms      ( seq disjoint-set -- )
USING: disjoint-sets ;

<disjoint-set>
{ 1 2 3 } over add-atoms   ! 1, 2 and 3 each in their own group

不相交集是可变的:add-atom、add-atoms和equate会就地修改它,而不是返回一个新的。当某个单词消耗掉不相交集之后,你想再把它放回栈上时,keep就很好用。

合并组

equate会合并包含其原子的那两个组。合并具有传递性:先合并两个原子,再把其中一个与第三个合并,这三个原子最终就在同一个组里。

equate ( atom1 atom2 disjoint-set -- )

代表元

每个组都有一个规范成员,也就是它的代表元。representative会返回它,而两个原子属于同一组,当且仅当它们的代表元相等。

representative ( atom disjoint-set -- representative )
USING: disjoint-sets ;

<disjoint-set>
{ 1 2 3 } over add-atoms
1 2 pick equate
1 over representative .   ! => 1
2 over representative .   ! => 1   (same representative as 1)
3 over representative .   ! => 3   (still on its own)

一个组会选哪个原子作为代表元,属于内部细节:永远不要依赖某个特定原子被选中,只需依赖同一组中的两个原子能得到一致的结果。

说明

当地的诗歌俱乐部要开始新的一季了。诗人加入俱乐部,只要其中两位合写一首诗,他们就属于同一个写作圈。俱乐部想记录谁和谁在同一个圈子里,于是请你编写管理它的那些词。

不相交集合再合适不过:每位诗人是一个原子,一个写作圈就是一个组。

1. 开办俱乐部

定义new-club,它接收一个诗人序列,返回一个全新的不相交集合,其中每位诗人都已登记。每位诗人一开始都待在自己的写作圈里。

{ "Keats" "Byron" "Dickinson" } new-club
! => a disjoint set holding the three poets

2. 记录一次合作

定义collaborate,它接收两位诗人和一个俱乐部。它把两位诗人的写作圈合并,并返回这个俱乐部,这样就可以一次接一次地记录合作。

{ "Keats" "Byron" "Dickinson" } new-club
"Keats" "Byron" rot collaborate
! => the club, with Keats and Byron now in one circle

3. 找到一位诗人的圈子

定义circle-of,它接收一位诗人和一个俱乐部,返回这位诗人所在写作圈的代表。同一个圈子里的两位诗人,报告出来的代表总是同一个。

{ "Keats" "Byron" "Dickinson" } new-club
"Dickinson" swap circle-of
! => "Dickinson"   (still in a circle of their own)

4. 是否在同一个圈子?

定义same-circle?,它接收两位诗人和一个俱乐部,当两位诗人属于同一个写作圈时返回t,否则返回f。请比较这两位诗人的代表,不要使用内置的等价测试。

{ "Keats" "Byron" "Dickinson" } new-club
"Keats" "Byron" rot collaborate
dup [ "Keats" "Byron" ] dip same-circle? .      ! => t
    [ "Keats" "Dickinson" ] dip same-circle? .  ! => f
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Factor Exercism

准备好开始 诗歌俱乐部 了吗?

注册 Exercism,借助 47 个概念163 个练习 和真人导师指导,学习并掌握 Factor,全部免费。