using System.Text.RegularExpressions; using Interfaces; namespace Graph.IO { using Graph = Graph, double>, Edge, double>; public static class GraphFile { // read a graph from file using IFileReader (i.e. Dependancy injection for unit testing) public static Graph Read(IFileReader reader) { string[] lines = reader.Lines; Graph graph = new Graph(); foreach (string line in reader.Lines) { // split string into vertex id and the edges string[] parts = line.Split(" ", 2); // parse vertex id int vertex = int.Parse(parts[0]); // parse edges, matches pairs of number two at a time, i.e. "num num" Match match = Regex.Match(parts[1], @"[^ ]+ [^ ]+"); while (match.Success) { // for each match, split the "vertex weight" pair string[] edge = match.Value.Split(" ", 2); // add edge to graph (vertex1, vertex2, weight) graph.AddEdge(new Edge( vertex, int.Parse(edge[0]), double.Parse(edge[1]) )); // iterate match match = match.NextMatch(); } } return graph; } // write a graph to file using IFileWriter (i.e. Dependancy injection for unit testing) public static void Print(Graph graph, IFileWriter writer) { // create array of strings with a size equal to vertices string[] lines = new string[graph.Vertices.Count]; // add each vertex to it's parents output line graph.Vertices.ForEach(vertex => { // do nothing if it has no parent if (vertex.Parent == -1) return; // for vertex & parent, create string if not already lines[vertex.Id] ??= $"{vertex.Id}"; lines[vertex.Parent] ??= $"{vertex.Parent}"; // add vertex + weight to parent's string & visa versa lines[vertex.Parent] += $" {vertex.Id} {vertex.Key.ToString("F1")}"; lines[vertex.Id] += $" {vertex.Parent} {vertex.Key.ToString("F1")}"; }); // write the array of strings to file writer.WriteAllLines(lines); } } }