聚类字符串 - 哪种算法合适?

时间:2016-02-04 10:54:28

标签: string algorithm

我有一些字符串,字符不会在一个字符串中重复。 例如:" AABC"是不可能的。

我想通过它们的公共子字符串将它们聚集到集合中。 例如:" ABC,CDF,GHP"将集群分为两组 {ABC,CDF},{GHP}。

具有一个或多个公共子字符串的几个字符串将在一个集合中。 没有公共子字符串和任何其他字符串的字符串将是一个集合本身。 所以保持最小的数量。

例如: 1." ABC,AHD,AKJ,LAN,WER"将是两套{ABC,AHD,AKJ,LAN},{WER}。 2." ABC,BDF,HLK,YHT,PX"将是3集{ABC,BDF}。{HLK,YHT},{PX}。

我认为找到一个与他人没有共同点的字符串很容易;

for(i=0; i< strings.num; i++)
{  str1 = strings[i];
     bool m_com=false;
     for(j=0;j < strings.num; j++ )
     {
      str2=strings[j];
      if(hascommon(str1,str2))
         m_com=true;
     }
   if(!m_com)
   {
     str1 has no common substring with any string,
   }
}

现在我正在考虑其他人,如何对它们进行分类,是否有适合此的算法?

输入:    字符串(字符不重复)

输出:    集(保持集数尽可能小)

我知道这涉及找到常见的子串问题和聚类。 但我不熟悉聚类技术,所以我希望有一些 可以推荐我这样的算法。

虽然我正在寻找做到这一点的好方法,但我也很欣赏其他人的建议。

提示:实际上,这些字符串是图表中两点之间的简单路径。我想找到去除所有这些路径的边缘。这些边缘的数量应该是最小的。因此,对于AB,BC,CD,它意味着存在单个路径ABCD。 我写下了一个算法来查找我的常见子串(我的情况更简单)。我想我可能会在聚类过程中使用这个算法来测量相似性。

我可能有两条路径,{ABC,ADC},删除A或删除B都可以分割路径。 或者我可以{ABC,ADC,HG},所以删除{A,H}或{CH},或{CG},或{AG}都可以。

我以为我可以通过查找常见的子字符串来解决这个问题,然后决定删除边缘的位置。

3 个答案:

答案 0 :(得分:1)

首先应该指出一件事:

For any two strings, "having common substring" is really equivalent to "having common letter". Thus we can replace the condition by "having common letter".

考虑其顶点为字符串的图G,当且仅当它们具有公共字母时,两个字符串由边连接。那么你真的要求将图G分成连接的组件。这可以使用标准图形操作算法,c.f。轻松完成。 the wiki page here

建立图表的任务仍然是什么。这也很简单:首先,创建26个框,标记为AZ,并读取每个字符串一次。如果字符串包含字母A,则将其(或其索引)放入框A等。最后,一个框内的字符串边缘相互连接。

可以进一步优化,但我想这取决于输入数据的性质。

答案 1 :(得分:0)

您必须使用Heap算法为您的工作创建排列https://en.wikipedia.org/wiki/Heap&#39; s_algorithm

答案 2 :(得分:0)

与WhatsUp相反,我假设你希望子集中的任何两个字符串都有一个共同的子字符串。这意味着对于{AB, BC, CD}AB不是有效的解决方案,因为CD和{{1}}没有共同的子字符串。

正如Whatsup已经指出的那样,你可以将你的字符串表示为一个图形,其中顶点是字符串,如果它们有一个共同的字符,则边缘从一个到另一个。

如果我们不接受链(如开头所述),问题就变成了minimum clique cover,遗憾的是NP完全。