2012-12-28 93 views
-3

我有一个列表(我可以实现它作为任何类型的集合给出了一个简洁的解决方案)是这样的:排序列表,忽略每个第n个元素?

4,1,5,2,1,3,8,1,6,4,2,3 

列表实际上是3个值的组,它的长度将永远是3的倍数。组的前2个值和组的第3个值之间没有关系。

我想对数组进行排序,使每个第三个值都留在原地。对于我给出的示例,结果将为:

1,1,5,1,2,3,2,4,6,4,8,3 

索引为0,1,3,4,6和7的元素已排序。索引2,5和8的元素尚未排序。另一种表达方式是想象列表是x,x,y,x,x,y,x,x,y,x,x,y,而我只想排序xs。

我可以写一个算法,但不知道是否有简洁的方法来做到这一点?

+1

这可能更适合代码审查(在你建议/写一个算法后)。 –

+0

@flem我明白你的意思,但是SO的目的当然是学习和推进?编写算法是微不足道的。我的目的是寻求更简洁的方法。 – Simon

回答

2

除非你迫切渴望真正有效地做到这一点,我会去一个简单解决方案:

  • 提取要整理到一个新的列表
  • 排序列表
  • 元素
  • 要么建立一个新的列表,合并你想要排序的元素与固定的元素,或者(如果你喜欢使用可变集合),只需将排序的元素放回原始列表。

因此,像:

var list = ...; // Get hold of the whole list. 
var sortedElements = list.Where((value, index) => index % 3 != 2) 
         .OrderBy(x => x) 
         .ToList(); 
for (int i = 0; i < sortedElements.Count; i++) 
{ 
    int index = (i/2) * 3 + i % 2; 
    list[index] = sortedElements[i]; 
} 
+0

谢谢约翰。最初的评论(自删除以来)要求我“先告诉我你先做了什么”,并且我非常沮丧地开始编写算法。当我看到这个回应时,我正要进行测试,但现在我可以从2个fugly' for'循环中移出,然后建立2个列表然后重新合并,再到我正在寻找的更优雅的方法。再次感谢,我学到了一些东西,并有了一个新的工具! :) – Simon

0

我认为采取了每三个值,并保持它分开,然后进行排序的一切,再次插入值将最简单的。

numbers.Where((n, index) => (index + 1) % 3 == 0); 
numbers.Where((n, index) => (index + 1) % 3 != 0); 

这给出了thrid索引列表以及需要排序的内容。

1

尝试以下LINQ

var ints = new int[]{4,1,5,2,1,3,8,1,6,4,2,3}; 
var result = ints.Where((i,j) => j%3!= 2).OrderBy(i=>i).ToArray(); 

var index = ints.Select ((i , j)=> 
    { 
     if (j%3==2) 
      return i; 
     else 
      return result[(j/3)*2 + j%3]; 
    }); 

工作原理
1.取排序后的数组忽略非必需值
2.从原始阵列准备输出阵列从排序后的数组每个三元组的第一2个值。

+0

谢谢。我希望我能接受2个答案。我喜欢在这里使用LINQ,但我认为John Skeet的解决方案更容易阅读(当然,有一天其他人将不得不阅读本文)。出于这个原因,我接受约翰的解决方案,并向你保证。再次感谢。 – Simon

+0

他是乔恩,而不是约翰。 upvote这个答案也。拥有多个答案总是很好的,这就是论坛的优点。 – Tilak

相关问题