/// <summary> /// Attempts to convert a text representation into a permutation. /// </summary> /// <param name="text">A text representation of the permutation.</param> /// <param name="output">The corresponding permutation.</param> /// <returns>True if the conversion succeeded, otherwise false.</returns> /// <remarks> /// <para>For information on supported text representations, see <see cref="Parse"/>.</para> /// </remarks> public static bool TryParse(string text, out Permutation output) { output = null; if (text == null) { return(false); } bool success = false; if ((text.Length > 0) && (text[0] == '[')) { // try to parse as ordering PermutationAsMap map; success = PermutationAsMap.TryParse(text, out map); if (success) { output = new Permutation(map); } } else { // try to parse as cycles PermutationAsCycles cycles; success = PermutationAsCycles.TryParse(text, out cycles); if (success) { output = new Permutation(cycles); } } return(success); }
public static bool TryParse (string text, out PermutationAsCycles result) { result = null; // Construct cycles list, adding up dimension as we go List<int[]> cyclesList = new List<int[]>(); int start = 0; int dimension = 0; while (start < text.Length) { if (text[start] != '(') return (false); int end = text.IndexOf(')', start); if (end < 0) return (false); string[] cycleText = text.Substring(start + 1, end - start - 1).Split((char[]) null, StringSplitOptions.RemoveEmptyEntries); int[] cycle = new int[cycleText.Length]; dimension += cycle.Length; for (int k = 0; k < cycle.Length; k++) { int value; if (!Int32.TryParse(cycleText[k], out value)) return (false); cycle[k] = value; } cyclesList.Add(cycle); start = end + 1; } int[][] cycles = cyclesList.ToArray(); // Validate cycles. Each integer should appear once. bool[] flags = new bool[dimension]; for (int i = 0; i < cycles.Length; i++) { for (int j = 0; j < cycles[i].Length; j++) { int value = cycles[i][j]; if ((value < 0) || (value >= dimension)) return (false); if (flags[value]) return (false); flags[value] = true; } } // At this point the cycles are valid but not necessarily canonical. // At this point we want to cannonicalize the cycles. We can do this by // shuffling and sorting rows, but a quick-and-dirty solution is to // just use the non-canonical cycles to generate a map and let the // map to cycles logic generate canonical cycles. result = new PermutationAsCycles(cycles); return (true); }
private void ComputeCycles() { Debug.Assert(map != null); cycles = new PermutationAsCycles(FromMapToCycles(map.map)); }
internal Permutation(PermutationAsCycles cycles) { this.cycles = cycles; }