数组搜索和切片
Array searching and slicing
给定仅包含数字的字符串 nums
和数字数组 predefinedNumbers
,我必须基于 nums
构造一个新字符串,但冒号之间的每个数字都有成为来自预定义数字和 return 所有可能性的有效数字。
示例输入:
nums = "143163421154143"
predefinedNumbers = ["21154", "143", "21154143", "1634", "163421154"]
期望的输出:
[ ":143:1634:21154:143:", ":143:163421154:143:", ":143:1634:21154143:" ]
到目前为止,我尝试了这段代码,但它不是我需要的结果,我一直在尝试了解如何递归地检查它:
let nums = "143163421154143";
predefinedNumbers = ["21154", "143", "21154143", "1634", "163421154"];
let newArray=[];
function makeNumSentences (nums, predefinedNumbers) {
predefinedNumbers.map(item => {
if (nums.includes(item)) {
newArray.push(item)
}
})
console.log(newArray.join(':'));
};
makeNumSentences("143163421154143",["21154", "143", "21154143", "1634", "163421154"])
非常感谢任何提示。
请注意,如果 nums
不仅仅由 predefinedNumbers
组成,循环将永远不会结束。
const nums = "143163421154143";
const predefinedNumbers = ["21154", "143", "21154143", "1634", "163421154"];
const result = [];
function makeNumSentences(nums) {
check([], nums);
console.log(result);
};
function check(array, nums) {
predefinedNumbers.forEach(e => {
if (nums.startsWith(e)) {
const newArray = array.concat(e);
const newNums = nums.slice(e.length);
if (newNums) { check(newArray, newNums); }
else { result.push(newArray.join(':')); }
}
});
}
makeNumSentences(nums);
首先,请阅读How do I ask and answer homework questions?。
虽然已经有一个可接受的答案,但我将只展示另一种方法。元素是数字这一事实是没有意义的。同样的技术适用于任何字符串。 (有数学技巧可以找到正确的值,但它们会很快溢出正常数字,而且由于无论如何输出都需要是一个字符串,所以似乎没有必要去追求它们。)
递归地考虑这个问题,我们可以把它分成两部分。我的哪些预定义值出现在目标字符串的开头?对于其中的每一个,我如何对字符串的其余部分执行相同的操作?递归需要一个基本情况,我们可以说如果目标字符串为空,那么我们可以 return 一个空字符串。
我们可以这样实现:
const make = (target, sources) =>
target .length == 0
? [[]]
: sources .filter (s => target .startsWith (s))
.flatMap (s => make (target .slice (s .length), sources) .map (r => [s, ...r]))
const makeNumSentences = (target, parts) =>
make (target, parts) .map (r => `:${r.join(':')}:`)
const nums = "143163421154143"
const predefinedNumbers = ["21154", "143", "21154143", "1634", "163421154"]
console .log (makeNumSentences (nums, predefinedNumbers))
请注意主要递归函数的细分,其中 return 是来自我们源 ([["143", "1634", "21154", "143"], ["143", "1634", "21154143"], ["143", "163421154", "143"]]
) 的元素数组的数组,以及将它们组合成输出格式的包装器。 ([":143:1634:21154:143:", ":143:1634:21154143:", ":143:163421154:143:"]
)。在我看来,这是工作的适当分解。数组很好用,我们可以用它们做更多的事情。但这不是唯一的方法。我们可以直接将其更改为 return 字符串:
const make = (target, sources) =>
target .length == 0
? ['']
: sources
.filter (s => target .startsWith (s))
.flatMap (s => make (target .slice (s .length), sources) .map (r => `:${s}${r}` + (r ? '' : ':')))
const nums = "143163421154143"
const predefinedNumbers = ["21154", "143", "21154143", "1634", "163421154"]
console .log (make (nums, predefinedNumbers))
请注意,这里在构建字符串时还有一些额外的复杂性。这是因为尾随“:
”。我们只想在现有字符串为空时在第一步添加它。 (我们总是添加领先的。)
给定仅包含数字的字符串 nums
和数字数组 predefinedNumbers
,我必须基于 nums
构造一个新字符串,但冒号之间的每个数字都有成为来自预定义数字和 return 所有可能性的有效数字。
示例输入:
nums = "143163421154143"
predefinedNumbers = ["21154", "143", "21154143", "1634", "163421154"]
期望的输出:
[ ":143:1634:21154:143:", ":143:163421154:143:", ":143:1634:21154143:" ]
到目前为止,我尝试了这段代码,但它不是我需要的结果,我一直在尝试了解如何递归地检查它:
let nums = "143163421154143";
predefinedNumbers = ["21154", "143", "21154143", "1634", "163421154"];
let newArray=[];
function makeNumSentences (nums, predefinedNumbers) {
predefinedNumbers.map(item => {
if (nums.includes(item)) {
newArray.push(item)
}
})
console.log(newArray.join(':'));
};
makeNumSentences("143163421154143",["21154", "143", "21154143", "1634", "163421154"])
非常感谢任何提示。
请注意,如果 nums
不仅仅由 predefinedNumbers
组成,循环将永远不会结束。
const nums = "143163421154143";
const predefinedNumbers = ["21154", "143", "21154143", "1634", "163421154"];
const result = [];
function makeNumSentences(nums) {
check([], nums);
console.log(result);
};
function check(array, nums) {
predefinedNumbers.forEach(e => {
if (nums.startsWith(e)) {
const newArray = array.concat(e);
const newNums = nums.slice(e.length);
if (newNums) { check(newArray, newNums); }
else { result.push(newArray.join(':')); }
}
});
}
makeNumSentences(nums);
首先,请阅读How do I ask and answer homework questions?。
虽然已经有一个可接受的答案,但我将只展示另一种方法。元素是数字这一事实是没有意义的。同样的技术适用于任何字符串。 (有数学技巧可以找到正确的值,但它们会很快溢出正常数字,而且由于无论如何输出都需要是一个字符串,所以似乎没有必要去追求它们。)
递归地考虑这个问题,我们可以把它分成两部分。我的哪些预定义值出现在目标字符串的开头?对于其中的每一个,我如何对字符串的其余部分执行相同的操作?递归需要一个基本情况,我们可以说如果目标字符串为空,那么我们可以 return 一个空字符串。
我们可以这样实现:
const make = (target, sources) =>
target .length == 0
? [[]]
: sources .filter (s => target .startsWith (s))
.flatMap (s => make (target .slice (s .length), sources) .map (r => [s, ...r]))
const makeNumSentences = (target, parts) =>
make (target, parts) .map (r => `:${r.join(':')}:`)
const nums = "143163421154143"
const predefinedNumbers = ["21154", "143", "21154143", "1634", "163421154"]
console .log (makeNumSentences (nums, predefinedNumbers))
请注意主要递归函数的细分,其中 return 是来自我们源 ([["143", "1634", "21154", "143"], ["143", "1634", "21154143"], ["143", "163421154", "143"]]
) 的元素数组的数组,以及将它们组合成输出格式的包装器。 ([":143:1634:21154:143:", ":143:1634:21154143:", ":143:163421154:143:"]
)。在我看来,这是工作的适当分解。数组很好用,我们可以用它们做更多的事情。但这不是唯一的方法。我们可以直接将其更改为 return 字符串:
const make = (target, sources) =>
target .length == 0
? ['']
: sources
.filter (s => target .startsWith (s))
.flatMap (s => make (target .slice (s .length), sources) .map (r => `:${s}${r}` + (r ? '' : ':')))
const nums = "143163421154143"
const predefinedNumbers = ["21154", "143", "21154143", "1634", "163421154"]
console .log (make (nums, predefinedNumbers))
请注意,这里在构建字符串时还有一些额外的复杂性。这是因为尾随“:
”。我们只想在现有字符串为空时在第一步添加它。 (我们总是添加领先的。)