注意:我添加了一些其他语言,因为我没有找到特定于PHP的这个问题… JavaScript或jquery解决方案将工作…我可以改变语言…它的方法我追求!
这个想法是字符串是从语音生成的
例1:
打开我的厨房灯,我的卧室和客厅的灯都熄灭了.
例2:
打开我的厨房灯,我的卧室灯亮,客厅灯关闭.
例3:
把我的厨房,卧室和客厅的灯关掉.
这是一个过于简化的例子,但请注意,我想扩展到这三个房间以外只是控制灯光
例如:外面的吊扇……
方法:我目前正在使用一些while循环迭代数组并检查数组中是否有某些字符串.
更多如何:我的想法是首先拆分“和”上的字符串.然后我检查每个阵列的开启或关闭.如果它没有打开或关闭我加入数组与下一个.
帮助:我想清理这个概念以及看到别人的想法……我很想做任何事……
谢谢
JT
码:
$input = 'kitchen lights on and bed and living lights off'; $output = preg_split( "/ (and) /",$input ); $num = (int)count($output); $i=0; while($i<$num){ if ((strpos($output[$i],'on') !== false)||(strpos($output[$i],'off') !== false)) {} elseif(((strpos($output[$i+1],'on') !== false)||(strpos($output[$i+1],'off') !== false))){ $output[$i+1] .= ' + '.$output[$i]; unset($output[$i]); } $i++; } $output = array_values($output); $i=0; $num = (int)count($output); echo '<br>'; while($i<$num){ if ((strpos($output[$i],'lights') !== false)&&(strpos($output[$i],'on') !== false)&&(strpos($output[$i],'kitchen') !== false)){ echo'kitchen lights on<br>'; } if ((strpos($output[$i],'off') !== false)&&(strpos($output[$i],'kitchen') !== false)){ echo'kitchen lights off<br>'; } if ((strpos($output[$i],'living') !== false)){ echo'living lights on<br>'; } if ((strpos($output[$i],'living') !== false)){ echo'living lights off<br>'; } if ((strpos($output[$i],'bed') !== false)){ echo'bed lights on<br>'; } if ((strpos($output[$i],'bed') !== false)){ echo'bed lights off<br>'; } $i++; }
代码试用2:注意:这处理所有上述示例!
<?PHP //works list $inp[]='turn the lights in the bedroom on'; $inp[]='Turn on the bedroom light'; $inp[]='turn on the lights in the bedroom'; $inp[]='Turn my kitchen and my bedroom and living room lights off.'; $inp[]='Turn the light in the kitchen on and the fan in the bedroom off'; $inp[]='Turn my kitchen lights on and my bedroom and living room lights off'; $inp[]='Turn my kitchen fan and my bedroom lights on and living room lights off.'; $inp[]='Turn my kitchen lights on and my bedroom lights on and living room lights off'; $inp[] = 'kitchen lights on and bath and living lights off'; $inp[] = 'flip on the lights in the living room'; $inp[] = 'turn on all lights'; //does not work list //$inp[] = 'turn on all lights but living'; foreach ($inp as $input){ $input = trim($input); $input = rtrim($input,'.'); $input = trim($input); $input = rtrim($input,'.'); $words = explode(" ",$input); $state = array('and','but','on','off','all','living','bed','bedroom','bath','kitchen','dining','light','lights','fan','tv'); $result = array_intersect($words,$state); $result = implode(" ",$result); $result = trim($result); //$result = preg_split('/(and|but)/',$input,-1,PREG_SPLIT_DELIM_CAPTURE); $result = preg_split( "/ (and|but) /",$result ); //$result = explode("and",$result); $sep=array(); foreach($result as $string){ $word = explode(" ",$string); $sep[]=$word; } $test=array(); $num = (int)count($sep); $i=0; while($i<($num)){ $result = (int)count(array_intersect($sep[$i],$state)); $j=$i; while($result<=3) { $imp = implode(" ",$sep[$j]); if(isset($test[$i])){$test[$i]=$imp.' '.$test[$i];} else{$test[$i]=$imp;} if ($result>=3){$j++;break;} $result = (int)count(array_intersect($sep[++$j],$state)); } $i=$j; } print_r($test); echo '<br>'; } ?>
解决方法
话虽如此,如果您愿意限制语法和涉及的关键字,您可能可以简化它.首先你需要知道什么是重要的 – 你在’地方'(卧室,厨房)中需要进入特定状态(‘开’,’关’)的’事物'(灯光,风扇).
我会把字符串变成一个单词数组,或者使用str_tok,或者只是爆炸”.
现在你有一系列的单词从最后开始,然后向后寻找’状态’ – 开启或关闭.然后跟着那个向后寻找一个’东西’,最后是一个’地方’.如果你打到另一个状态,那么你可以重新开始.
让我尝试用伪代码做到这一点:
// array of words is inArray currentPlace = null; currentThing = null; currentState = null; for (i = (inArray.length - 1); i >= 0; i--) { word = inArray[i]; if (isstate(word)) { currentState = word; currentPlace = null; currentThing = null; } else if (currentState) { if (isThing(word)) { currentThing = word; currentPlace = null; } else if (currentThing) { if (isPlace(word)) { currentPlace = word // Apply currentState to currentThing in currentPlace } // skip non-place,thing or state word. } // Skip when we don't have a thing to go with our state } // Skip when we don't have a current state and we haven't found a state }
而且,写完之后,很明显它本应该使用状态机和切换语句 – 这表明我应该首先在纸上设计它.如果你变得复杂,你想使用状态机来实现逻辑 – 状态将是’lookingForState’,’lookingForThing’等
你也不需要currentPlace作为变量,但我会留下它,因为它使逻辑更清晰.
编辑
如果你想支持’在卧室里打开灯’,你需要调整逻辑(如果你没有东西,你需要保存’地方’).如果你还想支持“打开卧室的灯”,你还需要更进一步.
考虑一下,我想知道你是否可以这样做:
have a currentState variable and arrays for currentPlace and currentThing for each word if it's a state: store it in currentState if it's a thing,or place: add it to the approriate array if currentState is set and there is content in currentPlaces and currentThings: apply currentState to all currentThings in all currentPlaces
编辑2
好的,我测试了它,并且由于英语的结构方式存在一些问题.问题是如果你想支持’打开…’和’打开……’然后你需要使用我的第二个伪代码,但由于句子中的’和’,这不起作用.例如:
打开我的厨房灯,我的卧室和客厅的灯都熄灭了.
第一个和连接两个语句,第二个和连接到地方.正确的方法是到diagram the sentence找出适用于什么的方法.
有两个快速选项,首先您可以坚持使用不同的单词或短语来连接两个命令:
把我的厨房灯打开,然后把我的卧室和客厅的灯关掉.
打开我的厨房灯,我的卧室和客厅灯也关闭.
或者,这可能更容易,你可以坚持只有’Turn … off / on’形式的命令.这适用于我上面的第一个伪代码.
请注意,如果有任何标点符号等,您可能需要对字符串进行大量预处理.您可能还希望将“起居室”(以及类似的两个单词短语)替换为“livingroom”而不仅仅是匹配一句话,希望能像我一样做到最好.此外,代码可以简化一点,但我想保持它接近psuedocode示例.
编辑3
这会处理一些额外的句子,并且会更好地清理它,它仍然依赖于每个子句末尾的“状态”,因为它用作应用操作的触发器(此版本可能会向前读取而不是向后).此外,它不会处理如下:
Turn my kitchen fan and my bedroom lights on and living room lights off.
你必须做一些更复杂的事情来理解’厨房’和’扇子’和’卧室’和’灯’之间的关系.
只要输入/说出命令的人遵循一些基本规则,这些技术的某些组合可能足以做一些相当令人印象深刻的事情.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。