查找列表中的项目在一行中重复多少次的最佳方法,以C#为单位?

查找列表中的项目在一行中重复多少次的最佳方法,以C#为单位?,c#,list,iteration,C#,List,Iteration,给出一个列表,例如: List}=newlist(){1,1,1,3,3,4,4,1,1,8,8,5,6,7,7,8} 以C#为单位,找出一个项目在一行中重复多少次的最佳/最快/最有效的方法是什么? 对于这个列表,我要查找的结果如下所示: 1*3 3*2 4*2 1*2 8*3 5*1 6*1 7*4 8*2 不必使用这种奇怪的乘法格式,我认为它更容易理解 我一直在尝试循环浏览列表,并将每个项目与下一个项目进行比较,但我不可避免地陷入困境,不知道该怎么办。我只会循环浏览列表,并查看每个项目的当前

给出一个列表,例如:
List}=newlist(){1,1,1,3,3,4,4,1,1,8,8,5,6,7,7,8}

以C#为单位,找出一个项目在一行中重复多少次的最佳/最快/最有效的方法是什么? 对于这个列表,我要查找的结果如下所示:

1*3

3*2

4*2

1*2

8*3

5*1

6*1

7*4

8*2

不必使用这种奇怪的乘法格式,我认为它更容易理解


我一直在尝试循环浏览列表,并将每个项目与下一个项目进行比较,但我不可避免地陷入困境,不知道该怎么办。

我只会循环浏览列表,并查看每个项目的当前项目是否与上一个项目相同。如果是,则递增一个count变量并继续。如果不是,则捕获上一个项目和计数,并将上一个项目重置为当前项目,计数重置为
1

使之更容易的一种方法是创建一个简单的类,该类包含一个
和一个
计数
,这样我们就可以返回代表列表中项目的列表:

public class Item<T>
{
    public T Value { get; set; }
    public int Count  { get; set; }

    public override string ToString()
    {
        return $"{Value} * {Count}";
    }
}
公共类项目
{
公共T值{get;set;}
公共整数计数{get;set;}
公共重写字符串ToString()
{
返回$“{Value}*{Count}”;
}
}
然后,我们可以编写一个通用方法,使用开头提到的策略接收列表并返回上面类的列表:

public static List<Item<T>> GetItemCounts<T>(List<T> input)
{
    if (input == null) return null;
    var itemCounts = new List<Item<T>>();
    Item<T> currentItem = null;

    foreach (var item in input)
    {
        // If we haven't set an item yet, do so
        if (currentItem == null)
        {
            currentItem = new Item<T> {Value = item, Count = 1};
        }
        // If the current item is the same as this item, increment the count
        else if (currentItem.Value.Equals(item))
        {
            currentItem.Count++;
        }
        // This is a new item, so save the current item and create a new one
        else
        {
            itemCounts.Add(currentItem);
            currentItem = new Item<T> { Value = item, Count = 1 };
        }
    }

    // Add the last item
    if (currentItem != null) itemCounts.Add(currentItem);

    return itemCounts;
}
公共静态列表GetItemCounts(列表输入)
{
if(input==null)返回null;
var itemCounts=新列表();
Item currentItem=null;
foreach(输入中的变量项)
{
//如果我们还没有设置项目,请这样做
如果(currentItem==null)
{
currentItem=新项{值=项,计数=1};
}
//如果当前项目与此项目相同,则增加计数
else if(currentItem.Value.Equals(item))
{
currentItem.Count++;
}
//这是一个新项目,请保存当前项目并创建一个新项目
其他的
{
itemCounts.Add(当前项);
currentItem=新项{值=项,计数=1};
}
}
//添加最后一项
如果(currentItem!=null)itemCounts.Add(currentItem);
返回项目计数;
}
现在,使用您的示例输入,我们可以使用上述方法获得结果:

public static void Main(string[] args)
{
    var items = new List<int> {1, 1, 1, 3, 3, 4, 4, 1, 1, 8, 8, 8, 5, 6, 7, 7, 7, 7, 8, 8};

    // Get our item counts and output them to the console window
    GetItemCounts(items).ForEach(Console.WriteLine);

    GetKeyFromUser("\nDone! Press any key to exit...");
}
publicstaticvoidmain(字符串[]args)
{
变量项=新列表{1,1,1,3,3,4,4,1,1,8,8,5,6,7,7,7,7,8};
//获取项目计数并将其输出到控制台窗口
GetItemCounts(items.ForEach(Console.WriteLine);
GetKeyFromUser(“\n完成!按任意键退出…”);
}
输出


这里有一个有效的算法

想法是这样的;在列表中迭代,直到到达倒数第二个项目,在每次迭代中查看当前项目是否与下一个项目相同。如果是,则增加
repeat
变量,该变量初始化为
1
。否则,打印当前项目的计数并重置
重复

var numbers = new List<int>() { 1, 1, 1, 3, 3, 4, 4, 1, 1, 8, 8, 8, 5, 6, 7, 7, 7, 7, 8, 8, 7 };

var repeat = 1;
for (int i = 0; i < numbers.Count - 1; i++)
{
    if (numbers[i] == numbers[i + 1])
    {
        repeat++;
    }
    else
    {
        Console.WriteLine("{0} * {1}", numbers[i], repeat);
        repeat = 1;
    }

    if (i == numbers.Count - 2)
    {
        if (numbers[i] == numbers[i + 1])
        {
            Console.WriteLine("{0} * {1}", numbers[i], repeat);
        }
        else
        {
            Console.WriteLine("{0} * {1}", numbers[i + 1], 1);
        }
    }
}
var numbers=newlist(){1,1,1,3,3,4,4,1,1,8,8,5,6,7,7,7};
var-repeat=1;
对于(int i=0;i

结尾处的附加
if
用于处理最后一项的特殊情况。由于循环只迭代到倒数第二个项,因此我们需要单独检查最后一个项。

尝试在整个集合的一个循环中执行此操作。一个
列表
,您可以在其中使用数字作为索引,或者进行计数。或者一本
字典可以很容易地做到这一点。为了您所珍视的一切,请不要只给变量命名
。因此,您已经实例化了列表。。。迭代和跟踪计数的尝试在哪里?你能告诉我们你的代码的这一部分吗?告诉我们你的循环尝试,这样我们就可以修复它。你要求“最好的”、“最快的”和“最有效的”,但这些不一定是同一件事。给出一个衡量“最佳性”和“效率”的指标,记住我们经常用,比如说,更糟糕的内存使用来换取更快的速度。哇。谢谢你的详细解释,尽管我的措辞平淡无奇!这很有帮助!