diff --git a/.vscode/launch.json b/.vscode/launch.json index 1da1702..c5213d1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "graphs0", "request": "launch", "type": "dart", - "program": "bin/main.dart" + "program": "bin/graphs0.dart" }, ] } \ No newline at end of file diff --git a/README.md b/README.md index a307539..8f79023 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -A simple command-line application. +Application to store graph data. diff --git a/bin/graphs0.dart b/bin/graphs0.dart new file mode 100644 index 0000000..1da0b65 --- /dev/null +++ b/bin/graphs0.dart @@ -0,0 +1,290 @@ +import 'src/graph.dart'; +import 'dart:convert'; +import 'dart:io'; + +int getIntLine() => int.parse(stdin.readLineSync(encoding: utf8)!); +String getStrLine() => stdin.readLineSync(encoding: utf8)!; + +void main(List arguments) { + Map x = {1: 10, 2: 11}; + var p = Dot.fromMap("Т1", x); + p.printD(); + x = {}; + + x[1] = 11; + var p2 = Dot.fromMap("Т2", x); + p2.printD(); + x = {}; + + var x1 = Graphs.fromList("Граф 1", [p, p2], true, false); + x1.addDot(p); + x1.addDotFromToLists("T3", [1, 2], [10, 20]); + x1.addIsolated("T4"); + x1.checkDots(true); + x1.printG(); + print(x1.addPath(4, 1, 10)); + x1.printG(); + x1.printToFile("outTest.txt"); + var x2 = Graphs.fromFile("outTest.txt"); + x2.printG(); + x2.delPath(1, 4); + x2.printG(); + x2.delDot(1); + x2.printG(); + x2.delDot(2); + x2.printG(); + x2.addPath(1, 2, 11); + x2.printG(); + + int deistvie = 1; + List graphs = []; + String name; + String str = ""; + Separators sep = Separators(); + while (deistvie != 0) { + stdout.write( + "1 - создать граф, 2 - удалить граф, 3 - добавить в граф вершину,\n4 - удалить вершину, 5 - добавить ребро/дугу, 6 - удалить ребро/дугу,\n7 - вывести граф на экран, 8 - вывести граф в файл, 0 - выход\nDeistvie: "); + deistvie = getIntLine(); + switch (deistvie) { + case 1: + { + // создать граф + print("1 - ввести из файла, 2 - ввести вручную\nDeistvie: "); + int d = getIntLine(); + List list = []; + switch (d) { + case 1: + { + // из файла + stdout.write("Имя файла: "); + name = getStrLine(); + graphs.add(Graphs.fromFile(name)); + graphs.last.printG(); + break; + } + case 2: + { + // с консоли + stdout.write("Имя графа: "); + name = getStrLine(); + + stdout.write( + "Граф: 1 - ориентированный, 2 - не ориентированный: "); + bool isOriented; + String x = getStrLine(); + if (x == "1") { + isOriented = true; + } else { + isOriented = false; + } + + stdout.write("Граф: 1 - взвешенный, 2 - не взвешенный: "); + bool hasLength; + x = getStrLine(); + if (x == "1") { + hasLength = true; + } else { + hasLength = false; + } + + stdout.write("Количество вершин: "); + int n = getIntLine(); + + list = []; + for (int i = 0; i < n; i++) { + stdout.write("Имя вершины: "); + String dotName = getStrLine(); + + stdout.write( + "Ввод: *куда*|*вес* через пробел. Если граф не взвешенный, то *вес* можно не указывать.\nВершина №${i + 1}. Смежна с: "); + str = getStrLine(); + + List inn = []; + List len = []; + while (str != "" && str != " ") { + List a = str.split(sep.space); + for (var splitted in a) { + var dt = splitted.split(sep.dotToLength); + if (dt.length == 2) { + inn.add(int.parse(dt[0])); + len.add(int.parse(dt[1])); + } + } + list.add(Dot.fromTwoLists(dotName, inn, len)); + } + Graphs newG = + Graphs.fromList(name, list, hasLength, isOriented); + newG.printG(); + graphs.add(newG); + break; + } + } + } + break; + } + case 2: + { + // удалить граф + int num = graphs.length; + stdout.write( + "Нумерация с 0. Количество сохраненных графов: $num. Удалить граф с номером: "); + int x = getIntLine(); + if (x >= 0 && x < num) { + /* + vector::iterator i = grafs.begin(); + for (int j = 0; j < x; j++) { + i++;} + grafs.erase(i);*/ + } else { + print("Не найден граф с таким номером"); + } + break; + } + case 3: + { + // добавить вершину + List inn = []; + List len = []; + stdout.write( + "Ввод: *куда*|*вес* через пробел. Если граф не взвешенный, то в *вес* ставить 0: "); + String x = getStrLine(); + while (x != "" && x != " ") { + String a = x.substring(0, x.indexOf(sep.dotToLength)); + if (x.contains(sep.dotToLength)) { + x = x.substring(x.indexOf(" ") + 1, x.length); + } else { + x = ""; + } + + if (a.contains(sep.dotToLength)) { + inn.add(int.parse((a.substring(0, a.indexOf(sep.dotToLength))))); + len.add(int.parse( + a.substring(a.indexOf(sep.dotToLength) + 1, a.length))); + } else { + inn.add(int.parse(a)); + len.add(0); + } + } + int num = graphs.length; + stdout.write( + "Нумерация с 0. Количество сохраненных графов: $num. Вставка в графа с номером: "); + int y = getIntLine(); + if (y >= 0 && y < num) { + graphs[y].addDotFromToLists("0", inn, len); + } else { + print("Не найден граф с таким номером"); + } + graphs[y].printG(); + break; + } + case 4: + { + // удалить вершину + int num = graphs.length; + stdout.write( + "Нумерация с 0. Количество сохраненных графов: $num. Вывод графа с номером: "); + int y = getIntLine(); + graphs[y].printG(); + if (y >= 0 && y < num) { + num = graphs[y].getDotAmount(); + stdout.write("Количество вершин: $num. Вершина для удаления: "); + int x = getIntLine(); + if (x >= 0 && x < num) { + graphs[y].delDot(x); + } else { + print("Не найдены вершины в графе\n"); + } + } else { + print("Не найден граф с таким номером"); + } + break; + } + case 5: + { + // добавить ребро/дугу + int num = graphs.length; + stdout.write( + "Нумерация с 0. Количество сохраненных графов: $num. Вставка в граф с номером: "); + int y = getIntLine(); + graphs[y].printG(); + if (y >= 0 && y < num) { + num = graphs[y].getDotAmount(); + stdout.write("Количество вершин: $num. Вершина куда вствляется: "); + int x1 = getIntLine(); + stdout.write("Вершина, которую вставляют: "); + int x2 = getIntLine(); + stdout.write("Вес ребра, вствить 0 если граф не взвешенный: "); + int w = getIntLine(); + if (x1 >= 0 && x1 < num && x2 >= 0 && x2 < num) { + graphs[y].addPath(x1, x2, w); + } else { + print("Не найдены вершины в графе\n"); + } + } else { + print("Не найден граф с таким номером"); + } + break; + } + case 6: + { + // удалить ребро/дугу + int num = graphs.length; + stdout.write( + "Нумерация с 0. Количество сохраненных графов: $num. Удаление из графа с номером: "); + int y = getIntLine(); + graphs[y].printG(); + int x1, x2; + if (y >= 0 && y < num) { + num = graphs[y].getDotAmount(); + stdout.write( + "Количество вершин: $num. Введите через пробел номера вершин между которыми удалить ребро: "); + List x = getStrLine().split(sep.space); + x1 = int.parse(x[0]); + x2 = int.parse(x[1]); + if (x1 >= 0 && x1 < num && x2 >= 0 && x2 < num) { + graphs[y].delPath(x1, x2); + } else { + print("Не найдены вершины в графе\n"); + } + } else { + print("Не найден граф с таким номером"); + } + break; + } + case 7: // вывод в консоль + { + int num = graphs.length; + stdout.write( + "Нумерация с 0. Количество сохраненных графов: $num. Вывод графа с номером: "); + int x = getIntLine(); + if (x >= 0 && x < num) { + graphs[x].printG(); + } else { + print("Не найден граф с таким номером"); + } + break; + } + case 8: + { + // вывод в файл + int num = graphs.length; + stdout.write( + "Нумерация с 0. Количество сохраненных графов: $num. Вывод графа с номером: "); + int x = getIntLine(); + stdout.write("В файл: "); + String out = getStrLine(); + if (x >= 0 && x < num) { + graphs[x].printToFile(out); + } else { + print("Не найден граф с таким номером"); + } + break; + } + case 0: + exit(0); + default: + print("Действие не распознано"); + break; + } + } +} diff --git a/bin/main.dart b/bin/main.dart deleted file mode 100644 index dc0f328..0000000 --- a/bin/main.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'src/graph.dart'; - -void main(List arguments) { - Map x = {1: 10, 2: 11}; - var p = Dot.fromMap("Т1", x); - p.printD(); - x = {}; - - x[1] = 11; - var p2 = Dot.fromMap("Т2", x); - p2.printD(); - x = {}; - - var x1 = Graphs.fromList("Граф 1", [p, p2], true, false); - x1.addDot(p); - x1.addDotFromToLists("T3", [1, 2], [10, 20]); - x1.addIsolated("T4"); - x1.checkDots(true); - x1.printG(); - print(x1.addPath(4, 1, 10)); - print(x1.addPath(4, 2, 10)); - x1.printG(); - x1.toFile("outTest.txt"); -} diff --git a/bin/src/graph.dart b/bin/src/graph.dart index 1d578ff..95491e3 100644 --- a/bin/src/graph.dart +++ b/bin/src/graph.dart @@ -19,14 +19,15 @@ class Dot { // ignore: prefer_final_fields String _name = ""; int num = -1; - Map ln = {}; + Map _ln = {}; //****Get**** String getName() => _name; - bool hasConnection(int n) => ln.containsKey(n); + bool hasConnection(int n) => _ln.containsKey(n); + Map getL() => _ln; int getLength(int x) { if (hasConnection(x)) { - return ln[x]!; + return _ln[x]!; } return -1; } @@ -36,18 +37,17 @@ class Dot { void setName(String n) => _name = n; //Add - void addPath(int inp, int length) => - ln[inp] = length; // нужна проверка на ориентированность + void addPath(int inp, int length) => _ln[inp] = length; //Del - void delPath(int n) => ln.removeWhere((key, value) => + 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]} "); + for (var i in _ln.keys) { + stdout.write("$i|${_ln[i]} "); } stdout.write("\n"); } @@ -56,7 +56,7 @@ class Dot { Dot() { _name = "Undefined"; num = -1; - ln = {}; + _ln = {}; } Dot.fromTwoLists(String name, List num0, List length, [int n = -1]) { @@ -68,14 +68,14 @@ class Dot { } else { for (var i = 0; i < num0.length; i++) { nw[num0[i]] = length[i]; - ln = nw; + _ln = nw; } } } Dot.fromMap(String name, Map l, [int n = -1]) { _name = name; num = n; - ln = l; + _ln = l; } //******Constructor****** @@ -83,7 +83,7 @@ class Dot { Dot.clone(Dot a) { _name = a.getName(); num = a.num; - ln = a.ln; + _ln = a._ln; } } @@ -92,10 +92,8 @@ class Graphs { 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************************ @@ -149,12 +147,40 @@ class Graphs { } //*********************Add************************ + //*********Delete********* + bool delPath(int from, int to) { + if (from <= 0 || from > _amount || to <= 0 && to > _amount) { + return false; + } + _dots[from - 1].delPath(to); + if (!_oriented) { + _dots[to - 1].delPath(from); + } + return true; + } + + bool delDot(int inn) { + List toDel = []; + for (int i in _dots[inn - 1].getL().keys) { + toDel.add(i); + } + for (int i in toDel) { + delPath(i, inn); + } + _dots.removeAt(inn - 1); + _syncNum(); + _syncNameTable(); + _fixAfterDel(inn); + return true; + } + //*********Delete********* + //******Helper******* bool checkDots([bool verbose = false]) { for (var a in _dots) { - for (var i in a.ln.keys) { + for (var i in a.getL().keys) { try { - if (!_dots[i - 1].ln.containsKey(a.num)) { + if (!_dots[i - 1].getL().containsKey(a.num)) { if (verbose) print("Can't find ${a.num}"); return false; } @@ -162,7 +188,7 @@ class Graphs { if (verbose) { print("Can't find Dot $i for path ${a.num}->$i. Exception $e"); } - _dots[a.num - 1].ln.remove(i); + _dots[a.num - 1].getL().remove(i); return false; } } @@ -170,11 +196,25 @@ class Graphs { return true; } + void _fixAfterDel(int inn) { + for (int i = 0; i < _dots.length; i++) { + Map l = {}; + for (int j in _dots[i].getL().keys) { + if (j >= inn) { + l[j - 1] = _dots[i].getL()[j]!; + } else { + l[j] = _dots[i].getL()[j]!; + } + } + _dots[i] = Dot.fromMap(_dots[i].getName(), l, _dots[i].num); + } + } + 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]!); + for (var i in a.getL().keys) { + if (!_dots[i - 1].getL().containsKey(a.num)) { + addPath(i, a.num, a.getL()[i]!); } } } @@ -207,6 +247,7 @@ class Graphs { List getDots() => _dots; String getName() => _name; String? getNameByNum(int n) => _nameTable[n]; + int getDotAmount() => _dots.length; int? getNumByName(String n) { for (var i in _nameTable.keys) { if (_nameTable[i] == n) return i; @@ -245,7 +286,7 @@ class Graphs { } } - void toFile(String name) { + void printToFile(String name) { Separators sep = Separators(); var file = File(name); file.writeAsStringSync("$_name\n"); @@ -262,7 +303,7 @@ class Graphs { for (int i = 0; i < _amount; i++) { file.writeAsStringSync((i + 1).toString() + sep.dotToConnections, mode: FileMode.append); - var d = _dots[i].ln; + var d = _dots[i].getL(); for (var j in d.keys) { file.writeAsStringSync( j.toString() + sep.dotToLength + d[j].toString() + " ", @@ -283,10 +324,10 @@ class Graphs { _amount = 0; _nameTable = {}; } - Graphs.fromList(String n, List d, bool useL, bool oriented) { - _name = n; - _dots = d; - _useLength = useL; + Graphs.fromList(String name, List dots, bool hasLen, bool oriented) { + _name = name; + _dots = dots; + _useLength = hasLen; _amount = _dots.length; _oriented = oriented; _syncNum(); @@ -309,13 +350,15 @@ class Graphs { 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])); + if (dt.length == 2) { + dot.add(int.parse(dt[0])); + len.add(int.parse(dt[1])); + } } - Dot add = Dot.fromTwoLists(name, dot, len); - _dots.add(add); + _dots.add(Dot.fromTwoLists(name, dot, len)); } } + _syncNum(); _syncNameTable(); if (!_oriented) _fullFix(); } diff --git a/pubspec.lock b/pubspec.lock index 3e4a837..adc4877 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -9,4 +9,4 @@ packages: source: hosted version: "1.0.1" sdks: - dart: ">=2.14.0-178.0.dev <3.0.0" + dart: ">=2.14.0 <3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 0a081b4..f3c9d73 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,10 +1,10 @@ name: graphs0 -description: A simple command-line application. -version: 1.0.0 -# homepage: https://www.example.com +description: Application to store graph data. +version: 0.9.0 +homepage: https://morozovad.ddns.net/lnd212/Graphs_dart environment: - sdk: '>=2.14.0-178.0.dev <3.0.0' + sdk: '>=2.14.0 <3.0.0' # dependencies: