/// <summary> /// 排序去除Top N /// </summary> /// <typeparam name="valueType">排序数据类型</typeparam> /// <param name="values">待排序数组</param> /// <param name="comparer">排序比较器</param> /// <param name="count">排序数据数量</param> /// <returns>排序后的数据</returns> private static valueType[] getRemoveTop <valueType>(this valueType[] values, Func <valueType, valueType, int> comparer, int count) { valueType[] newValues = new valueType[count]; count = values.Length - count; uint sqrtMod; int length = Math.Min(Math.Max(count << 2, count + (int)NumberExtension.sqrt((uint)values.Length, out sqrtMod)), values.Length); valueType[] removeValues = new valueType[length]; int readIndex = values.Length - length, copyCount = length - count, removeIndex = copyCount, writeIndex = copyCount; Array.Copy(values, readIndex, removeValues, 0, length); AutoCSer.Algorithm.RangeQuickSort.Sorter <valueType> sort = new AutoCSer.Algorithm.RangeQuickSort.Sorter <valueType> { Array = removeValues, Comparer = comparer, SkipCount = copyCount, GetEndIndex = copyCount }; sort.Sort(0, --length); Array.Copy(removeValues, 0, newValues, 0, copyCount); for (valueType maxValue = removeValues[copyCount]; readIndex != 0;) { if (comparer(values[--readIndex], maxValue) <= 0) { newValues[writeIndex++] = values[readIndex]; } else { removeValues[--removeIndex] = values[readIndex]; if (removeIndex == 0) { sort.Sort(0, length); removeIndex = copyCount; maxValue = removeValues[copyCount]; Array.Copy(removeValues, 0, newValues, writeIndex, copyCount); writeIndex += copyCount; } } } if (removeIndex != copyCount) { sort.Sort(removeIndex, length); Array.Copy(removeValues, removeIndex, newValues, writeIndex, copyCount - removeIndex); } return(newValues); }
/// <summary> /// 排序取Top N /// </summary> /// <typeparam name="valueType">排序数据类型</typeparam> /// <param name="values">待排序数组</param> /// <param name="comparer">排序比较器</param> /// <param name="count">排序数据数量</param> /// <returns>排序后的数据</returns> private static SubArray <valueType> getTop <valueType>(this valueType[] values, Func <valueType, valueType, int> comparer, int count) { uint sqrtMod; int length = Math.Min(Math.Max(count << 2, count + (int)NumberExtension.sqrt((uint)values.Length, out sqrtMod)), values.Length); valueType[] newValues = new valueType[length]; int readIndex = values.Length - length, writeIndex = count; Array.Copy(values, readIndex, newValues, 0, length); AutoCSer.Algorithm.RangeQuickSort.Sorter <valueType> sort = new AutoCSer.Algorithm.RangeQuickSort.Sorter <valueType> { Array = newValues, Comparer = comparer, SkipCount = count - 1, GetEndIndex = count - 1 }; sort.Sort(0, --length); for (valueType maxValue = newValues[sort.GetEndIndex]; readIndex != 0;) { if (comparer(values[--readIndex], maxValue) < 0) { newValues[writeIndex] = values[readIndex]; if (writeIndex == length) { sort.Sort(0, length); writeIndex = count; maxValue = newValues[sort.GetEndIndex]; } else { ++writeIndex; } } } if (writeIndex != count) { sort.Sort(0, writeIndex - 1); } if (AutoCSer.DynamicArray <valueType> .IsClearArray) { Array.Clear(newValues, count, newValues.Length - count); } return(new SubArray <valueType>(0, count, newValues)); }