Algorithm 由周期表元素生成最大单词的算法
我想为下面的问题场景编写一个算法 取元素周期表元素的名称,找出可以形成的最大单词? 诸如Algorithm 由周期表元素生成最大单词的算法,algorithm,word,Algorithm,Word,我想为下面的问题场景编写一个算法 取元素周期表元素的名称,找出可以形成的最大单词? 诸如Na、Ne等符号应视为单个元素 这是在一家知名公司的求职面试中提出的。 谁能帮我解决这个问题。生成所有可能的单词-天真的方法。 基于: 您可以生成所有可能的组合,并对照字典检查它是否是一个真实的单词。但这是低效的,而且只有在不允许符号重复的情况下才能使用 检查单词是否可以从符号中构建-仍然不完美。 如果允许重复,则需要对照符号列表检查单词。我提议如下: import itertools.. words = [
Na
、Ne
等符号应视为单个元素
这是在一家知名公司的求职面试中提出的。
谁能帮我解决这个问题。生成所有可能的单词-天真的方法。
基于:
您可以生成所有可能的组合,并对照字典检查它是否是一个真实的单词。但这是低效的,而且只有在不允许符号重复的情况下才能使用
检查单词是否可以从符号中构建-仍然不完美。
如果允许重复,则需要对照符号列表检查单词。我提议如下:
import itertools..
words = ['K', 'NaH', 'NaNaNaNa', 'HaKuNa']
symbols = ['Na','K','H']
for i in range(len(symbols)):
for word in itertools.permutations(symbols,i+1):
print( ''.join(word) )
def can_be_built(word):
pos = 0
ret = True
while(pos < len(word)):
#following loop checks if word starting form `pos`
#can be prefixed by a symbol
symbol_match = False
for symbol in symbols:
if word[pos:pos+len(symbol)] == symbol:
symbol_match = True
break
if symbol_match == False:
print('Word `{}` has no match for symbol from: {}'.format(word, word[pos:]))
ret = False
break
#if it does move forward
pos += len(symbol)
return ret
for word in words:
print("{} can be built? {}".format(word, can_be_built(word)))
它仍然不是完美的
正确的方法
正如Makoto所说,前缀检查应该返回每个可能匹配项的列表。算法应该从这些匹配中生成一个队列,并检查所有可能的路径。这有点像是构建一个前缀图来匹配单词。如果有人构建了一个完整的词,那么你就是家了
我认为纠正我的第二个示例仍然是相当容易的,但是我已经没有时间编写实际的代码了。我认为这是一个很好的起点。我认为更好的方法是检查字典中的每个单词,看看它是否可以由元素的名称组成。检查元素的每个排列将更难编程,效率也更低 虽然我同意产生这些组合比较容易,但是它们太多了,正如你所说的,如果你不给出一个限制,它们会趋于无穷大。带符号的单词的产生会稍微有点困难和挑剔,但我认为不会太难 例如,当你得到一个单词时,你可以在元素中搜索可以组成你单词的元素,然后使用这组元素尝试从头到尾填写字母。显然,对于长度不是2个字母和奇数的单词的元素,这会变得更加困难 实际上,你可以使用一种图形。说你有“硅”。 您可以从表中的字母“S”或“SI”开始。从中选择“SI”,因为它更接近您的解决方案。如果“SI”不能导致您的解决方案,您必须回来看看“S”是否有效
因此,它是一种深度优先搜索。生成所有单词并检查它们是否存在是不切实际的。有118^1个单词的长度为1,这是一个增长太快的函数。1643032三个符号单词 另一方面,正如Makoto所建议的那样,效率要高得多。试着把字典里的每一个单词都重新组合起来。大约有250000个英语单词 检查单词很简单:查看是否有任何元素符号与单词的开头匹配,然后继续使用剩余的字符 您必须尝试所有可能的匹配项,因为一个匹配项可能隐藏另一个匹配项。(我的意思是,单词ABC可以由符号A匹配,然后被卡住,因为BC不可用,但可能是AB和C不可用。)因此匹配函数将是递归的。我不期望在这个匹配过程中出现指数级爆炸 为了获得最大效率,您将在trie结构中存储符号 最后提示:当你被要求查找最长的匹配项时,可以通过减少长度来尝试单词,并在第一个匹配项处停止 这是一个简单的Python解决方案,没有任何优化。匹配从右到左进行,以允许按后期顺序打印符号序列:
Words= ['K', 'NaH', 'NaNaNaNa', 'HaKuNa']
Symbols= ['Na','K','H']
def Match(Word):
# Match the end of the word with every symbol
for S in Symbols:
# In case of a partial match, recurse on the prefix
if S == Word or (S == Word[-len(S):] and Match(Word[:-len(S)])):
print S,
return True
# No match, report failure
return False
for W in Words:
if Match(W):
print
>>>
K
Na H
Na Na Na Na
对不起,我被这些答案弄糊涂了。显然,最明显的答案是使用嵌套的bucket排序按字母顺序对字典进行排序,排序深度达到一定程度,比如说8个字母,这将为您提供从给定字母序列开始到8个字母的1次单词检索 然后像做游戏树一样浏览周期表。在每个步骤中,添加一个元素,然后检查列表,查看是否有以该组合开头的单词
这将相对占用大量内存,因为您可能需要至少6层存储桶(按前6个字母的字母顺序排列),但通常只有1000000个左右的单词。由于游戏树中几乎每个分支都会在四个字母后终止,因此youre DFS将非常快速地搜索整个游戏树。如果你能在字典中形成每个单词,那么它的分支数量必须与单词数量相同,并且在实践中,你只能在字典中得到一小部分单词,因此这种方法必须是有效的。[编辑:这篇文章基本上只是对Niklas B.在其他文章评论中提到的DP算法的完整解释。] 在线性时间内测试特定单词 在一个可以由化学元素名称构成的单词中,必须至少有以下一项为真:
- 最后一个字母是单字母化学元素名称,由除最后一个字母以外的所有字母组成的前缀本身是一个可以由化学元素名称构成的单词
- 最后两个字母是两个字母的化学元素名称,由除最后两个字母以外的所有字母组成的前缀本身就是一个可以由化学元素名称构成的单词
这就提出了一个很好的DP算法,对于长度为k的给定单词w,我们计算所有1如何将给定单词表示为化合物?这是一个动态规划解决方案。重要的一行是“让progress[i]作为单词[:i]的子问题的解”。下面是其他内容
elements=“H He He He Li Be B C N O F Ne Na Mg Al Si P Cl Ar K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe Cs Ba La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn Fr Ra
K can be built? True
NaH can be built? True
NaNaNaNa can be built? True
Word `HaKuNa` has no match for symbol from: aKuNa
HaKuNa can be built? False
Words= ['K', 'NaH', 'NaNaNaNa', 'HaKuNa']
Symbols= ['Na','K','H']
def Match(Word):
# Match the end of the word with every symbol
for S in Symbols:
# In case of a partial match, recurse on the prefix
if S == Word or (S == Word[-len(S):] and Match(Word[:-len(S)])):
print S,
return True
# No match, report failure
return False
for W in Words:
if Match(W):
print
>>>
K
Na H
Na Na Na Na
Backtracking void(String result, String[] PeriTable, String[] used){
for(int i=0;i<PeriTable.length;i++){
If(!used.contain(PeriTable[i])){
newResult=result+PeriTable[i];
If(isEnglishWord(newResult)) {
used.add(PeriTable[i]);
maxlength=Math.max(maxlength,newResult.length());
Backtracking(newResult, PeriTable, used);
used.remove(used.length()-1);
}
}
else continue;
}
}