C#统计列表中的连续重复项<;字符串>;
我有一个字符串列表,希望计算其中的重复项,以便稍后处理此信息。简单地计算重复项是非常容易的,但不幸的是,我只想计算连续的重复项 假设我们有一个列表,其中包含以下字符串项: “1A”、“3B”、“5X”、“7Q”、“2W”、“2G”、“2J”、“1A”、“2A” 现在我想数一数这个列表中的重复项我只看每个字符串的第一个字符,可以忽略字符串中的其他字符强> 我们得到的是2x“1%”和3x“2%”,我实际上想要得到的是连续的重复,所以我的结果应该是3x“2%”。必须忽略2x“1A”,因为它们不是一排。 (=席位持有人) 我编写了一段代码,在列表中循环,并将一个字符串与下一个字符串进行比较C#统计列表中的连续重复项<;字符串>;,c#,performance,list,duplicates,C#,Performance,List,Duplicates,我有一个字符串列表,希望计算其中的重复项,以便稍后处理此信息。简单地计算重复项是非常容易的,但不幸的是,我只想计算连续的重复项 假设我们有一个列表,其中包含以下字符串项: “1A”、“3B”、“5X”、“7Q”、“2W”、“2G”、“2J”、“1A”、“2A” 现在我想数一数这个列表中的重复项我只看每个字符串的第一个字符,可以忽略字符串中的其他字符 我们得到的是2x“1%”和3x“2%”,我实际上想要得到的是连续的重复,所以我的结果应该是3x“2%”。必须忽略2x“1A”,因为它们不是一排。 (
int counter = 0;
for (int i = 0; i < list.Count; i++)
{
char first = list[i][0];
if ((i + 1) == list.Count) break;
char second = list[(i + 1)][0];
if (first == second)
{
counter++;
}
}
我想实现的第二个特性是,列表中“重复计数”超过4的非重复项将被删除。如果没有一个“重复计数”或长度超过4的重复行,我想返回
例如:
“1A”、“1B”、“5X”、“3Q”、“1J”、“1I”
重复计数==4,因此返回
“1A”、“1B”、“1X”、“3Q”、“1J”、“1I”
重复count==5
,保存这五项,删除列表中的任何其他项
“1A”、“1B”、“1X”、“3Q”、“1I”、“1Z”、“1Z”
重复计数==6,保存这六项,删除列表中的任何其他项
注意:
每个字符串的第一个字符很重要。输入列表将有7个项目,而不是或多或少的单个项目。没有结果列表,必须更新旧的结果列表。如果重复计数小于或等于4,则没有工作要做,只需返回即可。
一行中的副本不会超过5个。我必须检查数以十亿计的列表,因此性能非常重要
由于德国学校没有更好的英语教学,我希望任何人都能理解我的问题所在,并愿意帮助我
这不是任何家庭作业的一部分。您可以在这里使用一种方法,该方法能够在满足条件时对连续项目进行分组:
public static IEnumerable<IEnumerable<T>> GroupWhile<T>(
this IEnumerable<T> source, Func<T, T, bool> predicate)
{
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
yield break;
List<T> list = new List<T>() { iterator.Current };
T previous = iterator.Current;
while (iterator.MoveNext())
{
if (!predicate(previous, iterator.Current))
{
yield return list;
list = new List<T>();
}
list.Add(iterator.Current);
previous = iterator.Current;
}
yield return list;
}
}
我建议您将列表中以相同字符开头的项目分组。此分组的结果将是一个
列表
。这使得与团队合作更加容易
var list = new List<string> {
"1A", "3B", "5X", "7Q", "2W", "2G", "2J", "1B", "1C", "1D", "1E"
};
var groups = new List<List<string>>();
char lastChar = (char)0; // We assume that NUL will never be used as first char.
List<string> group = null;
foreach (string s in list) {
if (s[0] != lastChar) {
group = new List<string>();
groups.Add(group);
lastChar = s[0];
}
group.Add(s);
}
// Join the first and the last group if their first char is equal
int lastIndex = groups.Count - 1;
if (groups.Count > 2 && groups[0][0][0] == groups[lastIndex][0][0]) {
// Insert the elements of the last group to the first group
groups[0].InsertRange(0, groups[lastIndex]);
// and delete the last group
groups.RemoveAt(lastIndex);
}
//TODO: Remove test
foreach (List<string> g in groups) {
Console.WriteLine(g[0][0]);
foreach (string s in g) {
Console.WriteLine(" " + s);
}
}
// Now create a list with items of groups having more than 4 duplicates
var result = new List<string>();
foreach (List<string> g in groups) {
if (g.Count > 4) {
result.AddRange(g);
}
}
//TODO: Remove test
Console.WriteLine("--------");
foreach (string s in result) {
Console.Write(s);
Console.Write(" ");
}
Console.WriteLine();
Console.ReadKey();
var list=新列表{
“1A”、“3B”、“5X”、“7Q”、“2W”、“2G”、“2J”、“1B”、“1C”、“1D”、“1E”
};
变量组=新列表();
char lastChar=(char)0;//我们假设NUL永远不会用作第一个字符。
列表组=空;
foreach(列表中的字符串s){
如果(s[0]!=lastChar){
组=新列表();
组。添加(组);
lastChar=s[0];
}
组。添加(s);
}
//如果第一个字符相等,则加入第一个和最后一个组
int lastIndex=groups.Count-1;
如果(groups.Count>2&&groups[0][0][0]==groups[lastIndex][0][0]){
//将最后一个组的元素插入第一个组
组[0]。InsertRange(0,组[lastIndex]);
//并删除最后一组
组。RemoveAt(lastIndex);
}
//TODO:删除测试
foreach(分组列出g){
Console.WriteLine(g[0][0]);
foreach(g中的字符串s){
控制台写入线(“+s”);
}
}
//现在创建一个列表,其中包含超过4个重复项的组项
var result=新列表();
foreach(分组列出g){
如果(g.计数>4){
结果:添加范围(g);
}
}
//TODO:删除测试
控制台写入线(“----------”);
foreach(结果中的字符串s){
控制台。写入;
控制台。写(“”);
}
Console.WriteLine();
Console.ReadKey();
您实际上没有问任何问题。使用“一行”实际上是指连续的重复?更改我的代码或提供任何输入的最佳方式是什么?您将如何处理该问题;)“一行中”的意思是连续的,是的。我不能简单地像var query=list.GroupWhile((prev,current)=>prev[0]==current[0])。其中(group=>group.Count()>1)。选择(group=>new{Character=group.First()[0],Count=group.Count(),});我想我忽略了这个问题obvious@user3868224你为什么不能呢?小小的改变对我来说很有用,谢谢!一次跑步需要大约0.00003-0.00004秒,足够快。
var query = data.GroupWhile((prev, current) => prev[0] == current[0])
.Where(group => group.Count() > 1)
.Select(group => new
{
Character = group.First()[0],
Count = group.Count(),
});
var list = new List<string> {
"1A", "3B", "5X", "7Q", "2W", "2G", "2J", "1B", "1C", "1D", "1E"
};
var groups = new List<List<string>>();
char lastChar = (char)0; // We assume that NUL will never be used as first char.
List<string> group = null;
foreach (string s in list) {
if (s[0] != lastChar) {
group = new List<string>();
groups.Add(group);
lastChar = s[0];
}
group.Add(s);
}
// Join the first and the last group if their first char is equal
int lastIndex = groups.Count - 1;
if (groups.Count > 2 && groups[0][0][0] == groups[lastIndex][0][0]) {
// Insert the elements of the last group to the first group
groups[0].InsertRange(0, groups[lastIndex]);
// and delete the last group
groups.RemoveAt(lastIndex);
}
//TODO: Remove test
foreach (List<string> g in groups) {
Console.WriteLine(g[0][0]);
foreach (string s in g) {
Console.WriteLine(" " + s);
}
}
// Now create a list with items of groups having more than 4 duplicates
var result = new List<string>();
foreach (List<string> g in groups) {
if (g.Count > 4) {
result.AddRange(g);
}
}
//TODO: Remove test
Console.WriteLine("--------");
foreach (string s in result) {
Console.Write(s);
Console.Write(" ");
}
Console.WriteLine();
Console.ReadKey();