Премини към съдържанието
  • Добре дошли!

    Добре дошли в нашите форуми, пълни с полезна информация. Имате проблем с компютъра или телефона си? Публикувайте нова тема и ще намерите решение на всичките си проблеми. Общувайте свободно и открийте безброй нови приятели.

    Моля, регистрирайте се за да публикувате тема и да получите пълен достъп до всички функции.

     

Задача по c# - търсене на подстрингове в даден стринг спрямо специфични правила.


underfree22

Препоръчан отговор

Здравейте,

Закъсал съм го с едно упражнение. 

Потребителя подава един голям стринг - състоящ се от букви, цифри и специални знаци. 

Да кажем имаме пет подстринга - S1, S2, S3, S4, S5, всичките имащи дадено правило:

S1 - Две цифри, еднакви, повтарящи се - 11, 22, 55, 44 и т.н - примерно

S2 - Една или повече букви lower case - а, dsa, adsadsa ... - неограничен брой букви.

S3 - Двойка букви в интервала a - d - примерно ab, ac, ad, da ....

S4 - Три еднакви цифри - 111, 333, 555 ....

S5 - Същата стойност като S3.

Идеята е следната:

След като потребителя подаде стринг ние трябва да проверим дали този стринг съдържа комбинация от тези пет подстринга, подредени точно в реда S1, S2, S3, S4, S5 - Залепени плътно един за друг.

S1, S3, S2, ... - Неправилно

S1, S1, S2, S3, S4, S5 - Правилно, понеже имаме една комбинация s1 - s5. 

S1, S2, (нещо, различно от s3), S3, S4, S5 - Неправилно.

Примерен инпут - ::??!:1dasw88kqlbc333bclqpelk?-

Тук:

 

s1 = 88

s2 = kql

s3 = bc

s4 = 333

s5 = bc

Имаме комбинация от стринговете, последователна, в правилния ред => правилно. 

Ето и моят опит да реша програмата:

class strings
{
    static void Main(string[] args)
    {

        string input;
        string s1Pattern = @"(\d)\1";
        string s2Pattern = @"[a-z]+";
        string s3Pattern = @"[abcd]{2}";
        string s4Pattern = @"(\d)\1{2}";
        string s5Pattern = @"[abcd]{2}";

        input = Console.ReadLine();
        MatchCollection s1Matches = Regex.Matches(input, s1Pattern);
        MatchCollection s2Matches = Regex.Matches(input, s2Pattern);
        MatchCollection s3Matches = Regex.Matches(input, s3Pattern);
        MatchCollection s4Matches = Regex.Matches(input, s4Pattern);
        MatchCollection s5Matches = Regex.Matches(input, s5Pattern);


        if (s1Matches.Count >= 1 &&
            s2Matches.Count >= 1 &&
            s3Matches.Count >= 1 &&
            s4Matches.Count >= 1 &&
            s5Matches.Count >= 1)
        {
            int s1Index = s1Matches[0].Index;
            int s2Index = s2Matches[0].Index;
            int s3Index = s3Matches[0].Index;
            int s4Index = s4Matches[0].Index;
            int s5Index = s5Matches[0].Index;

            if (s1Index < s2Index && s2Index < s3Index && s3Index < s4Index && s4Index < s5Index)
            {
                Console.WriteLine("The pattern is correct.");
            }
        }
    }
}

 

Регекс патърните са правилни - връщат каквото очаквам. Проблема е, че връщат повече стойности, от тези които очаквам - тъй като множество подстрингове отговарят на условието. Например s1Matches има два записа - 33 и 88, но в по-горния пример само 88 ме удовлетворява. Как трябва да го доразработя, така че да покрия всичките проверки? 

Всякаква помощ би била полезна.

Благодаря :)

Линк към коментара
Сподели в други сайтове

 Тази задача се решава с един Regular Expression!

(?:1{2}|2{2}|3{2}|4{2}|5{2}|6{2}|7{2}|8{2}|9{2}|0{2})(?:[a-z]+)(?:[a-d]{2})(?:1{3}|2{3}|3{3}|4{3}|5{3}|6{3}|7{3}|8{3}|9{3}|0{3})(?:[a-d]{2})

За повече ясност всяко от условията е затворено в Non-capturing group.

Условия 2, 3 и 5 не се нуждаят от групиране, така че можеш да си поиграеш да махнеш групиращите символи ако искаш...

 

Ето тук, можеш да експериментираш...

 

Успех!

 

Линк към коментара
Сподели в други сайтове

  • 2 седмици по-късно...

Ботът ChatGPT дава следният код:

Here is a sample code in C# to check if the given string contains a combination of the five substrings in the correct order (S1, S2, S3, S4, S5):

using System;
using System.Text.RegularExpressions;

namespace StringChecker
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = "::??!:1dasw88kqlbc333bclqpelk?-";

            string pattern = @"(\d{2})([a-z]+)([abcd]{2})(\d{3})([abcd]{2})";
            bool isMatch = Regex.IsMatch(input, pattern);

            Console.WriteLine("Is match: " + isMatch);
        }
    }
}

Explanation:

  • pattern variable is a regular expression that matches the given substrings in the correct order (S1, S2, S3, S4, S5).
  • (\d{2}) matches two consecutive digits (S1).
  • ([a-z]+) matches one or more lowercase letters (S2).
  • ([abcd]{2}) matches two consecutive letters from 'a' to 'd' (S3 and S5).
  • (\d{3}) matches three consecutive digits (S4).
  • The Regex.IsMatch method returns true if the given string matches the pattern, otherwise false.

Още едно допълнение от бота:

За да проверявате само първите записи, които отговарят на всички патерни, можете да използвате по-ефективен алгоритъм. Един от възможните начини е да преброявате всеки патерн, и да запазвате индексите на първото съвпадение за всеки от тях. След това можете да проверявате дали тези индекси са в правилния ред, като сравнявате стойностите им. Например:

class strings
{
    static void Main(string[] args)
    {

        string input;
        string s1Pattern = @"(\d)\1";
        string s2Pattern = @"[a-z]+";
        string s3Pattern = @"[abcd]{2}";
        string s4Pattern = @"(\d)\1{2}";
        string s5Pattern = @"[abcd]{2}";

        input = Console.ReadLine();
        Match s1Match = Regex.Match(input, s1Pattern);
        Match s2Match = Regex.Match(input, s2Pattern);
        Match s3Match = Regex.Match(input, s3Pattern);
        Match s4Match = Regex.Match(input, s4Pattern);
        Match s5Match = Regex.Match(input, s5Pattern);

        if (s1Match.Success &&
            s2Match.Success &&
            s3Match.Success &&
            s4Match.Success &&
            s5Match.Success)
        {
            int s1Index = s1Match.Index;
            int s2Index = s2Match.Index;
            int s3Index = s3Match.Index;
            int s4Index = s4Match.Index;
            int s5Index = s5Match.Index;

            if (s1Index < s2Index && s2Index < s3Index && s3Index < s4Index && s4Index < s5Index)
            {
                Console.WriteLine("The pattern is correct.");
            }
        }
    }
}

 

Линк към коментара
Сподели в други сайтове

Добавете отговор

Можете да публикувате отговор сега и да се регистрирате по-късно. Ако имате регистрация, влезте в профила си за да публикувате от него.

Гост
Публикацията ви съдържа термини, които не допускаме! Моля, редактирайте съдържанието си и премахнете подчертаните думи по-долу. Ако замените букви от думата със звездички или друго, за да заобиколите това предупреждение, профилът ви ще бъде блокиран и наказан!
Напишете отговор в тази тема...

×   Вмъкнахте текст, който съдържа форматиране.   Премахни форматирането на текста

  Разрешени са само 75 емотикони.

×   Съдържанието от линка беше вградено автоматично.   Премахни съдържанието и покажи само линк

×   Съдържанието, което сте написали преди беше възстановено..   Изтрий всичко

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Добави ново...