Skip to content

Commit ab89807

Browse files
committed
改进了关系匹配算法,在碎片存在大量相同数值的情况下速度得到大幅度提高
给排列算法增加了一个去除重复选项
1 parent 1b91b7c commit ab89807

File tree

4 files changed

+52
-33
lines changed

4 files changed

+52
-33
lines changed

AlgorithmLib/AlgorithmLib.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
<PropertyGroup>
44
<TargetFramework>netstandard2.0</TargetFramework>
5-
<Version>1.0.1</Version>
5+
<Version>1.0.2</Version>
66
<PackageId>AlgorithmLib</PackageId>
77
<Authors>Jiang Guogang</Authors>
88
<Company></Company>
99
<Description>一些常用的算法</Description>
1010
<RepositoryUrl>https://github.com/guogangj/AlgorithmLib</RepositoryUrl>
11-
<PackageReleaseNotes>增加了洗牌及随机取值算法</PackageReleaseNotes>
11+
<PackageReleaseNotes>改进了关系匹配算法,给排列算法增加了一个去除重复选项</PackageReleaseNotes>
1212
</PropertyGroup>
1313

1414
</Project>

AlgorithmLib/PermutationHelper.cs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
using System;
2+
using System.Collections.Generic;
23

34
namespace AlgorithmLib {
4-
/// <summary>
5-
/// 排列算法类
5+
/// <summary>
6+
/// 排列算法类
67
/// </summary>
78
public static class PermutationHelper {
89

@@ -11,9 +12,10 @@ public static class PermutationHelper {
1112
/// </summary>
1213
/// <param name="arr">要进行排列的数组</param>
1314
/// <param name="callback">回调方法</param>
14-
public static void Permutation<T>(T[] arr, Func<T[], bool> callback) {
15+
/// <param name="removeDuplicates">是否去除重复结果,默认是(用GetHashCode判断元素是否重复)</param>
16+
public static void Permutation<T>(T[] arr, Func<T[], bool> callback, bool removeDuplicates = false) {
1517
for (int n = 1; n <= arr.Length; n++) {
16-
if (!_Permutation(arr, n, callback)) {
18+
if (!_Permutation(arr, n, callback, removeDuplicates)) {
1719
return;
1820
}
1921
}
@@ -26,9 +28,10 @@ public static void Permutation<T>(T[] arr, Func<T[], bool> callback) {
2628
/// <param name="n1">排列结果取n1个数</param>
2729
/// <param name="n2">到取n2个数</param>
2830
/// <param name="callback">回调方法</param>
29-
public static void Permutation<T>(T[] arr, int n1, int n2, Func<T[], bool> callback) {
31+
/// <param name="removeDuplicates">是否去除重复结果,默认是(用GetHashCode判断元素是否重复)</param>
32+
public static void Permutation<T>(T[] arr, int n1, int n2, Func<T[], bool> callback, bool removeDuplicates = false) {
3033
for (int n = n1; n <= n2; n++) {
31-
if (!_Permutation(arr, n, callback)) {
34+
if (!_Permutation(arr, n, callback, removeDuplicates)) {
3235
return;
3336
}
3437
}
@@ -41,19 +44,27 @@ public static void Permutation<T>(T[] arr, int n1, int n2, Func<T[], bool> callb
4144
/// <param name="n">排列结果取多少个元素</param>
4245
/// <param name="callback">回调方法</param>
4346
/// <returns>true为正常结束,false为中断</returns>
44-
public static void Permutation<T>(T[] arr, int n, Func<T[], bool> callback) {
45-
_Permutation(arr, n, callback);
47+
/// <param name="removeDuplicates">是否去除重复结果,默认是(用GetHashCode判断元素是否重复)</param>
48+
public static void Permutation<T>(T[] arr, int n, Func<T[], bool> callback, bool removeDuplicates = false) {
49+
_Permutation(arr, n, callback, removeDuplicates);
4650
}
4751

48-
private static bool _Permutation<T>(T[] arr, int n, Func<T[], bool> callback) {
52+
private static bool _Permutation<T>(T[] arr, int n, Func<T[], bool> callback, bool removeDuplicates) {
4953

5054
bool SubPermutation(int len, int start) {
5155
if (len == 0) {
5256
T[] onePerm = new T[start];
5357
Array.Copy(arr, onePerm, start);
5458
return callback(onePerm);
5559
}
60+
HashSet<T> hash = removeDuplicates ? new HashSet<T>() : null;
5661
for (int i = start; i < arr.Length; i++) {
62+
if (hash != null) {
63+
if (hash.Contains(arr[i])) { //避免重复排列
64+
continue;
65+
}
66+
hash.Add(arr[i]);
67+
}
5768
T tmp = arr[i];
5869
arr[i] = arr[start];
5970
arr[start] = tmp;

AlgorithmLib/RelationshipHelper.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Diagnostics;
34
using System.Linq;
45

@@ -47,18 +48,22 @@ public static int[] FindRelationship(int[] originals, int[] fragments) {
4748
return null;
4849
}
4950

50-
int[] SubFindRelationship(int currOriginalIdx, int matchedValForCurrOrgIdx, int[] subFragments) {
51+
int[] SubFindRelationship(int currOriginalIdx, int matchedValForCurrOrgIdx, int[] subFragments) {
5152
Debug.Assert(currOriginalIdx < originals.Length && subFragments.Any());
52-
if (originals.Length-currOriginalIdx > subFragments.Length) {
53+
if (originals.Length - currOriginalIdx > subFragments.Length) {
5354
return null;
5455
}
5556
if (originals.Length - currOriginalIdx == 1 && subFragments.Length == 1) {
56-
return matchedValForCurrOrgIdx + subFragments[0]== originals[currOriginalIdx] ? subFragments : null;
57+
return matchedValForCurrOrgIdx + subFragments[0] == originals[currOriginalIdx] ? subFragments : null;
5758
}
58-
59+
HashSet<int> hash = new HashSet<int>();
5960
for (int i = 0; i < subFragments.Length; i++) {
61+
if(hash.Contains(subFragments[i])) {
62+
continue;
63+
}
64+
hash.Add(subFragments[i]);
6065
if (matchedValForCurrOrgIdx + subFragments[i] == originals[currOriginalIdx]) {
61-
int[] res = SubFindRelationship(currOriginalIdx+1, 0, RollArrayAndRemoveFirstByIndex(subFragments, i));
66+
int[] res = SubFindRelationship(currOriginalIdx + 1, 0, RollArrayAndRemoveFirstByIndex(subFragments, i));
6267
if (res != null) {
6368
return PrependElementToArray(res, subFragments[i]);
6469
}

AlgorithmLibDemo/Program.cs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ static void SimplePrintArray<T>(T[] arr) {
1111

1212
//组合demo
1313
static void CombinationDemo() {
14-
char[] arr = new char[] {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
14+
char[] arr = new char[] { 'a', 'a', 'a', 'd', 'e', 'f', 'g' };
1515

1616
CombinationHelper.Method = CombinationMethod.FlagDrift;
1717
Stopwatch sw = new Stopwatch();
1818
sw.Start();
19-
CombinationHelper.Combination(arr, 3, res => {
19+
CombinationHelper.Combination(arr, 2, res => {
2020
SimplePrintArray(res);
2121
return true;
2222
});
@@ -35,11 +35,16 @@ static void CombinationDemo() {
3535

3636
//排列demo
3737
static void PermutationDemo() {
38-
int[] arr = new int[] { 1, 2, 3, 4 };
39-
PermutationHelper.Permutation(arr, 2, 4, res => {
38+
//int[] arr = new int[] { 1, 2, 3, 4 };
39+
// int[] arr = new int[] { 1, 2, 2, 2 };
40+
int[] arr = new[] { 16, 11, 13, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28 };
41+
int count = 0;
42+
PermutationHelper.Permutation(arr, arr.Length, arr.Length, res => {
4043
SimplePrintArray(res);
44+
count++;
4145
return true;
42-
});
46+
}, true);
47+
Console.WriteLine("总数: " + count);
4348
}
4449

4550
//数值分摊demo
@@ -54,14 +59,16 @@ static void NumberDivideDemo() {
5459

5560
//查找关系DEMO
5661
static void FindRelationDemo() {
57-
//int[] originals = new[] { 8, 13, 2 };
58-
//int[] fragments = new[] { 7, 5, 3, 2, 6 };
62+
int[] originals = new[] { 8, 13, 2 };
63+
int[] fragments = new[] { 7, 5, 3, 2, 6 };
5964
//int[] originals = new[] { 23, 16, 4, 8, 15, 7 };
6065
//int[] fragments = new[] { 3, 3, 1, 7, 14, 8, 17, 1, 7, 4, 3, 1, 3, 1 };
61-
int[] originals = { 3, 5 };
62-
int[] fragments = { 2, 4, 1, 1 };
66+
//int[] originals = { 3, 5 };
67+
//int[] fragments = { 2, 4, 1, 1 };
6368
//int[] originals = new[] { 7, 13, 6, 99, 24, 16, 35 };
6469
//int[] fragments = new[] { 11, 9, 50, 13, 3,6, 30, 11, 7, 5, 4, 11, 2, 5, 9, 24};
70+
//int[] originals = new[] { 500, 100 };
71+
//int[] fragments = new[] { 16, 11, 13, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28 };
6572
int[] res = RelationshipHelper.FindRelationship(originals, fragments);
6673
if (res != null) {
6774
SimplePrintArray(res);
@@ -71,7 +78,7 @@ static void FindRelationDemo() {
7178
//洗牌,随机取值demo
7279
static void ShuffleDemo() {
7380
//洗牌10次
74-
for(int i=0; i<10; i++) {
81+
for (int i = 0; i < 10; i++) {
7582
char[] arr = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
7683
ShuffleHelper.Shuffle(arr);
7784
SimplePrintArray(arr);
@@ -92,21 +99,17 @@ static void ShuffleDemo() {
9299

93100
//边界测试
94101
char[] res = ShuffleHelper.RandomGet(arrAlpha, 0);
95-
Debug.Assert(res.Length==0);
102+
Debug.Assert(res.Length == 0);
96103
res = ShuffleHelper.RandomGet(arrAlpha, 7);
97104
SimplePrintArray(res);
98105
}
99106

100107
static void Main(string[] args) {
101-
int a = 1;
102-
int b = 2;
103-
(a, b) = (b, a);
104-
Console.WriteLine(a + ", " + b);
105-
//PermutationDemo();
108+
PermutationDemo();
106109
//CombinationDemo();
107110
//NumberDivideDemo();
108111
//FindRelationDemo();
109-
ShuffleDemo();
112+
//ShuffleDemo();
110113
}
111114
}
112115
}

0 commit comments

Comments
 (0)