Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Реализация функции

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: Проверка на корректность написания скобок
Mandalorian
Отправлено: 24 Ноября, 2021 - 14:10:17
Post Id


Новичок


Покинул форум
Сообщений всего: 16
Дата рег-ции: Сент. 2021  


Помог: 0 раз(а)




Здравствуйте! Стоит вот такая задача.

Реализуйте функцию isBalanced, которая принимает на вход строку, состоящую только из открывающих и закрывающих круглых скобок, и проверяет, является ли эта строка корректной. Пустая строка (отсутствие скобок) считается корректной.

Строка считается корректной (сбалансированной), если содержащаяся в ней скобочная структура соответствует требованиям:

Скобки — это парные структуры. У каждой открывающей скобки должна быть соответствующая ей закрывающая скобка.
Закрывающая скобка не должна идти впереди открывающей. Такой вариант недопустим )(, а вот такой допустим ()().

PHP:
скопировать код в буфер обмена
  1.  
  2. isBalanced('(())');  // true
  3. isBalanced('((())'); // false
  4.  


Написал решение такого плана:

PHP:
скопировать код в буфер обмена
  1.  
  2. function isBalanced($str) {
  3. $length = strlen($str);    
  4. $resLeft = [];
  5. $resRight = [];
  6.    
  7. for($i = 0; $i < $length; $i++){
  8. if ($str[$i] === '(') {
  9.     $resLeft []= $i;
  10.     } elseif ($str[$i] === ')') {
  11.     $resRight []= $i;
  12.     }
  13. }
  14.  
  15. for($i = 0; $i < $length; $i++){
  16.  
  17. if($resLeft[$i] > $resRight[$i]) {
  18.     return false;
  19. }
  20. }
  21. return true;
  22. }
  23.  


Вроде выдает правильные ответы.

Вопрос: может можно както упростить? Или на что-то не обратил внимания.
 
 Top
Vladimir Kheifets
Отправлено: 24 Ноября, 2021 - 19:53:37
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 879
Дата рег-ции: Март 2017  
Откуда: Германия, Бавария


Помог: 37 раз(а)




Mandalorian пишет:
Здравствуйте! Стоит вот такая задача.

Реализуйте функцию isBalanced, которая принимает на вход строку, состоящую только из открывающих и закрывающих круглых скобок, и проверяет, является ли эта строка корректной. Пустая строка (отсутствие скобок) считается корректной.

Строка считается корректной (сбалансированной), если содержащаяся в ней скобочная структура соответствует требованиям:

Скобки — это парные структуры. У каждой открывающей скобки должна быть соответствующая ей закрывающая скобка.
Закрывающая скобка не должна идти впереди открывающей. Такой вариант недопустим )(, а вот такой допустим ()().

Вопрос: может можно както упростить?


Здравствуйте!
Может быть как-то так:
Спойлер (Отобразить)
Удачи!

(Отредактировано автором: 24 Ноября, 2021 - 19:54:18)

 
 Top
don.bidon
Отправлено: 24 Ноября, 2021 - 20:04:57
Post Id


Гость


Покинул форум
Сообщений всего: 78
Дата рег-ции: Март 2019  


Помог: 2 раз(а)




PHP:
скопировать код в буфер обмена
  1. function isBalanced($str): bool
  2. {
  3.     $length = strlen($str);
  4.     $opened = 0;
  5.  
  6.     for ($i = 0; $i < $length; $i++) {
  7.         $char = $str[$i];
  8.         if ('(' === $char) {
  9.             $opened++;
  10.         } else if (')' === $char) {
  11.             if (0 === $opened) {
  12.                 return false;
  13.             }
  14.             $opened--;
  15.         } else {
  16.             throw new InvalidArgumentException(sprintf('Invalid char "%s" at %d offset', $char, $i));
  17.         }
  18.     }
  19.     return 0 === $opened;
  20. }

Не мерил производительность, но что-то подсказывает, что str_replace() использовать жестковато как-то )
 
 Top
Mandalorian
Отправлено: 25 Ноября, 2021 - 09:20:56
Post Id


Новичок


Покинул форум
Сообщений всего: 16
Дата рег-ции: Сент. 2021  


Помог: 0 раз(а)




Всем большое спасибо!

don.bidon пишет:
$opened = 0;

don.bidon, понравилось Ваше решение со счетчиком $opened Здорово
 
 Top
Vladimir Kheifets
Отправлено: 25 Ноября, 2021 - 10:14:58
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 879
Дата рег-ции: Март 2017  
Откуда: Германия, Бавария


Помог: 37 раз(а)




don.bidon пишет:
Не мерил производительность, но что-то подсказывает, что str_replace() использовать жестковато как-то )

Добрый день!

Сравнил по производительности две функции на PHP 7.4
Получил средующие результаты:
на строке в 140 символов Ваша функция работает быстрее моей на 700 nanoseconds
Спойлер (Отобразить)
на строке в 700 символов Ваша функция работает медленее моей на 36.700 nanoseconds.
Спойлер (Отобразить)
function isBalanced don.bidon
Спойлер (Отобразить)
function isBalanced Vladimir Kheifets
Спойлер (Отобразить)
Удачи!

(Отредактировано автором: 25 Ноября, 2021 - 10:18:49)

 
 Top
don.bidon
Отправлено: 25 Ноября, 2021 - 11:54:53
Post Id


Гость


Покинул форум
Сообщений всего: 78
Дата рег-ции: Март 2019  


Помог: 2 раз(а)




Vladimir Kheifets пишет:
Сравнил по производительности две функции на PHP 7.4

А, ну C-шные либы значит шустрее будут ))
 
 Top
MouseZver
Отправлено: 16 Декабря, 2021 - 13:54:23
Post Id



Новичок


Покинул форум
Сообщений всего: 58
Дата рег-ции: Июнь 2017  
Откуда: php.ru


Помог: 1 раз(а)




Vladimir Kheifets
Твой скрипт ломается банально на одних ((( или )(( ты это должен был знать, делая ставку на скорость.


Рабочий вариант со всеми нюансами:
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2.  
  3. // принимает на вход строку, состоящую только из открывающих и закрывающих круглых скобок
  4. function MouseZver( string $string ): bool
  5. {
  6.     // Пустая строка (отсутствие скобок) считается корректной.
  7.     if ( empty ( $string ) )
  8.     {
  9.         return true;
  10.     }
  11.    
  12.     // Закрывающая скобка не должна идти впереди открывающей.
  13.     if ( $string[0] == ')' )
  14.     {
  15.         return false;
  16.     }
  17.    
  18.     // У каждой открывающей скобки должна быть соответствующая ей закрывающая скобка.
  19.     $count_first = substr_count ( $string, '(' );
  20.    
  21.     for ( $i = 0; $i < $count_first; $i++ )
  22.     {
  23.         $string = str_replace ( '()', '', $string );
  24.     }
  25.    
  26.     return empty ( $string );
  27. }
  28.  
  29. $start = microtime ( true );
  30.  
  31. var_dump ( MouseZver( str_repeat ( '((((())))()())', 50 ) ) );
  32.  
  33. echo microtime ( true ) - $start;
  34.  
  35.  
  36. echo PHP_EOL;
  37.  
  38.  
  39. $start = microtime ( true );
  40.  
  41. var_dump ( MouseZver( str_repeat ( '(((()(', 50 ) ) );
  42.  
  43. echo microtime ( true ) - $start;
  44.  
  45.  
  46. echo PHP_EOL;
  47.  
  48.  
  49. $start = microtime ( true );
  50.  
  51. var_dump ( MouseZver( str_repeat ( ')))()((', 50 ) ) );
  52.  
  53. echo microtime ( true ) - $start;

(Отредактировано автором: 16 Декабря, 2021 - 13:59:57)

 
 Top
Vladimir Kheifets
Отправлено: 17 Декабря, 2021 - 08:04:56
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 879
Дата рег-ции: Март 2017  
Откуда: Германия, Бавария


Помог: 37 раз(а)




MouseZver пишет:
Vladimir Kheifets
Твой скрипт ломается банально на одних ((( или )(( ты это должен был знать, делая ставку на скорость.
Рабочий вариант со всеми нюансами:
Спойлер (Отобразить)

Добрый день!
Спасибо за ответ. Верно, скрипт ломался банально на одних ((( или )((
Рабочий вариант со всеми нюансами:
PHP:
скопировать код в буфер обмена
  1. <?
  2. function isBalanced($str) {
  3.     while (strpos($str,"()")!== false)
  4.         $str=str_replace("()","",$str);
  5.     return empty($str);
  6. }
  7. ?>

тест функции isBalanced (25100 nanoseconds)
PHP:
скопировать код в буфер обмена
  1. <?
  2. $test=["","()()",")(",")","(", "()", "((((())))()())" ,"(()())", "(()()","(((",")(("];
  3. $time_start = hrtime(true);
  4. echo "<hr>function isBalanced Vladimir Kheifets<br>";
  5. foreach($test as $str)
  6. {
  7.         echo "str: '$str' isBalanced: ", isBalanced($str)?"true":"false","<br>";
  8. }
  9. echo "Total execution time in nanoseconds: ",hrtime(true) - $time_start;
  10. /*
  11. function isBalanced Vladimir Kheifets
  12. str: '' isBalanced: true
  13. str: '()()' isBalanced: true
  14. str: ')(' isBalanced: false
  15. str: ')' isBalanced: false
  16. str: '(' isBalanced: false
  17. str: '()' isBalanced: true
  18. str: '((((())))()())' isBalanced: true
  19. str: '(()())' isBalanced: true
  20. str: '(()()' isBalanced: false
  21. str: '(((' isBalanced: false
  22. str: ')((' isBalanced: false
  23. Total execution time in nanoseconds: 25100
  24. */
  25. ?>

тест функции MouseZver (39500 nanoseconds)
PHP:
скопировать код в буфер обмена
  1. <?
  2. $test=["","()()",")(",")","(", "()", "((((())))()())" ,"(()())", "(()()","(((",")(("];
  3. $time_start = hrtime(true);
  4. echo "<hr>function MouseZver<br>";
  5. foreach($test as $str)
  6. {
  7.         echo "str: '$str' MouseZver: ", MouseZver($str)?"true":"false","<br>";
  8. }
  9. echo "Total execution time in nanoseconds: ",hrtime(true) - $time_start;
  10. /*
  11. function MouseZver
  12. str: '' MouseZver: true
  13. str: '()()' MouseZver: true
  14. str: ')(' MouseZver: false
  15. str: ')' MouseZver: false
  16. str: '(' MouseZver: false
  17. str: '()' MouseZver: true
  18. str: '((((())))()())' MouseZver: true
  19. str: '(()())' MouseZver: true
  20. str: '(()()' MouseZver: false
  21. str: '(((' MouseZver: false
  22. str: ')((' MouseZver: false
  23. Total execution time in nanoseconds: 39500
  24. */
  25. ?>

p.s. для оценки производительности скриптов рекомендуется использовать функцию hrtime (PHP 7 >= 7.3.0, PHP 8)

Удачи!

(Отредактировано автором: 19 Декабря, 2021 - 14:39:53)

 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB