如何实现字符顺序无关的字符串比较,修复Bash变位词生成程序问题
问题根因
现有代码使用的=~正则匹配逻辑仅能判断输入字符串按顺序包含目标字典单词的所有字符,无法识别字符顺序不同的变位组合,比如rats的字符可拼出tar,但tar的字符顺序与rats不一致,就会被现有逻辑漏掉。
核心解决思路
变位词的通用判断逻辑基于字符排序:将两个字符串的所有字符按字母顺序排序后,若候选单词的排序结果是输入单词排序结果的子序列,且候选单词长度在2到输入单词长度之间,就符合要求。
具体实现步骤:
- 对输入单词的字符统一转小写后排序,得到基准排序字符串
- 遍历字典时先过滤长度不符合要求的候选单词
- 对候选单词做同样的转小写、排序处理
- 判断排序后的候选字符串是否为基准排序字符串的子序列,符合条件则输出
修正后可运行的Bash代码
#! /usr/bin/bash echo "I installed wamerican for an american english dictionary, as linux.words wasn't present on my system." input=$1 # 输入转小写、字符排序生成基准串 sorted_input=$(echo -n "$input" | tr '[:upper:]' '[:lower:]' | grep -o . | sort | tr -d '\n') if [[ -z "$input" || ${#input} -gt 4 ]]; then echo "Usage: anagram.sh <word to anagram, 4 characters or less>" exit 1 fi # 遍历字典处理每一个单词 cat /etc/dictionaries-common/words | tr '[:upper:]' '[:lower:]' | while read -r line; do line_len=${#line} # 长度不符合直接跳过 if [[ $line_len -lt 2 || $line_len -gt ${#input} ]]; then continue fi # 候选单词排序 sorted_line=$(echo -n "$line" | grep -o . | sort | tr -d '\n') # 生成子序列匹配规则:候选每个字符间加.*匹配任意间隔字符 pattern=$(sed 's/./&.*/g' <<< "$sorted_line") # 匹配成功则输出原单词 if [[ $sorted_input =~ $pattern ]]; then echo "$line" fi done
效果验证
输入rats时,输入排序后得到arst,候选单词tar排序后为art,生成的匹配规则为a.*r.*t,可匹配arst;候选单词sat排序后为ast,生成的匹配规则为a.*s.*t,也可匹配arst,所有符合要求的变位词都会被正常输出。
内容的提问来源于stack exchange,提问作者komsire22
相关产品推荐
相关产品推荐

