如何通过比较字符串出现的位置来对字符串列表进行排序?
Posted
技术标签:
【中文标题】如何通过比较字符串出现的位置来对字符串列表进行排序?【英文标题】:How to sort list of strings by comparing position of a string occurrence? 【发布时间】:2021-11-15 01:58:50 【问题描述】:我有一个句子列表,可以与数组中的另一组单词进行比较。如果它包含数组中的任何单词,我可以将我的数组与列表进行比较并获得匹配的句子。
而且我还可以通过获取单词计数出现的数组来对列表进行降序排序。
例如:
List<string> sourceList = new List<string>()
"Realme smartphone has super Amoled screen with 4GB RAM capacity.",
"Realme smartphone has LCD screen with 4GB RAM capacity.",
"Realme phone has LCD screen with 6GB RAM capacity.",
"Realme phone has LED screen with 6GB RAM capacity.",
"Realme has smartphone with super Amoled screen with 4GB RAM and 4GB extended memory capacity",
"Realme has LCD phone with 6GB RAM capacity."
;
searchStr = new string[3] "Realme", "phone", "LCD" ;
预期的排序列表:
List<string> sortedList = new List<string>()
"Realme phone has LCD screen with 6GB RAM capacity.",
"Realme smartphone has LCD screen with 4GB RAM capacity.",
"Realme has LCD phone with 6GB RAM capacity.",
"Realme phone has LED screen with 6GB RAM capacity.",
"Realme smartphone has super Amoled screen with 4GB RAM capacity.",
"Realme has smartphone with super Amoled screen with 4GB RAM and 4GB extended memory capacity"
;
预期输出的原因是:
第一句包含“Realme”、“phone”、“LCD”中的所有 3 个确切单词 顺序相同。 第二句包含“Realme”、“phone”、“LCD”中的所有 3 个单词 相同的顺序。(即,智能手机包含手机)。 第三句包含所有 3 个单词,但顺序不准确。 第四句包含 2 个完全相同的单词,顺序相同。 第 5 句按顺序包含 2 个单词,但不是完全准确的单词。 第六句包含 2 个单词,但搜索词“电话”出现在 句子中的第三个位置。排序优先级为:
-
单词出现次数。
字序准确。
单词出现位置。
单词完全匹配。
部分单词匹配。
此外,如果单词在一个句子中出现多次,则该计数应被视为最高优先级。
我有获取计数的代码:
private List<string> GetMyList(List<string> strLst)
List<string> rslLst = new List<string>();
Dictionary<string, int> dctList = new Dictionary<string, int>();
var wrdList = new string[3] "Realme", "phone", "LCD" ;
int wrdCount = wrdList.Count();
foreach (string str in strLst)
int i = 0;
foreach (string wrd in wrdList)
var x = str.ToString().Trim().ToLower().Contains(wrd.Trim().ToLower());
if (x)
i = i + CountWordUniqueOccurrences(str.ToLower(), wrd.ToLower());
dctList.Add(str, i);
dctList = dctList.OrderByDescending(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
Dictionary<string, int>.KeyCollection keys = dctList.Keys;
foreach (var key in keys)
rslLst.Add(key);
return rslLst;
private int CountWordUniqueOccurrences(string text, string pattern)
int count = 0;
if(text.Contains(pattern))
count++;
return count;
谁能帮我找出实现这一目标的逻辑。
【问题讨论】:
你有 4 个问题需要解决:1) 计算一个单词在字符串中的出现次数,2) 找到单词在字符串中的位置,3) 找到“单词顺序的准确顺序。” (无论这意味着什么)和 4)按该顺序排序的值。你解决了这些吗?你被什么困住了? @DStanley - 我已经解决了计算字符串中单词出现次数的问题。使用 DictionaryOrderBy(s => SortOrder(s, searchStr)
) 中调用该函数。您甚至可以让该函数调用每个排序标准的子函数 (if (StringContainsWordsInOrder(s, searchStr))
)。我的观点是将问题分解为更小的子问题,然后将它们组合在一起以获得完整的解决方案。
我认为您对整个单词与部分匹配的匹配具有第四优先级。因此,匹配“我是手机”的“手机”在排序中高于“我是智能手机”。
@DStanley - 我已经更新了我的代码。你能帮我弄清楚逻辑吗?
【参考方案1】:
这里有一些开始:
using System;
using System.Collections.Generic;
using System.Linq;
List<string> sourceList = new List<string>()
"Realme smartphone has super Amoled screen with 4GB RAM capacity.",
"Realme smartphone has LCD screen with 4GB RAM capacity.",
"Realme phone has LCD screen with 6GB RAM capacity.",
"Realme phone has LED screen with 6GB RAM capacity.",
"Realme has smartphone with super Amoled screen with 4GB RAM and 4GB extended memory capacity",
"Realme has LCD phone with 6GB RAM capacity."
;
var searchStr = new string[3] "Realme", "phone", "LCD" ;
// We use Linq to order the list. The most important criteria comes first.
var result = sourceList
.OrderByDescending(CountWords(searchStr))
.ThenByDescending(CountOrderedWords(searchStr))
.ThenByDescending(CountExactWords(searchStr));
// Counts how many of the search terms appear in the string
Func<string, int> CountWords(params string[] terms) => s => terms.Count(t => s.Contains(t));
// Counts how many words appear after each other
Func<string, int> CountOrderedWords(params string[] terms) => s =>
var i = 0;
var score = 0;
foreach(var t in terms)
i = s.IndexOf(t, i);
if (i < 0) break;
score++;
return score;
;
// Counts how many words match exactly (you may want to update the word delimeters)
Func<string, int> CountExactWords(params string[] terms) =>
s => terms.Count(t => s.Split(' ', '.', ',').Contains(t));
但是,您的任务的语义对我来说不是很清楚,此外,这不是编码服务。所以剩下的就留给你们自己解决吧。如果遇到新问题,您仍然可以提出其他问题。
这是我玩过的 dotnet fiddle,也许你会觉得它有用:https://dotnetfiddle.net/NOBAgT
【讨论】:
这给了我一些随机的结果集。不像预期的那样。 你得到什么结果?它应该不是随机的。正如我所写的,我没有包括你所有的规则。不过,我很乐意帮助您进一步改进它。以上是关于如何通过比较字符串出现的位置来对字符串列表进行排序?的主要内容,如果未能解决你的问题,请参考以下文章