我需要检查字符串是否由数组中给出的任何字符串组合形成 例如:我们有一些[" for"," car"," keys"," forth"]和一串&#34 ;如果字符串是" forthcarxykeys",则结果应为false,因为xy不在数组中。数组中的单词顺序无关紧要。 没有必要匹配数组中的所有字符串,但测试字符串应该只由数组中的任何字符串组成。如果它包含除数组中的字符串以外的任何字符串,则返回false
我的方法:
var str = "forthcarkeys";
var arr = ["for","car","keys","forth"];
for(var i=0;i<arr.length;i++)
{
if(str.indexOf(arr[i]) !== -1)
{
str.replace(arr[i],"");
}
}
if(str !== "")
{
console.log("yes");
} else
{
console.log("no");
}
但这种方法效率低下且失败。
答案 0 :(得分:2)
一种可能的方法是检查每个前缀是否可以使用输入字符串表示。
我们的想法是,如果我们可以轻松计算长度为 i 的前缀是否可以用输入字符串表示,如果我们已经有这些信息用于更短的前缀(这可以通过检查是否任何允许的字符串都会导致更短的可表达前缀) - 请参阅下面的代码。
var str = "forthcarkeys";
var arr = ["for","car","keys","forth"];
// isPossible[i] indicates whether we can express the
// prefix str.substring(0, i) using strings in arr.
var isPossible = Array(str.length + 1).fill(false);
// it is always possible to construct the empty string
isPossible[0] = true;
// consider each prefix of str, from shortest to longest
for (var i = 1; i <= str.length; i++) {
// try to reach this prefix using an allowed string s_allowed,
// by appending s_allowed to a shorter prefix
for (var j = 0; j < arr.length; j++) {
// "start" is the position where the current string
// would need to be appended
start = i - arr[j].length;
if (start >= 0 && isPossible[start]) {
if (str.substring(start, i) == arr[j]) {
isPossible[i] = true;
// we break the loop over j, because we already found a
// solution to express the current prefix str.substring(0,i)
break;
}
}
}
}
for (var i = 1; i <= str.length; i++) {
console.log(str.substring(0, i) + " - " + isPossible[i] + "\n")
}
if (isPossible[str.length]) {
console.log("yes");
} else {
console.log("no");
}
&#13;
要进一步详细说明其工作原理,请考虑一个较小的示例:
此处描述的方法按照其长度的递增顺序测试str的所有前缀:
步骤0:空前缀 - 这被认为总是很好(可以使用0个字符串表示)。
第1步:前缀&#34; a&#34;:
我们尝试使用较短的前缀+一个允许的字符串来获取此前缀。为此,我们遍历允许的字符串:
第2步:前缀&#34; ab&#34;:
我们尝试使用较短的前缀+一个允许的字符串来获取此前缀。为此,我们遍历允许的字符串:
第3步:前缀&#34; abc&#34;:
我们尝试使用较短的前缀+一个允许的字符串来获取此前缀。为此,我们遍历允许的字符串:
我们耗尽了所有允许的字符串,因此前缀&#34; abc&#34;无法表达使用允许的字符串。
第4步:前缀&#34; abcd&#34; (整个字符串):
我们尝试使用较短的前缀+一个允许的字符串来获取此前缀。为此,我们遍历允许的字符串:
因此,我们得到前缀&#34; abcd&#34; (对应于整个字符串)可以使用输入字符串表示。
答案 1 :(得分:0)
如果sort
的条件为Dec
,则需要yes
数组str==""
订单
function check(str){
var arr = ["for", "car", "keys", "forth"];
arr= arr.sort((a,b)=> b.length-a.length) // sort with length dec order
console.log(arr) //longest length string is first then to lower length
for (var i = 0; i < arr.length; i++) {
str = str.replace(arr[i], "");
}
if (str.trim()== "") { //empty
console.log("yes");
} else {
console.log("no");
}
}
check("forthcarkeys")
check("forthcarxykeys")
答案 2 :(得分:0)
如果首先匹配所有单词,则可以在开始时省略不出现的单词。然后,如果匹配是在字符串中出现的顺序,则可以使用递归来查找匹配后的所有匹配项:
function eval(str, wordList = ["for","car","keys","forth", "the"]){ //note, added 'the' for testing
if(!str)return false; //empty string -> false
const words = wordList.map(w=> ({word:w, index: str.indexOf(w)})) //map all words with their occurence index inside the string
.filter(w=>w.index !== -1) //get rid of non occuring words alltogether
.sort((w1,w2) => w1.index - w2.index); //sort by index of occurence
const check = (arr,ind) => {
if(ind>=str.length)return ind === str.length; //end of string reached -> match if exactly at end (false if greater than)
let w;
while(arr.length){
[w,...arr] = arr; //destructure: w = next word (index 0), arr is set to the remaining elements
if(w.index > ind) return false; //gap since last match -> no match
if(w.index===ind && check(arr,ind + w.word.length)) //if match is at the expected index, check the next indices
return true; //word started at the 'current' index and remaining words match as well
//if code arrives here, try further with next word (while)
}
return false;
};
return check(words,0); //start recursive function with all words at string index 0
}
//test
function test(str, words){
console.log(str,':', eval(str, words));
}
test("forthcarkeys");
test("forthcarxykeys");
test("forthecar");
test("abcdef",[ "abc", "def", "abcd" ]);
&#13;
答案 3 :(得分:0)
您可以进行扩展尝试并搜索每个单词,并使用临时结果集过滤掉单词是否在字符串中。
function check(string, array) {
function fork(i, t) {
var s = t.slice(), j;
if (i === possibilities.length) {
result.push(t.join(''));
return;
}
if (possibilities[i].word.split('').every(function (c, j) { return s[j + possibilities[i].position] !== ''; })) {
for (j = 0; j < possibilities[i].word.length; j++) {
s[j + possibilities[i].position] = ''
}
}
fork(i + 1, s);
fork(i + 1, t);
}
var possibilities = array.reduce(function (r, a) {
var p = string.indexOf(a);
while (p !== -1) {
r.push({ word: a, position: p });
p = string.indexOf(a, p + 1);
}
return r;
}, []),
result = [];
console.log(possibilities);
fork(0, string.split(''));
console.log(result);
return result.some(function (a) { return !a; });
}
console.log(check("forthcarkeyboardingfor", ["for", "car", "key", "forth", "keyboard", "boarding"])); // true
console.log(check("forthxycarkeyboardingfor", ["for", "car", "key", "forth", "keyboard", "boarding"])); // false
.as-console-wrapper { max-height: 100% !important; top: 0; }
上述版本,提前退出。
function check(string, array) {
function fork(i, t) {
var s = t.slice(), j;
if (i === possibilities.length) {
return !t.join('');
}
if (possibilities[i].word.split('').every(function (c, j) { return s[j + possibilities[i].position] !== ''; })) {
for (j = 0; j < possibilities[i].word.length; j++) {
s[j + possibilities[i].position] = '';
}
}
return fork(i + 1, s) || fork(i + 1, t);
}
var possibilities = array.reduce(function (r, a) {
var p = string.indexOf(a);
while (p !== -1) {
r.push({ word: a, position: p });
p = string.indexOf(a, p + 1);
}
return r;
}, []);
return fork(0, string.split(''));
}
console.log(check("forthcarkeyboardingfor", ["for", "car", "key", "forth", "keyboard", "boarding"])); // true
console.log(check("forthxycarkeyboardingfor", ["for", "car", "key", "forth", "keyboard", "boarding"])); // false
答案 4 :(得分:0)
这是一个更强大的函数,可以找到用于组成它的所有可能元素和方法。如果结果的长度为零,则无法从池中生成原始文本。
function decompose(orignal, pool) { // recurisve function to find combinations of text
var results = [];
for (var element of pool) { // for each element in pool
if (orignal == element) { // resursive base case, stop when orignal == element
results.push([element]); // * add solution
} else {
if (orignal.indexOf(element) == 0) { // if original text starts with element
var remaining = orignal.slice(element.length); // ready remaining text to be scanned
var subresults = decompose(remaining, pool); // recursive call: findCombinationsOf remaining
for (subresult of subresults) {
results.push([element].concat(subresult)); // * add solution
}
}
}
}
return results;
}
console.log(JSON.stringify(decompose("forthcarkeys", ["for","car","keys","forth"])));
console.log(JSON.stringify(decompose("forthcarkeys", ["for","car","keys","forth", "th"])));
console.log(JSON.stringify(decompose("nowaydude!", ["for","car","keys","forth", "th"])));
答案 5 :(得分:0)
这是我的解决方案
详细说明:
"forthcarxykeys"
转换为数组并将其分配给变量chars
["for","car","keys","forth"]
"for"
)true
数组中将其标记为char
chars
中的所有值都为true,则返回true,否则返回false。JS:
// arr = ["for", "car", "keys", "forth"];
// str = "forthcarxykeys";
function check(arr, str) {
let chars = str.split('');
for (let i = 0; i < arr.length; i++) {
let word = arr[i];
let index = str.indexOf(word);
let wordExists = index !== -1;
if (wordExists) {
let endIndex = index + word.length;
for (index; index < endIndex; index++) {
chars[index] = true;
}
}
}
return chars.every(i => i === true);
}
答案 6 :(得分:-1)
这是更新的代码。字符串替换不起作用,因此使用正则表达式来实现这一点。 var re = new RegExp(arr[i], 'g');
function check(str, arr) {
var flag = true;
for (var i = 0; i < arr.length; i++) {
if (str.indexOf(arr[i]) === -1) {
flag = false;
}
}
if (!flag) {
console.log("Some keys didn't matched.");
} else {
console.log("Nothing remains. All matched.");
}
}
var str = "forcarxy";
var arr = ["for", "car", "keys", "forth"];
check(str, arr);
var arr = ["abcd", "def", "abc"];
var str = "abcdef";
check(str, arr);
var arr = [ "abcd", "cdef" ];
var str = "abcdef";
check(str, arr);
var str = "aabc";
var arr = ["a", "bc"];
check(str, arr);
&#13;
代码已更新,以考虑@inetphantom
的评论案例