Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.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#_Arrays - Fatal编程技术网

C# 数组按大小重新缩放整数

C# 数组按大小重新缩放整数,c#,arrays,C#,Arrays,我有一个整数数组,如果我想按大小对它们进行排序,我想更改它们的位置值,目前我正在这样做: var result = { 5,4,6,12,1,0 }; var order = new int[result.Length]; for (int i = 0; i < order.Length; i++) { order[i] = i; } Array.Sort(result,order); for (int i = 0; i < result.Length; i++) {

我有一个整数数组,如果我想按大小对它们进行排序,我想更改它们的位置值,目前我正在这样做:

var result = { 5,4,6,12,1,0 };

var order = new int[result.Length];

for (int i = 0; i < order.Length; i++)
{
    order[i] = i;
}
Array.Sort(result,order);

for (int i = 0; i < result.Length; i++)
{
    result[i] = i;
}

Array.Sort(order, result);
//output: result = { 3,2,4,5,1,0 }
var result={5,4,6,12,1,0};
变量顺序=新整数[result.Length];
for(int i=0;i
但根据VisualStudio的评测,我不仅觉得这非常低效,而且这些排序占用了我80%的CPU时间。
我怎样才能使它更快

您可以计算每个项目存在多少较低的值:

int[] r = result.Select(n => result.Count(x => x < n)).ToArray();
int[]r=result.Select(n=>result.Count(x=>x
或:

int[]r=newint[result.Length];
for(变量i=0;i

这实际上效率的高低取决于有多少数据。这是一个O(n*n)解决方案,因此如果阵列很长,它的效率就不会那么高。

这是一个使用LINQ编写的简单解决方案:

var input = new int[] { 5, 4, 6, 12, 1, 0 };
var result = from n in input
             let order = input.OrderBy(k => k).ToList()
             select order.IndexOf(n);

请注意,实际上,副本将具有相同的结果索引。我不知道它是否符合您的需要(但我怀疑在输入序列中不可能重复)。

仅对数组排序一次+它在集合中循环(仅)3次。如果收集量很大,这一点很重要。如果多个值具有相同的值,则它知道原始位置

var items = new[] { 5, 4, 6, 12, 1, 0 };

var combinations = items.Select((value, originalindex) => new { value, originalindex });
var sortedCombination = combinations.OrderBy(c => c.value);
var sortedCombinationWithIndex =
    sortedCombination.Select((combination, sortedIndex) => new {combination, sortedIndex});
var result = new int[items.Length]; 
foreach (var item in sortedCombinationWithIndex)
{
    result[item.combination.originalindex] = item.sortedIndex;
}
在您可以简单调用的方法中重写:

public int[] SortIndexes<T>(T[] source) where T : IComparable<T>
{
    var combinations = source.Select((value, originalindex) => new { value, originalindex });
    var sortedCombination = combinations.OrderBy(c => c.value);
    var sortedCombinationWithIndex =
        sortedCombination.Select((combination, sortedIndex) => new { combination, sortedIndex });
    var result = new int[source.Length];
    foreach (var item in sortedCombinationWithIndex)
    {
        result[item.combination.originalindex] = item.sortedIndex;
    }
    return result;
} 
public int[]SortIndexes(T[]source),其中T:IComparable
{
var combines=source.Select((value,originalindex)=>new{value,originalindex});
var sortedcomposition=combines.OrderBy(c=>c.value);
var分类与索引组合=
选择((组合,sortedIndex)=>new{combination,sortedIndex});
var result=newint[source.Length];
foreach(分类组合与索引中的var项)
{
结果[item.composition.originalindex]=item.sortedIndex;
}
返回结果;
} 
这个怎么样:

var order = Enumerable.Range( 0, results.Length ).OrderBy( i => results[i] ).ToArray();
这将为您提供一个数组,以便在不修改结果数组的情况下按顺序打印
结果
数组:

foreach( var index in order ) 
{
    Console.WriteLine( results[index] );
}
编辑: 如前所述,上述方法不能提供预期的结果。但是,它确实提供了结果的“反向”,因此很容易将其正确映射:

var order = Enumerable.Range( 0, results.Length ).OrderBy( i => results[i] ).ToArray();
var indices = new int[results.Length];
for( int i = 0; i < results.Length; ++i )
{
    indices[order[i]] = i;
}
// The indices array now holds the index that each item in the results array 
// would end up at if sorted
var order=Enumerable.Range(0,results.Length).OrderBy(i=>results[i]).ToArray();
var指数=新整数[results.Length];
对于(int i=0;i
对于初学者来说,根据输入大小选择正确的算法总是会带来好处。我不确定
Array.Sort
是否会这样做,很可能不会

例如:如果处理3-4个元素,则使用您自己的
插入排序/hardcoded if语句的实现将更快

其次,如果处理多个元素(~10000),如果并行化QuickSort,则可以轻松地将
Array.Sort
的性能提高50%。尽管如此,请参见
ParallelExtensions
,您并不是同时处理那么多的元素

问题最终归结为分类问题。使用LINQ/OrderBy的任何解决方案都不太可能击败本机
数组。在整数数组上排序
。.NET framework几乎没有将速度降低2倍的聪明优化

为了将算法改进2倍,只需排序一次

以下假设键的范围为0..1000:

int[] _indexArray = new int[1001];

public void AbitBetterImplementation(int[] array)
{
   int[] copy = array.ToArray();

   for(var i = 0; i < array.Length; i++){
        var elem = array[i];
        _indexArray[elem] = i;
    }

   Array.Sort(copy);

   for(var i = 0; i < copy.Length; i++){
     var oldIndex = _indexArray[copy[i]];
     array[oldIndex] = i;
   }

}

使用哈希树数组@TimSchmelter:我们的目标不是排序,而是获取该项在排序后的索引。例如,第一个项目得到索引3,因为它是第四个最小的值。@Guffa正是我想要的,我就是找不到描述它的词为什么要花这么多时间?您是在为大型阵列执行此操作吗?或者你经常这样做?把事情放在上下文中,我是为旅行推销员问题的遗传算法解决方案。这些阵列是两个基因组组合后访问城市的顺序。索引之间的差异是由于对父代基因组进行了转换,因此它们不会重叠。它为每一个新的孩子做一次,这在计算大量的世代、人口和城市时经常发生。令人惊讶的是,它没有更快地工作(在我的默认参数为100个城市的情况下,它花费的时间是我的两倍),即使是非常短的3号数组(长50%),也不可能在我的输入序列中重复。这个答案和Guffa的答案一样,无论是短数组还是长数组,都需要两倍的时间。我怀疑LINQ的额外开销不是helping@Meoiswa不,这不是LINQ的错,这是排序的错。我没有正确阅读您的初始解决方案,这显然更有效。这并没有给出预期的结果。(即使Enmerable.Range有正确数量的参数)。啊,我误解了期望的结果是什么。我的方法应该能够获得期望的结果,但是只需要很少的修改。我将编辑以添加它。我提出了一个类似的解决方案(未发布)。我没有测试您的特定代码,但我的代码对于“小”数组(大约80个元素以下)仍然较慢。对于较小的数组,速度稍快一些,对于较大的数组,速度稍快一些。忘记添加了,在执行并行处理时,速度略快于我的版本。没有它,它的速度大约是基准测试的两倍
int[] _indexArray = new int[1001];

public void AbitBetterImplementation(int[] array)
{
   int[] copy = array.ToArray();

   for(var i = 0; i < array.Length; i++){
        var elem = array[i];
        _indexArray[elem] = i;
    }

   Array.Sort(copy);

   for(var i = 0; i < copy.Length; i++){
     var oldIndex = _indexArray[copy[i]];
     array[oldIndex] = i;
   }

}
Basic implementation Time Elapsed 183,2125 ms
A bit better implementation Time Elapsed 99,4912 ms