1

Тема: Завдання на роботу зі строками

Вітаю.

Щось не можу опанувати одну задачку на роботу зі строками.

Створити програму, яка перевіряє, чи можна сформувати заданий рядок S з двох інших рядків: P1 і P2.
Умова в тому, що символи в P1 і P2 мають бути в тому самому порядку, що й у S.
(Не можу збагнути як раз, як написати перевірку на те, що символи у рядках P1 та P2 стоять у тому самому порядку як у S)

Приклад: 'radency' можна сформувати за допомогою 'rdnc’ та 'aey':
S : r a d e n c y  = radency
P1: r   d   n c    = rdnc
P2:   a   e     y  = aey

Ще варіанти для перевірки:

S = '8TaWpbgs8oaw68P86QT', P1 = '8TaWpbgs8', P2 = 'oaw68P86QTT'
Expected: False

S = 'iMZUyH I6 V8c8VAi03', P1 = 'iMUH 88i', P2 = 'Zy I6VcVA03'
Expected: True

S = 'radency', P1 = 'rade', P2 = 'ncyy'
Expected: False

S = 'w27y7', P1 = '27', P2 = 'w7y'
Expected: True

S = 'Ky5x3dsjeN5hoMYXSP9', P1 = 'Ky5x3dsje', P2 = 'N5hoYS9MXP'
Expected: False

S = 'A8VDpB6jugQOLifiRfd', P1 = '8D6jAVpBu', P2 = 'gQOLifiRfd'
Expected: False

S = 'radency', P1 = 'rade', P2 = 'nyc'
Expected: False

S = 'Keyzx6wj6Aa03c3AFN8', P1 = 'Ke6wyzxj6', P2 = 'A033F8acAN'
Expected: False

Мій код:

public class StringChecker
{
    public static bool Check(string s, string p1, string p2)
    {
        for (int i = 0; i < s.Length; i++)
        {
            if (!p1.Contains(s[i]) && !p2.Contains(s[i]))
            {
                return false;
            }
        }

        int count = 0;

        do
        {
            if (p1.Length != 0 && p1.Contains(s[count]))
            {
                int index = p1.IndexOf(s[count]);
                p1 = p1.Remove(index, 1);
                count++;
            }
            else if (p2.Length != 0 && p2.Contains(s[count]))
            {
                int index = p2.IndexOf(s[count]);
                p2 = p2.Remove(index, 1);
                count++;
            }
            else
            {
                return false;
            }
        } while (count < s.Length);

        if (p1.Length != 0 || p2.Length != 0)
        {
            return false;
        }
        
        return true;
    }
}
Подякували: leofun011

2 Востаннє редагувалося lucas-kane (18.02.2023 23:57:15)

Re: Завдання на роботу зі строками

1. Видаляєш пропуски у всіх трьох рядах S P1 P2
2. Робиш конкатенацію P1 та P2
3. Порівнюєш S та P1 + P2

Не уважно я прочитав завдання

3 Востаннє редагувалося koala (17.02.2023 07:35:23)

Re: Завдання на роботу зі строками

Бо задача дещо нетривіальна, і в загальному випадку має складність O(n^2). Ідіть по S, шукайте в обох P1 і P2 перші відповідні символи і перевіряйте обидва варіанти на кожному кроці.

розв'язок

тільки читайте уважно: https://www.techiedelight.com/check-str … n-strings/

Подякували: Dejavu, leofun01, lucas-kane3

4

Re: Завдання на роботу зі строками

Дякую, цікава досить стаття. Про рекурсію наприклад навіть і не думав.

Тут щойно дізнався що ChatGPT запрацював в Україні, тож наведу тут приклад того що він мені побудував. Все працює.
Але як на мене то додуматись до тієї формули то теж треба ще вміти.

public class StringChecker
{
    public static bool Check(string s, string p1, string p2)
    {
        if (p1.Length + p2.Length != s.Length) {
            return false;
        }

        bool[,] dp = new bool[p1.Length + 1, p2.Length + 1];

        for (int i = 0; i <= p1.Length; i++) {
            for (int j = 0; j <= p2.Length; j++) {
                if (i == 0 && j == 0) {
                    dp[i, j] = true;
                } else if (i == 0) {
                    dp[i, j] = dp[i, j - 1] && p2[j - 1] == s[i + j - 1];
                } else if (j == 0) {
                    dp[i, j] = dp[i - 1, j] && p1[i - 1] == s[i + j - 1];
                } else {
                    dp[i, j] = (dp[i, j - 1] && p2[j - 1] == s[i + j - 1]) || (dp[i - 1, j] && p1[i - 1] == s[i + j - 1]);
                }
            }
        }

        return dp[p1.Length, p2.Length];
    }
}

5

Re: Завдання на роботу зі строками

Це останній розв'язок з мого посилання. Будуємо таблицю значень функції.

6 Востаннє редагувалося leofun01 (18.02.2023 23:19:27)

Re: Завдання на роботу зі строками

Dejavu написав:

Створити програму, яка перевіряє, чи можна сформувати заданий рядок S з двох інших рядків: P1 і P2.
Умова в тому, що символи в P1 і P2 мають бути в тому самому порядку, що й у S.

Приклад: 'radency' можна сформувати за допомогою 'rdnc’ та 'aey':
S : r a d e n c y  = radency
P1: r   d   n c    = rdnc
P2:   a   e     y  = aey

Задача цікава. Здається таку перевірку можна зробити за час O(n).
Візьмемо
S : abcxyabxyabc
P1: abcabc
P2: xyabxy
Треба буде тримати як мінімум 5 індексів по стрічках. 1 для S і по 2 для P#.

Dejavu написав:

Не можу збагнути як раз, як написати перевірку на те, що символи у рядках P1 та P2 стоять у тому самому порядку як у S

Така перевірка зайва, вона не поможе порішати початкову задачу.

7

Re: Завдання на роботу зі строками

Не вийде за O(n). Простий приклад

S = acab
P1= ab
P2= ac

Щоб було за O(n), треба на першому кроці обрати, з якого P ми беремо a. І якщо оберемо P1, то отримаємо, ніби це неможливо. А якщо на кожному кроці перевірятимемо, що буде далі, і повертатимемося назад, то це не O(n).

Подякували: leofun01, lucas-kane2

8

Re: Завдання на роботу зі строками

koala правий. Мій алгоритм обламався на прикладі:
S : xababayab
P1: abab
P2: xabay

Подякували: lucas-kane1