import 'dart:io'; class Separators { final String dotToConnections = ": "; final String dotToLength = "|"; final String space = " "; final String hasLength = "Взвешенный\n"; final String hasNoLength = "НеВзвешенный\n"; final String isOriented = "Ориентированный\n"; final String isNotOriented = "НеОриентированный\n"; final String nL = "\n"; final String end = "END"; Separators(); } class Dot { //Data // ignore: prefer_final_fields String _name = ""; int num = -1; Map ln = {}; //****Get**** String getName() => _name; bool hasConnection(int n) => ln.containsKey(n); int getLength(int x) { if (hasConnection(x)) { return ln[x]!; } return -1; } //****Get**** //Set void setName(String n) => _name = n; //Add void addPath(int inp, int length) => ln[inp] = length; // нужна проверка на ориентированность //Del void delPath(int n) => ln.removeWhere((key, value) => key == n); // удалить обратный путь если не ориентированный //Print void printD() { stdout.write("$_name: №$num => "); for (var i in ln.keys) { stdout.write("$i|${ln[i]} "); } stdout.write("\n"); } //******Constructor****** Dot() { _name = "Undefined"; num = -1; ln = {}; } Dot.fromTwoLists(String name, List num0, List length, [int n = -1]) { _name = name; num = n; Map nw = {}; if (num0.length != length.length) { print("Error in lists"); } else { for (var i = 0; i < num0.length; i++) { nw[num0[i]] = length[i]; ln = nw; } } } Dot.fromMap(String name, Map l, [int n = -1]) { _name = name; num = n; ln = l; } //******Constructor****** //Copy Dot.clone(Dot a) { _name = a.getName(); num = a.num; ln = a.ln; } } class Graphs { //Data String _name = "Undefined"; //Имя int _amount = 0; //Количество вершин List _dots = []; //Список смежности вершин // ignore: prefer_final_fields Map _nameTable = {}; //Список вершин по именам bool _useLength = false; //Взвешенность // ignore: prefer_final_fields bool _oriented = false; //Ориентированность //*********************Add************************ bool addDot(Dot a) { if (getNumByName(a.getName()) != null) { print( "Dot name ${a.getName()} already in use. Change name or use addPath"); return false; } _amount++; a.num = _amount; _dots.add(a); _syncNameTable(); checkDots(false); if (!_oriented) _fullFix(); return true; } bool addDotFromToLists(String name, List num0, List length, [int n = -1]) { var a = Dot.fromTwoLists(name, num0, length, n); if (getNumByName(a.getName()) != null) { print( "Dot name ${a.getName()} already in use. Change name or use addPath"); return false; } _amount++; a.num = _amount; _dots.add(a); _syncNameTable(); checkDots(false); if (!_oriented) _fixPathAfterInsert(a); return true; } bool addIsolated(String name) { var o = addDot(Dot.fromTwoLists(name, [], [])); _syncNameTable(); return o; } bool addPath(int from, int to, [int len = 0]) { if (from <= 0 || from > _amount || to <= 0 && to > _amount) { return false; } _dots[from - 1].addPath(to, len); if (!_oriented) { _dots[to - 1].addPath(from, len); } return true; } //*********************Add************************ //******Helper******* bool checkDots([bool verbose = false]) { for (var a in _dots) { for (var i in a.ln.keys) { try { if (!_dots[i - 1].ln.containsKey(a.num)) { if (verbose) print("Can't find ${a.num}"); return false; } } catch (e) { if (verbose) { print("Can't find Dot $i for path ${a.num}->$i. Exception $e"); } _dots[a.num - 1].ln.remove(i); return false; } } } return true; } void _fixPathAfterInsert(Dot a) { //Для неориентированного for (var i in a.ln.keys) { if (!_dots[i - 1].ln.containsKey(a.num)) { _dots[i - 1].addPath(i, a.ln[i]!); } } } void _fullFix() { for (var i in _dots) { _fixPathAfterInsert(i); } } void _syncNameTable() { _nameTable = {}; for (var i in _dots) { _nameTable[i.num] = i.getName(); } } void _syncNum() { _amount = 0; for (var i in _dots) { i.num = ++_amount; } _syncNameTable(); } //******Helper******* //*****Getters******* bool getDoubleSided() => _oriented; bool getUseLength() => _useLength; List getDots() => _dots; String getName() => _name; String? getNameByNum(int n) => _nameTable[n]; int? getNumByName(String n) { for (var i in _nameTable.keys) { if (_nameTable[i] == n) return i; } return null; } List>? getTable() { List>? out = >[]; for (int i = 0; i < _amount; i++) { List xx = []; for (int j = 1; j <= _amount; j++) { xx.add(_dots[i].getLength(j)); } out.add(xx); } return out; } //*****Getters******* //******Print****** void printG() { stdout.write("$_name: "); if (_oriented) { stdout.write("Ориентированный, "); } else { stdout.write("Не ориентированный, "); } if (_useLength) { print("Взвешенный"); } else { print("Не взвешенный"); } for (var i in _dots) { i.printD(); } } void toFile(String name) { Separators sep = Separators(); var file = File(name); file.writeAsStringSync("$_name\n"); if (_oriented) { file.writeAsStringSync(sep.isOriented, mode: FileMode.append); } else { file.writeAsStringSync(sep.isNotOriented, mode: FileMode.append); } if (_useLength) { file.writeAsStringSync(sep.hasLength, mode: FileMode.append); } else { file.writeAsStringSync(sep.hasNoLength, mode: FileMode.append); } for (int i = 0; i < _amount; i++) { file.writeAsStringSync((i + 1).toString() + sep.dotToConnections, mode: FileMode.append); var d = _dots[i].ln; for (var j in d.keys) { file.writeAsStringSync( j.toString() + sep.dotToLength + d[j].toString() + " ", mode: FileMode.append); } file.writeAsStringSync(sep.nL, mode: FileMode.append); } file.writeAsStringSync(sep.end, mode: FileMode.append); } //******Print****** //*******Constructor******** Graphs() { _name = "Udefined"; _dots = []; _useLength = false; _oriented = false; _amount = 0; _nameTable = {}; } Graphs.fromList(String n, List d, bool useL, bool oriented) { _name = n; _dots = d; _useLength = useL; _amount = _dots.length; _oriented = oriented; _syncNum(); if (!_oriented) _fullFix(); } Graphs.fromFile(String path) { Separators sep = Separators(); File file = File(path); List lines = file.readAsLinesSync(); _name = lines.removeAt(0); _oriented = lines.removeAt(0) == sep.isOriented; _useLength = lines.removeAt(0) == sep.hasLength; _dots = []; for (var l in lines) { if (l != sep.end) { var spl = l.split(sep.space); List dot = []; List len = []; String name = spl.removeAt(0); name = name.substring(0, name.length - 1); for (var splitted in spl) { var dt = splitted.split(sep.dotToLength); dot.add(int.parse(dt[0])); len.add(int.parse(dt[1])); } Dot add = Dot.fromTwoLists(name, dot, len); _dots.add(add); } } _syncNameTable(); if (!_oriented) _fullFix(); } //*******Constructor******** //Copy Graphs.clone(Graphs a) { _name = a.getName(); _dots = a.getDots(); _oriented = a.getDoubleSided(); _useLength = a.getUseLength(); _amount = _dots.length; _syncNameTable(); } }