如何根据搜索词的出现顺序、位置及匹配度对字符串列表进行排序
自定义搜索结果排序实现方案
调整思路
原逻辑仅统计了单一的匹配次数,无法满足多维度排序需求,我们改为给每个句子计算多组排序权重,按照需求优先级从高到低链式排序即可,具体调整点:
- 新增4个排序维度,按优先级从高到低依次为:
- 总匹配权重:精确全词匹配1次计2分,模糊子串匹配1次计1分,优先总权重更高的结果
- 顺序匹配度:匹配到的搜索词首次出现顺序和搜索顺序完全一致的优先
- 精确匹配数:相同权重下,全词精确匹配的搜索词数量越多越靠前
- 首现位置总和:所有匹配到的搜索词首次出现的索引加总越小,说明匹配词越靠前,优先级越高
- 替换原来的单值字典排序为C#多条件链式排序,调整更灵活
实现代码
using System.Text.RegularExpressions; // 辅助类,存储每个句子的排序权重 public class SentenceWeight { public string Content { get; set; } // 总匹配权重:精确2分/次,模糊1分/次 public int TotalMatchWeight { get; set; } // 精确匹配的搜索词数量 public int ExactMatchCount { get; set; } // 匹配到的词是否符合搜索词顺序 public bool IsMatchOrder { get; set; } // 匹配词首次出现位置总和,越小越靠前 public int FirstOccurSum { get; set; } } // 检查是否为精确全词匹配(大小写不敏感) private bool IsExactMatch(string sentence, string word) { string escapedWord = Regex.Escape(word); return Regex.IsMatch(sentence, $@"\b{escapedWord}\b", RegexOptions.IgnoreCase); } // 获取词在句子中首次出现的起始索引,找不到返回-1(大小写不敏感) private int GetFirstOccurrenceIndex(string sentence, string word) { return sentence.IndexOf(word, StringComparison.OrdinalIgnoreCase); } // 检查匹配到的搜索词是否符合给定的搜索顺序 private bool CheckMatchOrder(string sentence, string[] searchWords) { int lastIndex = -1; foreach (var word in searchWords) { int currentIndex = GetFirstOccurrenceIndex(sentence, word); if (currentIndex == -1) continue; if (currentIndex < lastIndex) return false; lastIndex = currentIndex; } return true; } // 改造后的排序方法 private List<string> GetMyList(List<string> strLst) { var wrdList = new string[3] { "Realme", "phone", "LCD" }; var weightList = new List<SentenceWeight>(); foreach (string sentence in strLst) { var weight = new SentenceWeight { Content = sentence, IsMatchOrder = CheckMatchOrder(sentence, wrdList) }; foreach (var word in wrdList) { int firstIndex = GetFirstOccurrenceIndex(sentence, word); if (firstIndex == -1) continue; weight.FirstOccurSum += firstIndex; if (IsExactMatch(sentence, word)) { weight.TotalMatchWeight += 2; weight.ExactMatchCount += 1; } else { weight.TotalMatchWeight += 1; } } weightList.Add(weight); } // 按优先级多条件排序 return weightList .OrderByDescending(w => w.TotalMatchWeight) .ThenByDescending(w => w.IsMatchOrder) .ThenByDescending(w => w.ExactMatchCount) .ThenBy(w => w.FirstOccurSum) .Select(w => w.Content) .ToList(); }
以上代码运行你给出的示例输入,输出结果和预期完全一致,如果后续需要调整排序优先级,仅需要调整OrderByDescending/ThenBy的顺序即可。
内容的提问来源于stack exchange,提问作者Tech Learner
相关产品推荐
相关产品推荐

