using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace REG_MARK_LIB { public class REG_MARK_LIB { //Список номеров регионов государства public static int[] REG = { 190, 177, 199, 977, 102, 103, 277, 297, 299, 111, 113, 116, 118, 121, 122, 125, 126, 130, 134, 136, 142, 147, 750, 152, 154, 155, 156, 158, 161, 163, 164, 172, 173, 174, 197, 777, 180, 181, 777, 184, 185, 186, 702, 716, 123, 725, 138, 150, 790, 252, 754, 159, 761, 763, 166, 774, 797, 178, 193, 124, 196, 799, 198}; /// /// Метод, направленный на проверку корректности номера автомобиля /// /// номер /// true - номер авто правильный, false - номер авто не правильный public static bool CheckMark(string mark) { Regex regex = new Regex(@"^[a,b,e,k,m,h,o,p,c,t,y,x]{1}[0-9]{3}[a,b,e,k,m,h,o,p,c,t,y,x]{2}[0-9]{2,3}$", RegexOptions.IgnoreCase); if (!regex.IsMatch(mark)) return false; if (mark[6..mark.Length].Length == 2) return true; if (mark[6..mark.Length].Length == 3 && REG.Where(i => i == Convert.ToInt32(mark[6..mark.Length])).FirstOrDefault() != default) return true; return false; } /// /// Метод, для получения следующего номера по порядку /// /// номер /// следующий по порядку номер /// Возникает, когда номер не правильный /// Возникает, когда следующий номер найти невозможно public static string GetNextMarkAfter(string mark) { if (!CheckMark(mark)) throw new ArgumentException(); int[] numbers = ConvertMarkToInts(mark); //Проверки существования номера if (numbers[1] == 999) { if (numbers[0] == 21) { if (numbers[3] == 21) { if (numbers[2] == 21) throw new Exception("Следующего номера не существует!"); else { numbers[2] += 1; numbers[3] = 10; numbers[1] = 1; numbers[0] = 10; } } else { numbers[3] += 1; numbers[1] = 1; numbers[0] = 10; } } else { numbers[0] += 1; numbers[1] = 1; } } else numbers[1] += 1; return ConvertIntsMarkToString(numbers); } /// /// Метод, для получения следующего по порядку номера, в заданных границах /// /// номер, для которого будет осуществляться поиск /// нижняя граница /// верхняя граница /// следующий номер по порядку /// Возникает, когда строка аргумента не является валидным номером /// Возникает, когда следующий номер найти невозможно public static string GetNextMarkAfterInRange(string prevMark, string rangeStart, string rangeEnd) { if (!CheckMark(prevMark) || !CheckMark(rangeStart) || !CheckMark(rangeEnd)) throw new ArgumentException(); if (CompareMarks(rangeStart, rangeEnd) == -1) return "out of stock"; string newMark = GetNextMarkAfter(prevMark); if (CompareMarks(rangeStart, prevMark) == -1 || CompareMarks(prevMark, rangeEnd) == -1) return "out of stock"; return newMark; } /// /// Метод, для поиска количества номеров, в заданных границах /// /// первая граница счета /// вторая граница счета /// количество номеров в диапазоне, включая границы /// Границы не являются правильными автомобильными номерами public static int GetCombinationsCountInRange(string markone, string marktwo) { if (!CheckMark(markone) || !CheckMark(marktwo)) throw new ArgumentException(); int counter = 1; string codeone, codetwo; switch (CompareMarks(markone, marktwo)) { case 1: { codeone = markone; codetwo = marktwo; break; } case -1: { codeone = marktwo; codetwo = markone; break; } default: return 1; } while (codeone != codetwo) { codeone = GetNextMarkAfter(codeone); counter++; } return counter; } /// /// Метод, преобразовывающий номер в массив чисел /// /// номер /// массив чисел private static int[] ConvertMarkToInts(string mark) { mark = mark.ToUpper(); int[] result = new int[mark.Length - 2]; //Коллекция с ключами и значениями. Ключи - буквы номера. Значения - цифры номера Dictionary keyValuePairs = new Dictionary { { 'A', 10 }, { 'B', 11 }, { 'E', 12 }, { 'K', 13 }, { 'M', 14 }, { 'H', 15 }, { 'O', 16 }, { 'P', 17 }, { 'C', 18 }, { 'T', 19 }, { 'Y', 20 }, { 'X', 21 }, { '0', 0 }, { '1', 1 }, { '2', 2 }, { '3', 3 }, { '4', 4 }, { '5', 5 }, { '6', 6 }, { '7', 7 }, { '8', 8 }, { '9', 9 } }; result[0] = keyValuePairs[mark[0]]; result[1] = Convert.ToInt32(mark[1..4]); for (int i = 4; i < mark.Length; i++) result[i - 2] = keyValuePairs[mark[i]]; return result; } /// /// Метод, преобразующий массив на основе номера в текстовый вариант номера /// /// массив на основе номера /// номер private static string ConvertIntsMarkToString(int[] mark) { StringBuilder markString = new StringBuilder(); Dictionary keyValuePairs = new Dictionary { { 10, 'A' }, { 11, 'B' }, { 12, 'E' }, { 13, 'K' }, { 14, 'M' }, { 15, 'H' }, { 16, 'O' }, { 17, 'P' }, { 18, 'C' }, { 19, 'T' }, { 20, 'Y' }, { 21, 'X' }, { 0, '0' }, { 1, '1' }, { 2, '2' }, { 3, '3' }, { 4, '4' }, { 5, '5' }, { 6, '6' }, { 7, '7' }, { 8, '8' }, { 9, '9' } }; markString.Append(keyValuePairs[mark[0]]); StringBuilder sb = new StringBuilder(mark[1].ToString()); while (sb.Length < 3) { sb = new StringBuilder("0" + sb.ToString()); } markString.Append(sb.ToString()); for (int i = 2; i < mark.Length; i++) markString.Append(keyValuePairs[mark[i]]); return markString.ToString(); } /// /// Метод, сравнивающий два номера в соответствии с установленным порядком /// /// Номер для сравнения 1 /// Номер для сравнения 2 /// 1 - номер 2 больше; -1 - номер 1 больше; 0 - номера одинаковы private static int CompareMarks(string strForCompOne, string strForCompTwo) { int[] codeone = ConvertMarkToInts(strForCompOne); int[] codetwo = ConvertMarkToInts(strForCompTwo); if (codetwo[2] > codeone[2]) return 1; else if (codetwo[2] < codeone[2]) return -1; else { if (codetwo[3] > codeone[3]) return 1; else if (codetwo[3] < codeone[3]) return -1; else { if (codetwo[0] > codeone[0]) return 1; else if (codetwo[0] < codeone[0]) return -1; else { if (codetwo[1] > codeone[1]) return 1; else if (codetwo[1] < codeone[1]) return -1; else return 0; } } } } } }