按KeyValuePair分组列表值

3
说我有一个列表
[1,2,2,1,3,3,3,2,3,3,1,3,3,2,3]

enter image description here

有什么想法可以将它们 (List<KeyValuePair<int, int>>) 分组,使得键是下一个最小数字,值是下一个最大数字,并且如果重复出现,则与相同的最小键分组,如果这样说有意义的话...

我要寻找的输出如下:

[Key, Value]
[0,1]
[0,2]
[3,4]
[3,5]
[3,6]
[7,8]
[7,9]
[10,11]
[10,12]
[13,14]

4
你目前已经尝试过什么了吗? - Yuval Itzchakov
你可以使用 SortedList<int,List<int>>。当你需要输出时,只需遍历所有键(不要忘记在开始迭代之前使用 List.Sort 方法进行排序)。如果你想要的话,我可以轻松地分享一段代码片段。 - Nissim
foreach循环,然后使用if语句检查当前索引的+1或-1偏移量。如果左侧或右侧存在超过2个相同的数字,则无法正常工作。我尝试为每个索引运行while循环以查找最小值和最大值,但我很难理解这一点。 - wtz
4个回答

1
    private static void foo()
    {
        SortedList<int, List<int>> collection = new SortedList<int, List<int>>();
        Random rnd = new Random();

        // Filling the collection with random keys/values:
        for (int i = 0; i < 100; i++)
        {
            int key = rnd.Next(0, 10);
            if (!collection.ContainsKey(key))
                collection.Add(key, new List<int>());
            for (int j = 0; j < 10; j++)
            {
                int value = rnd.Next(0, 1000);
                collection[key].Add(value);
            }
        }

        // Displaying all pairs:
        foreach (var key in collection.Keys)
        {
            collection[key].Sort();
            for (int j = 0; j < collection[key].Count; j++)
                Console.WriteLine(string.Format("[{0},{1}]", key, collection[key][j]));
        }
    }

1
根据图片和示例输入:
       var list = new List<int> { 1, 2, 2, 1, 3, 3, 3, 2, 3, 3, 1, 3, 3, 2, 3}; //example input

        var results = new List<KeyValuePair<int, int>>();
        int key = 0;
        for (int i = 0; i < list.Count; i++)
        {
            if(i==0 || list[i] < list[i - 1])                
                key = i++; //assign key and proceed to next index (NB no index out of range checking)                
            results.Add(new KeyValuePair<int, int>(key, i));
        }

这里使用了与前一个元素的直接比较,将索引用作键,数值用作示例输出中的值。如果键值始终小于前一个元素(如您所述),则可以使用以下代码替换if语句:if(i==0 || list[i] < list[i - 1])编辑,将Tuple更改为KeyValuePair。

你说得对,关键值总是比前一个元素小。谢谢你。这样可以工作 :) - wtz

1

试试这个

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> input = new List<int>() { 1, 2, 2, 1, 3, 3, 3, 2, 3, 3, 1, 3, 3, 2, 3 };
            int previous = 0;
            int keyIndex = 0;
            Dictionary<int, List<int>> dict = new Dictionary<int, List<int>>();
            for (int i = 0; i < input.Count; i++)
            {
                if (i == 0)
                {
                    keyIndex = 0;
                }
                else
                {
                    if (input[i] < previous)
                    {
                        keyIndex = i;
                    }
                    else
                    {
                        if (dict.ContainsKey(keyIndex))
                        {
                            dict[keyIndex].Add(i);
                        }
                        else
                        {
                            dict.Add(keyIndex, new List<int>(){ i});
                        }
                    }
                }
                previous = input[i];
            }

            foreach (int dictKey in dict.Keys)
            {
                var l = dict[dictKey];

                Console.WriteLine("Key:{0}, values={1}", dictKey, string.Join(",", dict[dictKey].Select(x => x.ToString()).ToArray()));
            }
            Console.ReadLine();

        }
    }
}
​

1

我希望它能解决你的问题

public void GetPairs()
{
     List<int> list = new List<int>() { 1,3,3,2,3,3,1,3,4,1 };

     List<KeyValuePair<int, int>> kvapar = new List<KeyValuePair<int, int>>();
     int prev = 0, firstIndex = 0, lastIndex = 0;
     foreach (int i in list)
     {
          if (i < prev)
          {
              kvapar.AddRange(GetRange(list.GetRange(firstIndex, lastIndex)));
              firstIndex += lastIndex; lastIndex = 0;
          }
          prev = i; lastIndex++;
     }
} 
public List<KeyValuePair<int, int>> GetRange(List<int> list)
{
       List<KeyValuePair<int, int>> result = new List<KeyValuePair<int, int>>();
       foreach(int i in list)
       {
           if (list.IndexOf(i) == 0) continue;
           result.Add(new KeyValuePair<int, int>(list[0], i));
       }
           return result;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接