CMake如何高效查找列表中的所有重复条目?
在CMake中高效找出列表中的重复条目
CMake本身没有内置的一键命令直接找出所有重复列表项,但可以通过模拟哈希表跟踪元素出现情况的方式,实现只遍历一次原列表、无需创建大量子列表的高效方案,比你当前的方法更简洁高效。
核心思路
利用CMake的set集合记录已遍历过的元素,同时用变量名模拟哈希表,存储每个元素对应的所有出现索引。只需要遍历原列表一次,即可收集所有重复项及其位置:
- 用一个
SEEN_ELEMENTS集合跟踪已处理过的元素; - 遍历原列表的每个元素,记录当前索引;
- 若元素未见过,就将其加入集合,并初始化存储该元素索引的变量;
- 若元素已见过,就将当前索引追加到对应变量的索引列表中;
- 最后遍历所有元素的索引列表,筛选出出现次数≥2的条目,即为重复项。
完整示例代码
# 示例大列表(替换为你的实际列表) set(MY_BIG_LIST "foo" "bar" "baz" "foo" "qux" "bar" "foo" "corge") # 初始化跟踪变量 set(SEEN_ELEMENTS "") set(DUPLICATE_RESULTS "") # 获取列表长度,遍历所有索引 list(LENGTH MY_BIG_LIST LIST_LENGTH) math(EXPR LAST_IDX "${LIST_LENGTH} - 1") foreach(IDX RANGE 0 ${LAST_IDX}) list(GET MY_BIG_LIST ${IDX} CURRENT_ITEM) if(CURRENT_ITEM IN_LIST SEEN_ELEMENTS) # 元素已存在,追加当前索引到对应列表 list(APPEND "ITEM_INDEXES_${CURRENT_ITEM}" ${IDX}) else() # 首次出现,标记为已见并初始化索引列表 list(APPEND SEEN_ELEMENTS ${CURRENT_ITEM}) set("ITEM_INDEXES_${CURRENT_ITEM}" "${IDX}") endif() endforeach() # 整理重复项结果 foreach(ITEM IN LISTS SEEN_ELEMENTS) list(LENGTH "ITEM_INDEXES_${ITEM}" INDEX_COUNT) if(INDEX_COUNT GREATER 1) # 拼接所有出现索引 string(JOIN ", " INDEX_STR "${ITEM_INDEXES_${ITEM}}") list(APPEND DUPLICATE_RESULTS "${ITEM}: 出现于索引 ${INDEX_STR}") endif() endforeach() # 输出结果 if(DUPLICATE_RESULTS) message(STATUS "检测到重复条目:") foreach(RESULT IN LISTS DUPLICATE_RESULTS) message(STATUS " ${RESULT}") endforeach() else() message(STATUS "列表中无重复条目") endif()
相比你当前方法的优势
- 无需创建子列表:全程只遍历原列表一次,避免了数千次子列表生成的性能开销;
- 直接统计出现次数与位置:通过索引列表可以直接获取元素的所有出现位置,解决
list FIND只能找首次的局限; - 逻辑更简洁:利用
IN_LIST替代list FIND,代码可读性更高。
补充说明
CMake的列表操作确实偏向基础,没有原生的哈希表或统计类命令,但这种模拟哈希表的方式已经是处理此类问题的最优实践之一,在处理数千条目的列表时,性能会明显优于你当前的子列表查找方案。
内容的提问来源于stack exchange,提问作者arnschi
相关产品推荐
相关产品推荐

