Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.IO;
- namespace Интерпретатор_НАМ
- {
- class Program
- {
- public struct Rules
- {
- public string word;//для записи символов
- public string pravilo;//для записи правил для символов
- public bool last;//для определения конечности операции
- }
- public static void Print(char[] mas1, int count)
- {
- int i = 0;
- Console.WriteLine("Исходный алвавит: ");
- for (i = 0; i < count; i++) Console.Write(mas1[i] + " ");
- Console.WriteLine();
- }
- public static void Print(Rules[] rules)
- {
- int i = 0;
- Console.WriteLine("Набор правил: ");
- for (i = 0; i < rules.Length; i++)
- {
- if (rules[i].last) Console.WriteLine("{0}->.{1}", rules[i].word, rules[i].pravilo);
- else Console.WriteLine("{0}->{1}", rules[i].word, rules[i].pravilo);
- }
- Console.WriteLine();
- }
- public static char[] Alphabet(ref int count)
- {
- char[] mas = new char[100];
- string s;
- bool right = false;
- char s1 = ' ';
- count = 0;
- Console.WriteLine(@"Вводите символы алфавита последовательно!
- Обратите внимание, что алфавит может содержать только маленькие латинские буквы, цифры, знаки (*, %, &, #, $, /, +, -) и знак пустоты Л (лямбда).
- Если вы хотите использовать пустоту в правилах, запишите её в ваш алфавит.
- Если вы хотите прервать процесс ввода правил, введите '!'.
- ");
- do
- {
- do
- {
- Console.Write("Введите {0} символ алфавита: ", count + 1);
- s = Console.ReadLine();
- if (s == "!") break;
- else
- {
- s = s.Trim();
- if (s == "") { Console.WriteLine("Строка пуста! Введите символ!"); right = false; }
- else if (s.Length > 1) { Console.WriteLine("Символ алфавита должен содержать не более одного символа! Повторите ввод."); right = false; }
- else
- {
- s1 = Convert.ToChar(s);
- if ((s1 >= 'a') && (s1 <= 'z') || (s1 >= '0') && (s1 <= '9') || (s1 == '*') || (s1 == 'Л') || (s1 == '#') || (s1 == '&') || (s1 == '%') || (s1 == '/') || (s1 == '$') || (s1 == '+') || (s1 == '-')) right = true;
- else { Console.WriteLine("Неверный символ! Повторите ввод."); right = false; }
- }
- if (right)
- {
- for (int i = 0; i < count; i++)
- {
- if (mas[i] == s1) { Console.WriteLine("Такой символ уже существует в алфавите! Повторите ввод."); right = false; break; }
- }
- }
- if (right)
- {
- mas[count] = s1;
- count++;
- }
- else break;
- }
- } while (count == 0);
- if (count == 45) Console.WriteLine("Вы ввели максимально допустимое число символов!");
- if (count == 0) Console.WriteLine("Вы не ввели ни одного символа алфавита!");
- if (s == "!" && count != 0) break;
- } while (count < 45);
- char[] mas1 = new char[count + 3];
- for (int i = 0; i < count; i++) mas1[i] = mas[i];
- mas1[count] = '>'; mas1[count + 1] = '-'; mas1[count + 2] = '.';
- return mas1;
- }
- public static bool Check(ref string str, char[] mas)//проверка ввода строки, а также правил
- {
- bool right = false;//для проверки строки
- int pustota = 0, mestopusto = 0;//для проверки наличия пустоты
- str = str.Trim();
- for (int i = 0; i < str.Length; i++)
- if (str[i] == ' ')
- {
- str = str.Remove(i, 1);
- i--;
- }
- //Console.WriteLine(str);
- char[] arr = str.ToCharArray();
- for (int i = 0; i < arr.Length; i++)
- {
- right = false;
- for (int j = 0; j < mas.Length; j++)
- {
- if (arr[i] == mas[j]) right = true;
- }
- if (arr[i] == 'Л') { pustota++; mestopusto = i; }
- if (!right) { Console.WriteLine("Ошибка в введенной строке: несоответствие введенных символов алфавиту! Повторите ввод."); break; }
- }
- if (right && pustota != 0)
- {
- //Console.WriteLine(pustota);
- if (pustota > 1) { right = false; Console.WriteLine("Ошибка со знаком пустоты! Повторите ввод."); }
- else
- {
- //Console.WriteLine(mestopusto);
- if (mestopusto == 0 && str[mestopusto + 1] == '-' || mestopusto == (str.Length - 1) && ((str[mestopusto - 1] == '>' || str[mestopusto - 1] == '.'))) right = true;
- else { right = false; Console.WriteLine("Ошибка с постановкой знака пустоты! Повторите ввод."); }
- }
- }
- if (!right) return false;
- else return true;
- }
- public static Rules[] Rule(char[] mas)
- {
- bool right, last = false, end = false;
- string str;
- int i = 0, j = 0, num = 0, count = 0, count1 = 0;
- string word1, pravilo1;
- Rules[] rules = new Rules[100];
- Console.WriteLine(@"Вводите комбинации символов и правила для них:
- через знак '->' , если правило не должно быть конечным;
- через знак '->.' , если правило конечное.
- Максимальное количество правил: 100.
- Максимальное количество шагов: 5000.
- Если вы хотите прервать процесс ввода правил, введите '!'.");
- do
- {
- do
- {
- count = 0;
- Console.WriteLine("Введите правило " + (num + 1) + ":");
- str = Console.ReadLine();
- if (str == "!") break;
- right = false;
- end = false;
- right = Check(ref str, mas);
- if (right)
- {
- for (i = 0; i < str.Length; i++)
- {
- if (str[i] == '-')
- {
- if (str.Length == i + 1) { end = false; break; }
- if (str.Length > (i + 3) && str[i + 1] == '>' && str[i + 2] == '.') { last = true; end = true; break; }
- if (str.Length > (i + 2) && str[i + 1] == '>') { last = false; end = true; break; }
- break;
- }
- }
- if (end && (str[str.Length - 1] == '>' || str[str.Length - 1] == '.')) { right = false; Console.WriteLine("Отсутствует правая часть правила!"); }
- if (!end && (str[str.Length - 1] == '.' || str[str.Length - 1] == '>')) { right = false; Console.WriteLine("Отсутствует правая часть правила!"); }
- else if (!end) { Console.WriteLine("Отсутствует символ '->' или '->.'!"); right = false; }
- if (i == 0) { right = false; Console.WriteLine("Отсутствует левая часть правила!"); }
- }
- if (right)
- {
- char[] brr = str.ToCharArray();
- if (last)
- {
- count = 0;
- j = 0;
- while (brr[count] != '-') count++;
- char[] word = new char[count];
- count1 = (brr.Length - count) - 3;
- char[] pravilo = new char[count1];
- for (i = 0; i < word.Length; i++) word[i] = brr[i];
- for (i = count + 3; i < brr.Length; i++) { pravilo[j] = brr[i]; j++; }
- word1 = new string(word);
- pravilo1 = new string(pravilo);
- for (i = 0; i < num; i++) if (rules[i].word == word1) { right = false; Console.WriteLine("Этому слову уже присвоено правило!"); }
- if (right)
- {
- rules[num].word = word1;
- rules[num].pravilo = pravilo1;
- //Console.WriteLine("Правило принимает следующий вид. Должно без точки "+rules[num].pravilo);
- rules[num].last = true;
- }
- }
- else
- {
- count = 0;
- j = 0;
- while (brr[count] != '-') count++;
- char[] word = new char[count];
- count1 = (brr.Length - count) - 2;
- char[] pravilo = new char[count1];
- for (i = 0; i < word.Length; i++) word[i] = brr[i];
- for (i = count + 2; i < brr.Length; i++) { pravilo[j] = brr[i]; j++; }
- word1 = new string(word);
- pravilo1 = new string(pravilo);
- for (i = 0; i < num; i++) if (rules[i].word == word1) { right = false; Console.WriteLine("Этому слову уже присвоено правило!"); }
- if (right)
- {
- rules[num].word = word1;
- rules[num].pravilo = pravilo1;
- rules[num].last = false;
- }
- }
- if (right) num++;
- }
- else break;
- } while (num == 0);
- if (num == 0) Console.WriteLine("Вы не ввели ни одного правила!");
- if (str == "!" && num != 0) break;
- if (num == rules.Length) Console.WriteLine("Вы ввели максимально возможное количество правил!");
- } while (num < rules.Length);
- Rules[] rules1 = new Rules[num];
- for (i = 0; i < rules1.Length; i++) rules1[i] = rules[i];
- return rules1;
- }
- public static Rules[] RulesFromFile(char[] mas)
- {
- int i = 0, j = 0, k, num = 0, count = 0, count1 = 0;
- bool ok, open, right = false, end = false, last = false;
- string name, str, word1, pravilo1;
- Rules[] rules = new Rules[100];
- do
- {
- try
- {
- Console.Write("Введите имя файла (без расширения): ");
- do
- {
- name = Convert.ToString(Console.ReadLine());
- ok = true;
- if (name.Length == 0)
- {
- ok = false;
- Console.WriteLine("Неверный ввод! Повторите попытку.");
- }
- } while (!ok);
- FileStream file = new FileStream(name + ".txt", FileMode.Open);
- StreamReader rd = new StreamReader(file);
- Rules[] rules1 = new Rules[100];
- for (k = 0; (str = rd.ReadLine()) != null && k < 100; k++)
- {
- count = 0;
- num = 0;
- count1 = 0;
- right = false;
- end = false;
- last = false;
- right = Check(ref str, mas);
- if (right)
- {
- for (i = 0; i < str.Length; i++)
- {
- if (str[i] == '-')
- {
- if (str.Length == i + 1) { end = false; break; }
- if (str.Length > (i + 3) && str[i + 1] == '>' && str[i + 2] == '.') { last = true; end = true; break; }
- if (str.Length > (i + 2) && str[i + 1] == '>') { last = false; end = true; break; }
- break;
- }
- }
- if (end && (str[str.Length - 1] == '>' || str[str.Length - 1] == '.')) right = false;
- if (!end && (str[str.Length - 1] == '.' || str[str.Length - 1] == '>')) right = false;
- else if (!end) right = false;
- if (i == 0) right = false;
- }
- if (right)
- {
- char[] brr = str.ToCharArray();
- if (last)
- {
- count = 0;
- j = 0;
- while (brr[count] != '-') count++;
- char[] word = new char[count];
- count1 = (brr.Length - count) - 3;
- char[] pravilo = new char[count1];
- for (i = 0; i < word.Length; i++) word[i] = brr[i];
- for (i = count + 3; i < brr.Length; i++) { pravilo[j] = brr[i]; j++; }
- word1 = new string(word);
- pravilo1 = new string(pravilo);
- for (i = 0; i < num; i++) if (rules[i].word == word1) right = false;
- if (right)
- {
- rules1[num].word = word1;
- rules1[num].pravilo = pravilo1;
- //Console.WriteLine("Правило принимает следующий вид. Должно без точки "+rules[num].pravilo);
- rules1[num].last = true;
- }
- }
- else
- {
- count = 0;
- j = 0;
- while (brr[count] != '-') count++;
- char[] word = new char[count];
- count1 = (brr.Length - count) - 2;
- char[] pravilo = new char[count1];
- for (i = 0; i < word.Length; i++) word[i] = brr[i];
- for (i = count + 2; i < brr.Length; i++) { pravilo[j] = brr[i]; j++; }
- word1 = new string(word);
- pravilo1 = new string(pravilo);
- for (i = 0; i < num; i++) if (rules[i].word == word1) right = false;
- if (right)
- {
- rules1[num].word = word1;
- rules1[num].pravilo = pravilo1;
- rules1[num].last = false;
- }
- }
- if (right) num++;
- }
- else break;
- }
- rd.Close();
- file.Close();
- open = true;
- Rules[] rules2 = new Rules[num];
- for (i = 0; i < rules2.Length; i++) rules2[i] = rules1[i];
- rules = rules2;
- if (right == false) { open = false; Console.WriteLine("При обработке правил из файла произошла ошибка! Выберите другой файл."); }
- if (k == 100) { open = false; Console.WriteLine("В данном файле более 100 правил! Выберите другой файл."); }
- }
- catch (IOException)
- {
- Console.WriteLine("\aОшибка открытия файла (возможно, файла не существует)!");
- open = false;
- }
- } while (!open);
- return rules;
- }
- static public void Markov(ref string s, Rules[] rules, ref int zachod, int results)
- {
- //i-для правил j-для строки
- int i = 0, j, k = 0, size = 0, z;
- bool found = false, end = false;
- do
- {
- for (i = 0; i < rules.Length; i++)
- {
- found = false;
- k = 0;
- //Console.WriteLine("Мы рассматриваем {0} ое правило", (i + 1));
- if (rules[i].word[0] == 'Л')
- {
- found = true;
- size = rules[i].pravilo.Length + s.Length;
- char[] arr = new char[size];
- while (k < rules[i].pravilo.Length) { arr[k] = rules[i].pravilo[k]; k++; }
- for (z = 0; z < s.Length; z++) { arr[k] = s[z]; k++; }
- s = new string(arr);
- if (rules[i].last) end = true;
- if (results == 1)
- {
- Console.WriteLine("После подстановки правила: " + s);
- Console.ReadLine();
- }
- i = -1;
- zachod++;
- }
- else
- {
- for (j = 0; j < s.Length; j++)
- {
- //Console.WriteLine("Длина строки" + s.Length);
- //Console.WriteLine("Первый символ правила " + rules[i].word[0]);
- //Console.WriteLine("Рассматриваемый сивол в строке " + s[j]);
- //Console.ReadLine();
- found = false;
- if (rules[i].word[0] == s[j])
- {
- //Console.WriteLine("Зашел в цикл. Символы оказались равны");
- if (s.Length - j >= rules[i].word.Length)
- {
- int begin = j;
- for (z = 0; z < rules[i].word.Length; z++)
- {
- //Console.WriteLine("Зашёл в цикл for");
- if (s[begin] == rules[i].word[z]) { found = true; begin++; }
- else { found = false; break; }
- }
- }
- }
- if (found)
- {
- //Console.WriteLine("Место, с которого начнется замена " + (j + 1)); Console.WriteLine("Место, на котором замен азакончится " + (j + rules[i].word.Length));
- size = j + rules[i].pravilo.Length + (s.Length - (j + rules[i].word.Length));
- //Console.WriteLine("Мы заменим " + rules[i].word + " на " + rules[i].pravilo);
- //Console.WriteLine(size);
- if (rules[i].pravilo == "Л") size = size - 1;
- char[] arr = new char[size];
- while (k < j) { arr[k] = s[k]; k++; }
- if (rules[i].pravilo != "Л")
- for (z = 0; z < rules[i].pravilo.Length; z++) { arr[k] = rules[i].pravilo[z]; k++; }
- for (z = j + rules[i].word.Length; z < s.Length; z++) { arr[k] = s[z]; k++; }
- s = new string(arr);
- if (rules[i].last) end = true;
- if (results == 1)
- {
- Console.WriteLine("После {0} подстановки правила: {1}", zachod + 1, s);
- Console.ReadLine();
- }
- i = -1;
- zachod++;
- break;
- }
- }
- }//Console.WriteLine("Правило:" + i);
- if (i == rules.Length - 1 && found == false) { Console.WriteLine("Обойдя все правила, программа не нашла подходящего для продолжения обработки строки, поэтому выходим из цикла."); end = true; }
- if (zachod == 5000) end = true;
- if (end) break;
- }
- } while (!end);
- //Console.WriteLine(zachod);
- //Console.ReadLine();
- }
- public static bool CheckString(ref string s, int count, char[] mas)
- {
- bool right = false;
- for (int i = 0; i < s.Length; i++)
- if (s[i] == ' ')
- {
- s = s.Remove(i, 1);
- i--;
- }
- //Console.WriteLine(s);
- char[] arr = s.ToCharArray();
- for (int i = 0; i < arr.Length; i++)
- {
- right = false;
- for (int j = 0; j < count; j++)
- {
- if (arr[i] == mas[j]) right = true;
- }
- if (arr[i] == 'Л') right = false;
- if (!right) { Console.WriteLine("Ошибка в введенной строке!\nПроверьте правильность строки!"); break; }
- }
- if (right) return true;
- else return false;
- }
- public static int Menu(string sentence, ref int n)
- {
- bool Catch_Mist = false;
- Console.WriteLine(sentence);
- Console.WriteLine("1 - да\n2 - нет");
- do
- {
- Catch_Mist = int.TryParse(Console.ReadLine(), out n);
- if (!Catch_Mist) Console.WriteLine("Ошибка ввода! Повторите ввод.");
- if (Catch_Mist && (n > 2 || n < 1)) { Catch_Mist = false; Console.WriteLine("Ошибка ввода! Повторите ввод."); }
- } while (!Catch_Mist);
- return n;
- }
- static void Main(string[] args)
- {
- Console.Title = "Интерпретатор нормальных алгорифмов Маркова";
- Console.ForegroundColor = ConsoleColor.Yellow;
- Console.WriteLine("Вас приветствует программа \"Интерпретатор нормальных алгорифмов Маркова\"!");
- Console.WriteLine(@"Для лучшего отображения информации в окне советуем развернуть его на полный экран.
- Обратите внимание:
- Максимальное количество символов (по количеству разрешенных для использования): 45.
- Максимальное количество правил: 100.
- Максимальное количество шагов: 5000.
- Приятной работы!
- ");
- Console.ResetColor();
- bool right = false;
- int n = 0, zachod = 0, results = 0;
- string s;
- int count = 0;
- char[] mas;
- Rules[] rules = new Rules[100];
- do
- {
- do
- {
- mas = Alphabet(ref count);
- Print(mas, count);
- Menu("Хотите внести поправки в алфавит (ввести алфавит заново)?", ref n);
- } while (n == 1);
- Menu("Ввести правила из файла (в ином случае - ввод вручную)?", ref n);
- switch (n)
- {
- case 1:
- {
- rules = RulesFromFile(mas);
- Print(rules);
- break;
- }
- case 2:
- {
- do
- {
- rules = Rule(mas);
- Print(rules);
- Menu("Хотите внести поправки в правила (ввести правила заново)?", ref n);
- } while (n == 1);
- break;
- }
- }
- do
- {
- do
- {
- Console.WriteLine("Введите строку для обработки: ");
- s = Console.ReadLine();
- s = s.Trim();
- if (s == "") { Console.WriteLine("Строка пуста! Повторите ввод."); right = false; }
- else right = CheckString(ref s, count, mas);
- } while (!right);
- Menu("Хотите ли вы видеть промежуточные результаты?", ref results);
- Markov(ref s, rules, ref zachod, results);
- if (zachod == 5000) Console.WriteLine("Процесс зациклился или для его выполнения необходимо больше 5000 шагов.");
- else Console.WriteLine("Окончательный результат: " + s);
- zachod = 0;
- Menu("Хотите ввести другую строку для заданных правил?", ref n);
- } while (n == 1);
- Menu("Хотите поработать с другим алфавитом и правилами?", ref n);
- } while (n == 1);
- Console.ForegroundColor = ConsoleColor.Yellow;
- Console.WriteLine(@"Программа завершила свою работу.
- Спасибо, что воспользовались данным интерпретатором!
- Нажмите любую клавишу, чтобы закрыть окно...");
- Console.ResetColor();
- Console.ReadLine();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement