NodeJS环境下基于名称数组生成无重复单词的唯一名称
基于名称数组生成全信息无重复唯一名称的实现方法
需求概述
给定由多个字符串类型的名称组成的数组,生成可覆盖数组全部有效信息的唯一名称,要求名称中不存在重复单词,禁止使用直接选取数组最长元素的简单逻辑。
输入示例
[ 'Xiaomi Mi', 'Xiaomi', 'Mi', 'TV', 'Stick', 'Xiaomi Mi TV Stick', 'Xiaomi Mi TV', 'Mi TV Stick', 'Mi TV', 'TV Stick', 'Reproductor', 'Reproductor Multimedia', 'Multimedia' ]
期望输出
'Xiaomi Mi TV Stick, Reproductor Multimedia'
实现思路
- 分词与共现关系统计:先将所有输入字符串按空格拆分得到单词全集,统计每个单词的出现频次,同时记录单词之间的共现关系(即两个单词是否同时出现在同一个输入字符串中)。
- 独立词组聚类:基于共现关系对单词进行聚类,互相存在共现关系的单词会被归为同一个聚类,无共现关系的单词会被拆分到不同聚类。示例中
Xiaomi、Mi、TV、Stick属于同一个聚类,Reproductor、Multimedia属于另一个独立聚类。 - 聚类内语序还原:对每个聚类,匹配输入数组中覆盖该聚类所有单词的最长字符串,直接复用该字符串的语序,保证命名符合常规表达逻辑。
- 多聚类结果拼接:将不同聚类的结果用分隔符拼接,得到最终的唯一名称,确保所有有效信息都被覆盖,且无重复单词。
该方案完全规避了直接取最长元素的问题:如果直接取全局最长字符串,只能得到
Xiaomi Mi TV Stick,会漏掉另一组独立的Reproductor Multimedia相关信息。
代码实现(Python)
from collections import defaultdict def generate_unique_name(name_list): # 统计单词共现关系 co_occur = defaultdict(set) all_words = set() for name in name_list: words = name.split() for w in words: all_words.add(w) for other_w in words: if w != other_w: co_occur[w].add(other_w) # 对单词进行聚类 clusters = [] visited = set() for word in all_words: if word not in visited: cluster = set() stack = [word] visited.add(word) while stack: cur = stack.pop() cluster.add(cur) for neighbor in co_occur.get(cur, set()): if neighbor not in visited: visited.add(neighbor) stack.append(neighbor) clusters.append(cluster) # 生成每个聚类的完整名称 result_parts = [] for cluster in clusters: max_len = -1 best_match = "" for name in name_list: name_words = name.split() if set(name_words).issubset(cluster) and len(name_words) > max_len: max_len = len(name_words) best_match = name result_parts.append(best_match) return ", ".join(result_parts) # 测试示例 input_arr = [ 'Xiaomi Mi', 'Xiaomi', 'Mi', 'TV', 'Stick', 'Xiaomi Mi TV Stick', 'Xiaomi Mi TV', 'Mi TV Stick', 'Mi TV', 'TV Stick', 'Reproductor', 'Reproductor Multimedia', 'Multimedia' ] print(generate_unique_name(input_arr)) # 输出结果:Xiaomi Mi TV Stick, Reproductor Multimedia
内容的提问来源于stack exchange,提问作者rmartrenado
相关产品推荐
相关产品推荐

