AlgorithmLib 1.0.7

dotnet add package AlgorithmLib --version 1.0.7
                    
NuGet\Install-Package AlgorithmLib -Version 1.0.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AlgorithmLib" Version="1.0.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AlgorithmLib" Version="1.0.7" />
                    
Directory.Packages.props
<PackageReference Include="AlgorithmLib" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AlgorithmLib --version 1.0.7
                    
#r "nuget: AlgorithmLib, 1.0.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AlgorithmLib@1.0.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AlgorithmLib&version=1.0.7
                    
Install as a Cake Addin
#tool nuget:?package=AlgorithmLib&version=1.0.7
                    
Install as a Cake Tool

AlgorithmLib

AlgorithmLib是一个包含了我的一些常用的算法的基于.NET Standard 2.0的帮助类库。目前包含的算法有:排列、组合、数值分摊、计算组合关系等。

使用

  1. nuget包引用
Install-Package AlgorithmLib
  1. 用之...

排列(Permutation)

一般地,从n个不同元素中取出m(m≤n)个元素,按照一定的顺序排成一列,叫做从n个元素中取出m个元素的一个排列。特别地,当m=n时,这个排列被称作全排列。

全排列(All Permutation)

int[] arr = new int[] { 1, 2, 3 };
PermutationHelper.Permutation(arr, res => {
    // ...
    return true;
});

res依次是:

1
2
3
1 2
1 3
2 1
2 3
3 2
3 1
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
3 1 2

指定排列结果元素个数

int[] arr = new int[] { 1, 2, 3 };
PermutationHelper.Permutation(arr, 2, res => {
    // ...
    return true;
});

res依次是:

1 2
1 3
2 1
2 3
3 2
3 1

指定排列结果元素个数范围

int[] arr = new int[] { 1, 2, 3, 4 };
PermutationHelper.Permutation(arr, 2, 4, res => {
    // ...
    return true;
});

res依次是:

1 2
1 3
...
4 3
4 1
1 2 3
1 2 4
...
4 1 3
4 1 2
1 2 3 4
1 2 4 3
...
4 1 3 2
4 1 2 3

中止

可以在回调函数中返回false来中止排列的执行:

int[] arr = new int[] { 1, 2, 3 };
PermutationHelper.Permutation(arr, res => {
    if(condition){
        return false;
    }
    return true;
});

组合(Combination)

从n个不同的元素中,任取m(m≤n)个元素为一组,叫作从n个不同元素中取出m个元素的一个组合。

指定取几个数

int[] arr = new int[] { 1, 2, 3 };
CombinationHelper.Combination(arr, 2, res => {
    // ...
    return true;
});

res依次是:

1, 2
1, 3
2, 3

指定取几个数到几个数

int[] arr = new int[] { 1, 2, 3, 4 };
CombinationHelper.Combination(arr, 2, 3, res => {
    SimplePrintArray(res);
    return true;
});

res依次是:

1, 2
1, 3
1, 4
2, 3
2, 4
3, 4
1, 2, 3
1, 2, 4
1, 3, 4
2, 3, 4

中止

与排列类似,在回调函数中返回false即可。

指定组合算法

目前提供了两种组合算法,分别是“标志选择法”和“回溯法”,默认是使用“标志选择法”,这种方法没用递归,而“回溯法'则用到了递归,两种方法效率差不多,在元素较多时,回溯法略快一些。下面是使用回溯法的例子:

CombinationHelper.Method = CombinationMethod.Backtrack;
int[] arr = new int[] { 1, 2, 3, 4 };
CombinationHelper.Combination(arr, 2, 3, res => {
    SimplePrintArray(res);
    return true;
});

res依次是:

3, 4
2, 4
2, 3
1, 4
1, 3
1, 2
2, 3, 4
1, 3, 4
1, 2, 4
1, 2, 3

请注意回溯法返回的组合的出现的先后次序与标志选择法正好是倒过来的。

数值比例分摊

就是把一个数字,按一定的比例,分成若干个数字,这若干个数字加起来,要严格等于原先的数字,这个算法主要是解决了小数运算的精度的问题,这在企业开发中用得非常多。下面是一些例子:

// 100按"1,1.2"比例分摊,保留两位小数
// 结果为:45.45, 54.55
NumberDivideHelper.Divide(100, new[] { 1m, 1.2m }, 2);

// 结果为:10, 0
NumberDivideHelper.Divide(10, new[] { 1m, 0m }, 2);

// 结果为:3.34, 3.33, 3.33
NumberDivideHelper.Divide(10, new[] { 3m, 3m, 3m }, 2);

// 结果为:4, 3, 3
NumberDivideHelper.Divide(10, new[] { 3m, 3m, 3m }, 0);

// 结果为:8, 2, 0
NumberDivideHelper.Divide(10, new[] { 5m, 1m, 0.1m }, 0);

// 结果为:8.3, 1.7, 0.2
NumberDivideHelper.Divide(10.1m, new[] { 5m, 1m, 0.1m }, 1);

组合关系

找出构成整体的碎片集

给出一个总数(整体),和一个数组(碎片),从这个数组中找到若干个数,使它们的和等于给出的总数。

int whole = 17;
int[] fragments = new int[] { 4, 4, 5, 5, 8, 2, 1, 9 };
int[] res = RelationshipHelper.FindFragments(whole, fragments);
// res为 [4, 4, 8, 1]

找出构成整体的碎片集(对象处理)

这是找出构成整体的碎片集的附加功能版本。在企业开发中,我们常常需要建立对应关系,即若干个碎片加起来等于整体,找到这种关系后把碎片对象的一个字段设置为整体的ID,以此建立对应关系。

/// <summary>
/// 明细对象(碎片)
/// </summary>
class BillLine {
    /// <summary>
    /// 明细ID
    /// </summary>
    public int LineId { get; set; }
    /// <summary>
    /// 明细值
    /// </summary>
    public int LineValue { get; set; }
    /// <summary>
    /// 所属主档ID(这是想要的结果)
    /// </summary>
    public int MasterId { get; set; }
}

/// <summary>
/// 主档对象(整体)
/// </summary>
class MasterBill {
    /// <summary>
    /// 主档ID
    /// </summary>
    public int MasterId { get; set; }
    /// <summary>
    /// 主档值
    /// </summary>
    public int MasterValue { get; set; }
}

BillLine[] detailList = new BillLine[] {
    new BillLine{LineId = 1001, LineValue = 16},
    new BillLine{LineId = 1002, LineValue = 11},
    new BillLine{LineId = 1003, LineValue = 13},
    new BillLine{LineId = 1008, LineValue = 28},
    new BillLine{LineId = 1009, LineValue = 28},
    new BillLine{LineId = 1010, LineValue = 28},
    new BillLine{LineId = 1011, LineValue = 28},
    new BillLine{LineId = 1012, LineValue = 28},
};

MasterBill[] masterList = new MasterBill[] {
    new MasterBill{MasterId = 2001, MasterValue = 80},
    new MasterBill{MasterId = 2002, MasterValue = 100}
};

RelationshipHelper.MakeRelationShip(
    masterList,                    //整体列表
    detailList,                    //碎片列表
    t1 => t1.MasterId,             //获取整体ID的方法
    t1 => t1.MasterValue,          //获取整体的值的方法
    t2 => t2.LineValue,            //获取碎片的值的方法
    (t2, id) => t2.MasterId = id); //将结果ID

结果:

整体 | ID | 值 | |----|----| |2001|80 | |2002|100 |

碎片 | ID |值|关联整体ID| |----|--|----| |1001|16|2002| |1002|11|2001| |1003|13|2001| |1008|28|2001| |1009|28|2001| |1010|28|2002| |1011|28|2002| |1012|28|2002|

找出多值组合关系

这其实是找出构成整体的碎片集的变化版本。在企业开发中,常常遇到这样的问题,把原先的一些记录(原始)拆分成若干更多的记录(碎片),而我们要建立碎片和原始之间的对应关系,例如给出"原始":8,13,2, 给出"碎片:7,5,3,2,6, 我们需要获得的结果是5,3,6,7,2, 因为5+3=8, 6+7=13, 2=2

int[] originals = new[] { 3, 5 };
int[] fragments = new[] { 2, 4, 1, 1 };
int[] res = RelationshipHelper.FindRelationship(originals, fragments);
// res为 [2, 1, 1, 4]

如果组合关系匹配失败,将会返回null

洗牌和随机取值

洗牌(随机打乱一个数组)

char[] arr = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
ShuffleHelper.Shuffle(arr);
// 数组arr被随机打乱,如:'3', '0', '9', '5', '8', '6', '2', '1', '4', '7'

随机从一个数组中取出N个下标

这种方法无需提供数组对象本身

int[] arr = ShuffleHelper.RandomGet(10, 5);
// arr为0-9的随机下标,如:3, 6, 4, 9, 1

随机从一个数组中取出N个值

char[] arrAlpha = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
char[] arr = ShuffleHelper.RandomGet(arrAlpha, 3);
// arr为arrAlpha中的随机的3个元素,如:'d', 'f', 'b'

数组位移

数组的位移就是直接根据需求挪动数组的元素。如数组[1,2,3,4,5][2,3]子数组向右挪1个位置,数组就变成了[1,4,2,3,5]

注: 如果越界,会抛出IndexOutOfRangeException异常。

int[] arr = new int[]{1,2,3,4,5,6,7,8,9};
ArrayHelper.ShiftArrayItems(arr, 7, 3, -5); //-5表示左移5位
// arr为 [0, 1, 7, 8, 9, 2, 3, 4, 5, 6]
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.7 123 6/22/2026
1.0.6.1 277 11/29/2024
1.0.6 265 11/29/2024 1.0.6 is deprecated because it has critical bugs.
1.0.5 333 7/10/2023
1.0.4 410 3/2/2023
1.0.3 384 2/15/2023
1.0.2 641 3/8/2022
1.0.1 435 12/31/2021
1.0.0 447 12/30/2021

优化了FindRelationship方法,大幅提高速度