如果每个单词与下一个单词至少有2个字母,则该字符串被命名为 2-consistent 。
例如
" Atom另一个时代" [
atom
与a
和t
共有another
和another
e
与a
有era
和"Do these words have at least 2 letters in common?"
(答案不是唯一的)。
首先,我需要一个数据结构,在问题n
现在,给定一串radix tree
字词,我需要找到最长的2-consistent 子字符串。
我无法弄清楚要使用哪种数据结构。我想到了prefix tree
或{{1}},但我找不到答案。你能救我吗?
答案 0 :(得分:4)
假设字母不重音并忽略大小写,对于每个单词,您可以将位字段存储在32位整数中,如果存在来自a-z的相应字母,则位0-25设置为1。
整数可以按线性时间计算:
int getBitField(char* word)
{
int bits = 0;
while(*word)
bits |= 1 << ((*word++) - 'a');
return bits;
}
如果假设单词是英语单词或其他语言,单词长度最大则则恒定时间和线性时间之间的差异毫无意义,因为(为了论证)所有小于最大长度的单词都可以用不匹配的字符填充,这将产生一个恒定的时间算法。
一旦你有两个单词的位字段,你可以通过将它们组合在一起并检查结果是否为零(这表示没有共同的字母)而不是通用的幂来测试它们是否在恒定时间内是2 - 一致的2(这表示只有一个字母共同,因为只设置了一个位)。您可以通过对自身减去1的数字进行运算来测试2的幂。
bool is2Consistent(int word1bits, int word2bits)
{
int common = word1bits & word2bits;
return (common & (common - 1)) != 0;
}
如果您打算定义像“见面”这样的词,那么这项工作将无法奏效。和牛肉&#39;其中重复的字母为2-consistent。
如果您想测试3次一致性,只需在函数中添加一行:
bool is3Consistent(int word1bits, int word2bits)
{
int common = word1bits & word2bits;
common &= (common - 1);
return (common & (common - 1)) != 0;
}
将一个整数与自身减去1只能删除最低有效位,因此您可以将它应用任意次数来测试4一致性,5次一致性等。
答案 1 :(得分:2)
第1部分:MyObject.abs(-12)
和wordOne
是否一致?
wordTwo
第2部分:最长的2个一致子字符串
public bool IsWordsTwoConsistent(string first, string second)
{
int[] letters = Enumerable.Repeat(0, 26).ToArray();
int countDoubles = 0;
foreach (char c in first.toLowerCase())
{
letters[(int)c - 97]++;
}
foreach (char c in second.toLowerCase())
{
if (letters[(int)c - 97] > 0)
countDoubles++;
if (countDoubles > 1)
return true;
}
return false;
}
答案 2 :(得分:1)
首先,我需要一个需要2个单词和答案的数据结构 在问题“这些词至少有2个 共同的字母?“
易。首先计算你正在使用的字典的邻接矩阵,其中'adjacent'被定义为'至少有两个共同的字母'。我不同意上面的评论,如今存储一个全面的英语词典并不是很多数据。存储完整的邻接矩阵可能会占用您太多的空间,因此请使用稀疏数组工具。
现在,请记住,英语单词只是基数为26的数字(如果你坚持区分大写字母,则为base-52),因此查找一对单词的行和列是一个常数时间操作,你有解决问题的方法。
哦,当然,这会耗费空间并进行大量的预先计算,但是OP会询问一个数据结构,以便在固定的时间内回答问题。