如何实现函数:替换起始字符串占位词生成全组合句子数组?
实现思路与代码示例
核心思路
本质是生成所有占位词替换项的笛卡尔积,再将每个组合替换回原句子。可以通过递归或迭代逐步扩展组合:
- 先提取句子中所有唯一的占位词(避免重复处理)
- 建立占位词与对应替换列表的映射,方便快速查找
- 从原始句子出发,依次对每个占位词,将当前所有字符串的该占位词替换为所有可能的选项,生成新的组合数组,直到所有占位词处理完毕
代码实现(递归版)
function generateAllCombinations(sentence, swaps) { // 提取所有唯一占位词(去掉前后的|) const placeholders = [...new Set( sentence.match(/\|([^\|]+)\|/g).map(match => match.slice(1, -1)) )]; // 转成占位词->替换列表的映射对象 const swapMap = Object.fromEntries( swaps.map(item => [item.name, item.replacements]) ); // 递归函数:处理第index个占位词,currentSentences是当前已生成的字符串数组 function recurse(index, currentSentences) { // 所有占位词处理完成,返回结果 if (index === placeholders.length) return currentSentences; const placeholder = placeholders[index]; const replacements = swapMap[placeholder]; const newSentences = []; // 遍历当前所有字符串,替换当前占位词的所有可能值 for (const str of currentSentences) { for (const replacement of replacements) { newSentences.push( str.replace(new RegExp(`\\|${placeholder}\\|`, 'g'), replacement) ); } } // 递归处理下一个占位词 return recurse(index + 1, newSentences); } // 初始状态:只有原始句子 return recurse(0, [sentence]); } // 测试示例 const swaps = [ {name: "animal", replacements: ["cat", "dog", "rabbit"]}, {name: "location", replacements: ["the park", "bed with a cold", "the back seat of the car"]}, {name: "man", replacements: ["Pete", "Tom", "Robert"]} ]; const sentence = "I saw |man| in |location| with his pet |animal|."; console.log(generateAllCombinations(sentence, swaps));
代码实现(迭代版,更直观)
如果觉得递归不好理解,也可以用循环逐步扩展组合:
function generateAllCombinations(sentence, swaps) { const placeholders = [...new Set( sentence.match(/\|([^\|]+)\|/g).map(match => match.slice(1, -1)) )]; const swapMap = Object.fromEntries( swaps.map(item => [item.name, item.replacements]) ); // 初始组合:只有原始句子 let combinations = [sentence]; // 逐个处理每个占位词 for (const placeholder of placeholders) { const replacements = swapMap[placeholder]; const temp = []; // 对当前每个组合字符串,替换当前占位词的所有可能值 for (const str of combinations) { for (const replacement of replacements) { temp.push(str.replace(new RegExp(`\\|${placeholder}\\|`, 'g'), replacement)); } } // 更新组合数组为新生成的结果 combinations = temp; } return combinations; }
关键说明
- 正则
/\|([^\|]+)\|/g用于匹配所有|xxx|格式的占位词,slice(1, -1)去掉前后的|得到占位词名称 - 使用
new Set去重,避免重复处理同一个多次出现的占位词(比如句子里多次写|man|,只会处理一次) - 替换时用
new RegExp(\|${placeholder}\|, 'g')确保替换所有出现的该占位词,而不是只替换第一个
内容的提问来源于stack exchange,提问作者GeorgePorge
相关产品推荐
相关产品推荐

