KDPoid
Full Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору spajwan ...И вот теперь, когда вы получили громоздкий, корявый и неуклюжий код из циклов, сравните насколько меньше букв надо колотить, если владеть рекурсией... В форме заводим кнопку, для старта, мемо для вывода результата: Код: TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); ... | В приватной части объявляем мозговище: Код: private Elements : Array of String; // Кусочки из которых мы собираем. // Функция, которая всё и делает. // WS - Текущая строка, которую ещё надо собирать // Res - Часть решения, которое мы уже нашли. procedure Analyze(const WS, Res : String); ... | На кнопку вешаем запуск: Код: procedure TForm1.Button1Click(Sender: TObject); begin // Начальные значения доступных элементов. SetLength(Elements,10); Elements[0] := 'BCDEFG'; Elements[1] := 'GDFA'; Elements[2] := 'BCDE'; Elements[3] := 'EFG'; Elements[4] := 'ABC'; Elements[5] := 'FG'; Elements[6] := 'GF'; Elements[7] := 'D'; Elements[8] := 'F'; Elements[9] := 'A'; // Понеслась. Анализируем строку ABCDEFG, решение у нас пустое Analyze('ABCDEFG',''); end; | Ну и сама функция чистого самопознания: Код: Procedure TForm1.Analyze(const WS, Res: String); var i: integer; tmpS: string; begin // Цикл по всем элементам. Мы не паримся, сколько их, поэтому от первого до последнего. for i:= Low(Elements) to High(Elements) do begin if WS = Elements[i] then // если текущий элемент - это вся строка, значит мы нашли конец решения begin // Выводим итоговое решение в мемо. Начало, которое к нам пришло, и конец, который мы обнаружили. if Res<>EmptyStr then memo1.Lines.Add(Res+'+'+WS) else memo1.Lines.Add(Res+WS); end else begin // текущий элемент - не конец. // Выделим из анализируемой строки начало, равное длине нашего элемента. Для удобства. tmpS := copy(WS,1,Length(Elements[i])); if tmpS = Elements[i] then // Если начало строки равно текущему элементу, значит это середина решения. begin // Из анализируемой строки уберём начало, равное нашему элементу, и прибавим его к решению. // А потом вызовем новый экземпляр Analyze, с остатком целевой строки и уже найденной частью решения. // Пусть она поищет продолжения. if Res<>EmptyStr then Analyze(Copy(WS, Length(tmpS)+1, Length(WS) - Length(tmpS)), Res + '+' + tmpS) else Analyze(Copy(WS, Length(tmpS)+1, Length(WS) - Length(tmpS)), Res + tmpS); end; end; end; end; | Вот и всё. Попробуйте наколотить это всё в свой проект. Включите отображение локальных переменных, стека, watch list, в который добавьте просмотр Elements[i]. Пройдитесь по алгоритму по шагам, при помощи F8-F7. Возможно, понадобится карандаш, 4 листа бумаги и литр колы. Этого достаточно, чтобы понять, как эта штука работает. Надеюсь, вам хватит самоуважения разобраться, а не копипастить. | Всего записей: 404 | Зарегистр. 08-08-2006 | Отправлено: 10:28 20-02-2016 | Исправлено: KDPoid, 09:33 23-02-2016 |
|