Я знаю, что немного опоздал на эту вечеринку; это также мой самый первый пост в StackOverflow.
Но когда я просмотрел ответы, я подумал, что смогу найти лучшее решение.
Так что мое решение - использовать несколько указателей.
Ему даже не нужно использовать какое-либо ОЗУ, поскольку для этого могут использоваться регистры.
Я не проверял код; это написано на лету.
Вам нужно будет исправить мои опечатки и отладить их, но я верю, что вы поймете эту идею.
Использование памяти: в большинстве случаев регистрируется только процессор.
Загрузка ЦП: зависит, но примерно вдвое быстрее, чем чтение строки.
Модифицирует память: №
b: строка b начало, e: строка e nd.
l: l в верхнем положении, r: r в вертикальном положении.
с: с хар, м: м атч чар
если r достигнет конца строки, мы добьемся успеха.
Я идет назад от г к б.
Всякий раз, когда r встречает новый стартовый тип, установите l = r.
когда я достигну b, мы закончим с блоком; перейти к началу следующего блока.
const char *chk(const char *b, int len) /* option 2: remove int len */
{
char c, m;
const char *l, *r;
e = &b[len]; /* option 2: remove. */
l = b;
r = b;
while(r < e) /* option 2: change to while(1) */
{
c = *r++;
/* option 2: if(0 == c) break; */
if('(' == c || '{' == c || '[' == c)
{
l = r;
}
else if(')' == c || ']' == c || '}' == c)
{
/* find 'previous' starting brace */
m = 0;
while(l > b && '(' != m && '[' != m && '{' != m)
{
m = *--l;
}
/* now check if we have the correct one: */
if(((m & 1) + 1 + m) != c) /* cryptic: convert starting kind to ending kind and match with c */
{
return(r - 1); /* point to error */
}
if(l <= b) /* did we reach the beginning of this block ? */
{
b = r; /* set new beginning to 'head' */
l = b; /* obsolete: make left is in range. */
}
}
}
m = 0;
while(l > b && '(' != m && '[' != m && '{' != m)
{
m = *--l;
}
return(m ? l : NULL); /* NULL-pointer for OK */
}
Подумав некоторое время об этом подходе, я понял, что он не будет работать так, как сейчас.
Проблема будет в том, что если у вас есть «[() ()]», произойдет сбой при достижении «]».
Но вместо того, чтобы удалить предложенное решение, я оставлю его здесь, так как на самом деле это не невозможно заставить его работать, хотя оно требует некоторой модификации.