mirror of
https://github.com/UglyToad/PdfPig.git
synced 2026-03-10 00:23:29 +08:00
Improve GroupIndexes() performance with #1178
This commit is contained in:
@@ -216,25 +216,26 @@
|
||||
yield return group.Select(i => elements[i]).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Group elements using Depth-first search.
|
||||
/// <para>https://en.wikipedia.org/wiki/Depth-first_search</para>
|
||||
/// </summary>
|
||||
/// <param name="edges">The graph. edges[i] = j indicates that there is an edge between i and j.</param>
|
||||
/// <returns>A List of HashSets containing the grouped indexes.</returns>
|
||||
|
||||
internal static List<HashSet<int>> GroupIndexes(int[] edges)
|
||||
{
|
||||
int[][] adjacency = new int[edges.Length][];
|
||||
// Improved thanks to https://github.com/UglyToad/PdfPig/issues/1178
|
||||
var adjacency = new List<int>[edges.Length];
|
||||
for (int i = 0; i < edges.Length; i++)
|
||||
{
|
||||
HashSet<int> matches = new HashSet<int>();
|
||||
if (edges[i] != -1) matches.Add(edges[i]);
|
||||
for (int j = 0; j < edges.Length; j++)
|
||||
adjacency[i] = new List<int>();
|
||||
}
|
||||
|
||||
// one pass O(n)
|
||||
for (int i = 0; i < edges.Length; i++)
|
||||
{
|
||||
int j = edges[i];
|
||||
if (j != -1)
|
||||
{
|
||||
if (edges[j] == i) matches.Add(j);
|
||||
// i <-> j
|
||||
adjacency[i].Add(j);
|
||||
adjacency[j].Add(i);
|
||||
}
|
||||
adjacency[i] = matches.ToArray();
|
||||
}
|
||||
|
||||
List<HashSet<int>> groupedIndexes = new List<HashSet<int>>();
|
||||
@@ -242,55 +243,20 @@
|
||||
|
||||
for (int p = 0; p < edges.Length; p++)
|
||||
{
|
||||
if (isDone[p]) continue;
|
||||
if (isDone[p])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
groupedIndexes.Add(DfsIterative(p, adjacency, ref isDone));
|
||||
}
|
||||
return groupedIndexes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Group elements using Depth-first search.
|
||||
/// <para>https://en.wikipedia.org/wiki/Depth-first_search</para>
|
||||
/// </summary>
|
||||
/// <param name="edges">The graph. edges[i] = [j, k, l, ...] indicates that there is an edge between i and each element j, k, l, ...</param>
|
||||
/// <returns>A List of HashSets containing the grouped indexes.</returns>
|
||||
internal static List<HashSet<int>> GroupIndexes(int[][] edges)
|
||||
{
|
||||
int[][] adjacency = new int[edges.Length][];
|
||||
for (int i = 0; i < edges.Length; i++)
|
||||
{
|
||||
HashSet<int> matches = new HashSet<int>();
|
||||
for (int j = 0; j < edges[i].Length; j++)
|
||||
{
|
||||
if (edges[i][j] != -1) matches.Add(edges[i][j]);
|
||||
}
|
||||
|
||||
for (int j = 0; j < edges.Length; j++)
|
||||
{
|
||||
for (int k = 0; k < edges[j].Length; k++)
|
||||
{
|
||||
if (edges[j][k] == i) matches.Add(j);
|
||||
}
|
||||
}
|
||||
adjacency[i] = matches.ToArray();
|
||||
}
|
||||
|
||||
List<HashSet<int>> groupedIndexes = new List<HashSet<int>>();
|
||||
bool[] isDone = new bool[edges.Length];
|
||||
|
||||
for (int p = 0; p < edges.Length; p++)
|
||||
{
|
||||
if (isDone[p]) continue;
|
||||
groupedIndexes.Add(DfsIterative(p, adjacency, ref isDone));
|
||||
}
|
||||
return groupedIndexes;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Depth-first search
|
||||
/// <para>https://en.wikipedia.org/wiki/Depth-first_search</para>
|
||||
/// </summary>
|
||||
private static HashSet<int> DfsIterative(int s, int[][] adj, ref bool[] isDone)
|
||||
private static HashSet<int> DfsIterative(int s, List<int>[] adj, ref bool[] isDone)
|
||||
{
|
||||
HashSet<int> group = new HashSet<int>();
|
||||
Stack<int> S = new Stack<int>();
|
||||
|
||||
Reference in New Issue
Block a user