Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#集合-按元素排序(旋转)_C#_Collections - Fatal编程技术网

C#集合-按元素排序(旋转)

C#集合-按元素排序(旋转),c#,collections,C#,Collections,我有一个IEnumerable集合。假设它包含5个点(实际上更像2000) 我想对这个集合进行排序,这样集合中的一个特定点就成为第一个元素,所以它基本上是在一个特定点截断一个集合,然后将它们重新连接在一起 因此,我列出了5点: {0,0},{10,0},{10,10},{5,5},{0,10} 根据索引3处的元素重新排序将成为: {5,5},{0,10},{0,0},{10,0},{10,10} 解决这个问题的计算效率最高的方法是什么,或者是否有一种内置的方法已经存在。。。如果是这样,我似乎找不

我有一个
IEnumerable
集合。假设它包含5个点(实际上更像2000)

我想对这个集合进行排序,这样集合中的一个特定点就成为第一个元素,所以它基本上是在一个特定点截断一个集合,然后将它们重新连接在一起

因此,我列出了5点:

{0,0},{10,0},{10,10},{5,5},{0,10}

根据索引3处的元素重新排序将成为:

{5,5},{0,10},{0,0},{10,0},{10,10}

解决这个问题的计算效率最高的方法是什么,或者是否有一种内置的方法已经存在。。。如果是这样,我似乎找不到一个

在这种情况下,一个简单的数组拷贝是O(n),这对于几乎所有实际用途来说都足够好了。然而,在某些情况下——如果这是多层算法中的一部分——这可能是相关的。另外,您是否只需要以有序的方式迭代此集合,还是创建一个副本

var list = new[] { 1, 2, 3, 4, 5 };

var rotated = list.Skip(3).Concat(list.Take(3));

// rotated is now {4, 5, 1, 2, 3}
链表很容易像这样重新组织,尽管访问随机元素的成本更高。总的来说,计算效率还取决于您如何准确地访问此项集合(以及它们是什么类型的项—值类型还是引用类型?)

标准的.NET链表似乎不支持这种手动操作,但一般来说,如果您有一个链表,只需将新的“下一个”和“上一个”指针指定给端点,就可以按照您描述的方式轻松地在列表的各个部分移动

此处可用的集合库支持以下功能:。 具体地说,您正在寻找
LinkedList.Slide()
方法,您可以在
LinkedList.View()
返回的对象上使用该方法。在这种情况下,简单的数组副本是O(n),这对于几乎所有实际用途来说都足够了。然而,在某些情况下——如果这是多层算法中的一部分——这可能是相关的。另外,您是否只需要以有序的方式迭代此集合,还是创建一个副本

链表很容易像这样重新组织,尽管访问随机元素的成本更高。总的来说,计算效率还取决于您如何准确地访问此项集合(以及它们是什么类型的项—值类型还是引用类型?)

标准的.NET链表似乎不支持这种手动操作,但一般来说,如果您有一个链表,只需将新的“下一个”和“上一个”指针指定给端点,就可以按照您描述的方式轻松地在列表的各个部分移动

此处可用的集合库支持以下功能:。
具体地说,您正在寻找
LinkedList.Slide()
可用于
LinkedList.View()
返回的对象的方法ulrichb显示的Linq方法的另一种替代方法是使用队列类(fifo集合)对索引进行出列,并将您取出的文件排队。

ulrichb显示的Linq方法的另一种替代方法是使用队列类(fifo集合)将您的索引排队,并将您取出的文件排队。

版本未枚举
列表两次,但由于
T[]
,内存消耗更高:

public static IEnumerable<T> Rotate<T>(IEnumerable<T> source, int count)
{
    int i = 0;

    T[] temp = new T[count];

    foreach (var item in source)
    {
        if (i < count)
        {
            temp[i] = item;
        }
        else
        {
            yield return item;
        }

        i++;
    }

    foreach (var item in temp)
    {
        yield return item;
    }
}

[Test]
public void TestRotate()
{
    var list = new[] { 1, 2, 3, 4, 5 };

    var rotated = Rotate(list, 3);

    Assert.That(rotated, Is.EqualTo(new[] { 4, 5, 1, 2, 3 }));
}
公共静态IEnumerable旋转(IEnumerable源,int计数)
{
int i=0;
T[]温度=新的T[计数];
foreach(源中的var项)
{
如果(i

注意:添加参数检查。

版本不枚举
列表
两次,但由于
T[]
,内存消耗更高:

public static IEnumerable<T> Rotate<T>(IEnumerable<T> source, int count)
{
    int i = 0;

    T[] temp = new T[count];

    foreach (var item in source)
    {
        if (i < count)
        {
            temp[i] = item;
        }
        else
        {
            yield return item;
        }

        i++;
    }

    foreach (var item in temp)
    {
        yield return item;
    }
}

[Test]
public void TestRotate()
{
    var list = new[] { 1, 2, 3, 4, 5 };

    var rotated = Rotate(list, 3);

    Assert.That(rotated, Is.EqualTo(new[] { 4, 5, 1, 2, 3 }));
}
公共静态IEnumerable旋转(IEnumerable源,int计数)
{
int i=0;
T[]温度=新的T[计数];
foreach(源中的var项)
{
如果(i

注意:添加参数检查。

使用linq的简单实现是:

IEnumerable x = new[] { 1, 2, 3, 4 };
var tail = x.TakeWhile(i => i != 3);
var head = x.SkipWhile(i => i != 3);
var combined = head.Concat(tail); // is now 3, 4, 1, 2
这里发生的事情是,为了得到组合序列中的第一个元素,需要执行两次比较。 该解决方案可读性强,结构紧凑,但效率不高。
其他贡献者描述的解决方案可能更有效,因为他们使用特殊的数据结构作为数组或列表。

使用linq的简单实现是:

IEnumerable x = new[] { 1, 2, 3, 4 };
var tail = x.TakeWhile(i => i != 3);
var head = x.SkipWhile(i => i != 3);
var combined = head.Concat(tail); // is now 3, 4, 1, 2
这里发生的事情是,为了得到组合序列中的第一个元素,需要执行两次比较。 该解决方案可读性强,结构紧凑,但效率不高。
其他参与者描述的解决方案可能更有效,因为他们使用特殊的数据结构作为数组或列表。

您可以编写一个用户定义的列表扩展,该扩展使用List.Reverse()进行旋转。我从C++标准模板库中提取了基本思想,基本上使用了三个步骤的反向:反向(第一,中间)反向(中间,最后)反向(第一,最后)

据我所知,这是最有效、最快的方法。我测试了10亿个元素,旋转(0,50000,800000)需要0.00097秒