Częściowe/procentowe porównanie string'ów - czy jest coś takiego? Ewentualnie może jest jakiś algorytm do takiego przypadku?

0

Mam klasę która reprezentuje nazwę programu wgrywanego do urządzenia. Taki program w danej chwili jest jedynym obowiązującym.
Mój "system" w pewnym etapie produkcji urządzeń porównuje program wgrany do urządzenia z obecnie obowiązującym/zatwierdzonym wzorcem.

Problem zaczyna się gdy do jednego urządzenia wgrywane są dwa albo więcej programów (bo urządzenie ma więcej procków i do każdego idzie inny program).
Na razie jest tak ze:

  • sprawdzam czy nazwy programów - wzorca i sprawdzanego - od pozycji 0 do pozycji "indexPozycjiWersji" są równe,
  • jeżeli tak to sprawdzam sygnatury wersji a potem
  • sygnatury rewizji.

i teraz reguły:

  • jeżeli sygnatury wersji są sobie równe oraz sygnatury rewizji są sobie równe we wzorcu i w produkowanym urządzeniu to wszystko jest ok
  • jeżeli sygnatury wersji są sobie równe ale rewizja wzorca jest wyższa niż ta w produkowanym urządzeniu to to jest dopuszczalne choć wymaga zarejestrowania w zapisach produkcyjnych
  • jeżeli sygnatura wzorca jest wyższa niż sygnatura wersji w produkowanym urządzeniu to błąd krytyczny i urządzenie ma zawracać do przeprogramowania

Największą niepewnością obarczony jest początek nazwy programu, nie mam gwarancji ze tam nic się nie zmieni. Nie mam wpływu na standard nazywania programów musze sobie poradzić z tym co jest. Początek przeważnie jest identyczny bo to nazwa urządzenia (choć nie zawsze), potem do początku sygnatury są różne rzeczy i to miejsce dużej niepewności. to co jest po rewizji jest nieistotne. Schemat nazewnictwa programów poniżej.

Lp starsza wersja nowsza wersja
1. UrzadzenieMaleZolte_tz.4.31_ASD_S012.32gdaREV123_f_d_h_w_g_a_e.asd UrzadzenieMaleZolte_tz.4.31_ASD_S012.40gdaREV123_f_d_h_w_g_a_e.asd
2. UrzDuzeZolte_ty.7.2_S098.03_REV456_f_d_h_w_g_w_a_e.asd UrzDuzeZolte_888_S098.03_REV457_f_d_h_w_g_w_a_e.asd
3. CzerwonySprzęt_S542.65poqREV763_w_a_e.asd CzerwonySprzęt_S545.65poqREV812_w_a_e.asd

i teraz przypadek gdy w jednym urządzeniu są dwa programy nr.1 i nr.2,

  1. Jak mam rozpoznać aby do programu wzorcowego nr 2 na pewno porównywać program wgrany nr 2, a do wzorcowego nr1 porównywać wgrany nr1 , żeby ich nie skrosowac?
  2. Jak mam uodpornić system na nieistotne różnice w nazwie programu miedzy nazwa urządzenia a sygnatura wersji? W przykładzie nr.2. w starszym programie jest "ty.7.2" a w nowszym, który jest nowszy tylko o wartość rewizji pojawiło sie 888. jeżeli będę porównywał tylko początki nazw plików to otrzymam porównanie:
    UrzDuzeZolte_ty.7.2_ != UrzDuzeZolte_888_ czyli system zinterpretuje ze to są różne programy a tak naprawdę przy takiej zmianie rewizji powinny zostać dopuszczone. Myslalem o przyrostowym pomiarze poczatkó stringa np. porownuje pozycje 0 do 0 potem 1 do 1 potem 2 do 2 itp. ale wtedy musiałbym jakoś określić procentowo dopuszczalność różnic pomiędzy stringami od pozycji "0"do "indexPozycjiWersji"- są takie algorytmy na takie problemy?
public class DaneProgramu
    {
        //zaimplementowac IComparer, ma byc wiadomo ktory program jest nowszy ktory starszy

        private readonly string regexSygnaturaWersjiProgramu = @"S[0-9]{2,3}?\.[0-9]{2}";
        private readonly string regexSygnaturyRewizjiProgramu = @"REV\d{2,3}";

        private string nazwaPlikuProgramu;
        public string NazwaPlikuProgramu
        {
            get { return nazwaPlikuProgramu; }
            private set { nazwaPlikuProgramu = value; }
        }

        private string sygnaturaWersjiProgramu;
        public string SygnaturaWersjiProgramu
        {
            get { return sygnaturaWersjiProgramu; }
            private set { sygnaturaWersjiProgramu = value; }
        }

        private int indexPozycjiWersji;
        public int IndexPozycjiWersji
        {
            get { return indexPozycjiWersji; }
            private set { indexPozycjiWersji = value; }
        }

        private int dlugoscSygnaturyWersji;
        public int DlugoscSygnaturyWersji
        {
            get { return dlugoscSygnaturyWersji; }
            private set { dlugoscSygnaturyWersji = value; }
        }

        private string sygnaturaRewizjiProgramu;
        public string SygnaturaRewizjiProgramu
        {
            get { return sygnaturaRewizjiProgramu; }
            private set { sygnaturaRewizjiProgramu = value; }
        }

        private int indexPozycjiRewizji;
        public int IndexPozycjiRewizji
        {
            get { return indexPozycjiRewizji; }
            set { indexPozycjiRewizji = value; }
        }

        private int dlugoscSygnaturyRewizji;
        public int DlugoscSygnaturyRewizji
        {
            get { return dlugoscSygnaturyRewizji; }
            set { dlugoscSygnaturyRewizji = value; }
        }


        public DaneProgramu(string nazwaPliku)
        {
            NazwaPlikuProgramu = nazwaPliku.ToUpper();

            if (WyszukajSygnaturyWersji(NazwaPlikuProgramu))
            {
                WyszukajSygnaturyRewizji(NazwaPlikuProgramu);
            }
        }

        private bool WyszukajSygnaturyWersji(string nazwa)
        {
            bool wynik = false;

            if (Regex.IsMatch(nazwa, regexSygnaturaWersjiProgramu))
            {
                Match matchWersji = Regex.Match(nazwa, regexSygnaturaWersjiProgramu);

                SygnaturaWersjiProgramu = matchWersji.Value; //S001.13
                IndexPozycjiWersji = matchWersji.Index;
                DlugoscSygnaturyWersji = matchWersji.Length;

                wynik = true;
            }
            else
            {
                SygnaturaWersjiProgramu = string.Empty;
                IndexPozycjiWersji = 0;
                DlugoscSygnaturyWersji = 0;
            }

            return wynik;
        }
        private bool WyszukajSygnaturyRewizji(string nazwa)
        {
            bool wynik = false;

            if (Regex.IsMatch(nazwa, regexSygnaturyRewizjiProgramu))
            {
                Match matchRewizji = Regex.Match(nazwa, regexSygnaturyRewizjiProgramu);

                SygnaturaRewizjiProgramu = matchRewizji.Value;
                IndexPozycjiRewizji = matchRewizji.Index;
                DlugoscSygnaturyRewizji = matchRewizji.Length;

                wynik = true;
            }
            else
            {
                SygnaturaRewizjiProgramu = String.Empty;
                IndexPozycjiRewizji = 0;
                DlugoscSygnaturyRewizji = 0;
            }

            return wynik;
        }

        public override string ToString()
        {
            return $"|{NazwaPlikuProgramu.Substring(0, indexPozycjiWersji)}:  " +
                $"|Wersja: {SygnaturaWersjiProgramu.PadRight(20, ' ')}" +
                $"| Rewizja: {SygnaturaRewizjiProgramu.PadRight(20, ' ')}|";
        }
    }
5

Generalnie straciłem wątek ale radzę zrobić tak:

  • Regexem parsuj nazwy programów, podziel je na części i postaraj się wyciągnąć te na których ci zależy typu S933.32 czy REV324. Potem porównuj te sparsowane.

Procentowe porównywanie stringów to znana z kursu algosów https://pl.m.wikipedia.org/wiki/Odleg%C5%82o%C5%9B%C4%87_Levenshteina

1 użytkowników online, w tym zalogowanych: 0, gości: 1