Другие языки программирования и технологии

Ошибка в программе delphi. Рекурсия

Нужна рекурсивная функция, проверяющая правильность постановки скобок [] ().Пример неправильной расстановки ([)].Вот что получилось пока только с одним типом скобок. Нужно добавить еще одни скобки []. Использовал рекурсию вместо цикла for. Как выходной параметр индекс элемента строки. Вроде работает, но выводит в конце индекс 0. Как это исправить? В чем ошибка? И как добавить еще одни скобки в условие (Чтобы не проходить всю строку еще раз.), т. е чтобы строка состояла из 2 типов скобок () и []? Помогите пожалуйста, заранее спасибо.
Код Delphi1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
program Project2;

{$APPTYPE CONSOLE}

uses
SysUtils;

var
s: string;
i,count: integer;

function rec(i:integer;s:string):integer;
begin

if (s[i] = '(') and (count >= 0) then
Inc(count);
if s[i] = ')' then
Dec(count);

{ if (s[i] = '[') and (count >= 0) then
Inc(count);
if s[i] = ']' then
Dec(count);
}
inc(i);
if (i<=length(s)) then
rec(i,s)
else
begin
if count = 0 then
WriteLn('Yes')
else
WriteLn('No');

exit;
end;
end;



begin
count := 0;//j,yekztncz ghb ds[jlt
i:=1;
s:='(()())';
writeln(rec(i,s)); //индекс -0, но робит странно


end.
{ for i := 1 to Length(s) do //сделать как рекурсию индекс
begin
if (s[i] = '(') and (count >= 0) then
Inc(count);
if s[i] = ')' then
Dec(count);
if (s[i] = '[') and (count >= 0) then
Inc(count);
if s[i] = ']' then
Dec(count);
end;}
> Вйцало Бурдяйко
> Использовал рекурсию вместо цикла for
У вас, извиняюсь, какое-то г. . но, а не рекурсия. И кстати, почему вы таки не хотите использовать стек явно, как вам предложили выше, почему нужна именно рекурсия?

> Ponyfag1337
> Разве это рекурсивная задача?
> По-моему, она решается стеком.
Тык рекурсия использует стек во все поля, только неявно.

> Алексей Кузьминов
> Заранее сообщаю, что одну рекурсивную однопроходную функцию для двух
типов скобок написать нельзя (точнее: можно, но это на порядок усложнит
реализацию)
Да ладно, "на порядок усложнит". Вот три типа скобок, ну может быть чуть-чуть сложнее.

procedure f(var s: string; var p: integer);
var
c: char;
begin
if (p <= length(s)) and (s[p] in ['(', '[', '{']) then begin
case s[p] of
'(': c := ')';
'[': c := ']';
'{': c := '}';
end;
inc(p);
f(s, p);
if (p > length(s)) or (s[p] <> c) then begin
p := 0;
exit;
end;
inc(p);
f(s, p);
end;
end;

var
s: string;
p: integer;
begin
readln(s);
p := 1;
f(s, p);
if p > length(s) then writeln('yes') else writeln('no');
end.

Входной строкой для данной программы может быть строка, состоящая ТОЛЬКО из скобок разного типа ( '(', '{', '[', ']', '}', ')' ). Если у вас может быть строка, которая, кроме скобок может содержать другие символы, то напишите подпрограмму, которая удалит из исходной строки все символы, кроме скобок, а потом к получившейся строке уже и примените рекурсивную подпрограмму.
Вася Пупкин
Вася Пупкин
99 225
Лучший ответ
я тупо рисовал вложенные скобки и прикидывал как вычленить нужную. в конце концов получился парсер для json строки )).
Да, циклами тут делать нечего! рекурсия, это вызов функцией саму себя. а у вас тупо-цикл
Mussa ______
Mussa ______
84 502
Разве это рекурсивная задача?
По-моему, она решается стеком.
Подозрительный вопрос: проверить соответствие СТРАННО работающей (читай НЕРАБОТАЮЩЕЙ) программы условиям нечётко поставленной задачи.
Предполагаю, что вам нужна ИМЕННО рекурсивная функция, которая проверяет правильность расстановки скобок ДВУХ типов, других символов в строке нет. (а может больше? - есть еще фигурные, угловые, двойные угловые. . )

Имхо, для написания рекурсивных функций нужно ПИСЬМЕННО СФОРМУЛИРОВАТЬ шаг рекурсии. Желательно в комментариях программы.

Заранее сообщаю, что одну рекурсивную однопроходную функцию для двух типов скобок написать нельзя (точнее: можно, но это на порядок усложнит реализацию) .
Можно попробовать написать функции, возвращающие позицию корректной закрывающей скобки типа 1/типа 2 или -1, если не обнаружена. Параметром будет номер текущей позиции как ссылка.

Пример алгоритма для функции '(' с позицией р.
Бесконечный цикл:
1. р - конец строки - вернуть -1, так как была открывающая (, а строка закончилась.
2. Т присвоить -2, на всякий случай, потом всё равно затрется.
3. case символ [р]
'(': запустить себя от р+1, результат занести в переменную Т
'{': запустить соседку от р+1, результат занести в переменную Т
')': вернуть р, выйти
'}': вернуть -1, выйти
что-то другое: вывести 'неверный символ в позиции ', р, ': ', символ [р] , выйти
4. проверить Т:
<= 0: вывести 'нет закрывающей для скобки ( в позиции ', р, вернуть -1, выйти - вывод для отладки, потом убрать
>0 р присвоить Т+1 - вернулись из проверки вложенных и снова ищем закрывающую

Вызвать из похожего бесконечного цикла:
1. р - конец строки вывести 'ОК', если строка не пустая, иначе вывести 'строка нулевой длины', выйти в обоих случаях
2. Т присвоить -2, на всякий случай, потом всё равно затрется.
3. case символ [р]
'(', '{': запустить нужную функцию от р+1, результат занести в переменную Т
что-то другое: вывести 'неверный символ в позиции ', р, ': ', символ [р] , выйти
4. проверить Т:
<= 0: вывести 'нет закрывающей скобки в позиции ', р, выйти
>0 р присвоить Т+1 - вернулись из проверки вложенных и снова ищем закрывающую

Искренне надеюсь, что заработает.