Форум программистов, компьютерный форум, киберфорум
PHP для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
8 / 5 / 4
Регистрация: 18.02.2014
Сообщений: 409

Оцените код

24.09.2016, 23:15. Показов 1491. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет. Такая ситуация, пару недель назад пытался устроиться на работы на вакансию "PHP Разработчик". По требованиям я им подошел, дали тестовое задание вот такое:

Написать программу которая бы проверяла правильно ли расставлены фигурные скобки в php файле. Например:
{ … { … } { … { … } … } здесь не правильно расставлены скобки
{ … { … } { … { … } … }...} здесь правильно
написал вот такой код:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
    $getFileText = file_get_contents('./checkPhpFile.php');
    $str = preg_replace('/[^{}]/ui', '',$getFileText); // удаляю все символы кроме скобок
    // теперь прохожу по символьно по всей строке и смотрю нет ли такой ситуации, что бы закрывающихся скобок было больше чем уже открытых
    $arr = str_split($str);
    $openingParenthesis = 0; // счетчик открытых скобок
    $closingParenthesis = 0; // счетчик закрытых скобок
    foreach ($arr as $value) {
        if($value == '{'){
            $openingParenthesis++;
        }else if($value == '}'){
            $closingParenthesis++;
        }
        if ($openingParenthesis < $closingParenthesis) {
            exit("Скобки расставлены не верно");
        }
    }
    // и в конце еще сравним равны ли у нас кол-ва открывающихся и закрывающихся скобок в строке вдруг у нас закрывающихся скобок меньше
    if ($openingParenthesis != $closingParenthesis) {
        echo 'Скобки расставлены не верно';
    }else{
        echo "Все ок. Скобки расставлены верно";
    }
?>
Но когда отправил им свое задание ответили, что я не справился с заданием.
Кто может объяснить, чем этот код плох. И как можно было сделать лучше?
Вроде так то код работает и делает, что от него требуется. Плиз подскажите, что могло не понравится? Ну очень интересно, где я налажал.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.09.2016, 23:15
Ответы с готовыми решениями:

Оцените код
Доброго времени. Выполняю задание, необходимо собрать пользователей сайта habr, и у каждого по пять записей, сайт должен быть в рамках MVC....

Оцените мой код. Знания в Веб технологиях у меня не маленькие и опыт тоже!
Ребят, нет времени объяснять, вообщем оцените мой код. Есть база данных с таблицей аккаунтов, в ней 10.000 записей, вот я короче делаю...

Оцените код
В общем, пилю я тут свою &quot;мега,кликер,супер&quot; игру, скажите пожалуйста, что не так? Может есть какие-то очевидные ошибки и недочёты? Буду...

16
Фрилансер
Эксперт PythonЭксперт JSЭксперт PHP
 Аватар для Azdeman
1871 / 1362 / 604
Регистрация: 12.01.2011
Сообщений: 5,470
24.09.2016, 23:23
Ну возможно потому что слишком много телодвижений.(1 разбивка, другая, 10-я...) Задача проста, найти закрывающие и открывающие теги, сравнить кол-во тех и других и если равны то всё ок, если не равны, значит какую то скобку забыли.
PHP
1
2
3
4
5
6
7
8
9
10
    $a = "{ … { … } { … { … } … }";
    $b = "{ … { … } { … { … } … }...}";
$function = function($a){
    preg_match_all("~(\\{)|(\\})~",$a,$m);
    $c = count(array_filter($m[1]));
    $c1= count(array_filter($m[2]));
    echo ($c===$c1) ? 'Верно' : 'Нет';
};
echo $function($a).PHP_EOL;
echo $function($b);
http://sandbox.onlinephpfuncti... bc57a59d3e
1
276 / 201 / 143
Регистрация: 22.01.2016
Сообщений: 637
25.09.2016, 03:50
А возможно и потому, что вы и правда не справились с заданием.
Вы считаете закрывающие и открывающие скобки, но даже если их будет поровну, не очень похоже, чтоб в строке } … { … } { … { … } … }...{ скобки были расставлены правильно.
Если к красивому и компактному решению ув. Azdeman добавить проверку первой и последней скобки, то думаю получится то, что надо.
1
Эксперт PHP
5755 / 4134 / 1508
Регистрация: 06.01.2011
Сообщений: 11,276
25.09.2016, 07:12
Ещё короче:
PHP
1
2
3
4
5
6
7
8
<?php
    $string = '{ … { … } { … { … } … } } {}';
    
    $regex = '~[^{}]*\{([^{}]*|(?R))*\s?\}[^{}]*~';
    
    preg_match_all($regex, $string, $matches);
    
    echo implode($matches[0]) === $string ? 'Верно' : 'Неверно';
0
1943 / 1768 / 825
Регистрация: 23.01.2014
Сообщений: 6,230
25.09.2016, 08:10
Чего Вы тут насоветовали?

Эта задача стара как мир и решается по-другому, за один проход по строке:

1. Нашел открывающую скобку, прибавил единицу к счетчику.
2. Нашел закрывающую скобку, убавил единицу.
3. Каждый раз проверяешь - если счетчик меньше 0, ошибка.
4. Если в конце строки счетчик остался больше 0, ошибка.
5. Иначе верно.

Только обычно делают сразу несколько видов скобок ({[...
1
Эксперт PHP
5755 / 4134 / 1508
Регистрация: 06.01.2011
Сообщений: 11,276
25.09.2016, 08:44
pav1uxa, с регулярным выражением короче.

Добавлено через 5 минут
И на двух миллионах подряд идущих скобок отрабатывает в 2 раза быстрее, чем for.

Не по теме:

Только кому эти два миллиона нужны. :D

0
25.09.2016, 10:20

Не по теме:

Цитата Сообщение от Para bellum Посмотреть сообщение
с регулярным выражением короче.
Не знаю, даже комментировать не хочется.

Надеюсь Вы все это в шутку :D

Я уже молчу про
PHP
1
$string = 'asdf';
Code
1
Неверно

0
Эксперт PHP
5755 / 4134 / 1508
Регистрация: 06.01.2011
Сообщений: 11,276
25.09.2016, 10:51
Цитата Сообщение от pav1uxa Посмотреть сообщение
Не знаю, даже комментировать не хочется.
А что не нравится? Тридцать символов заместо 100 (минимум) с FOR? Если бы это работало, конечно.
А так -- да, это провал.

Тогда только Ваш вариант -- посимвольно перебирать.
0
1943 / 1768 / 825
Регистрация: 23.01.2014
Сообщений: 6,230
25.09.2016, 12:13
Да это не то чтобы мой вариант, он народный Стандартная задача на собеседованиях по любому ЯП. Задача на стек.

Просто следующее задание будет с {[(. И тут тяжело будет без понимания.
0
1137 / 685 / 412
Регистрация: 07.11.2015
Сообщений: 1,102
25.09.2016, 12:26
Еще вариант с http://php.net/manual/ru/function.count-chars.php
PHP
1
2
3
4
function check($str) {
    $c = count_chars($str);
    echo $c[ord('{')] === $c[ord('}')] ? 'Верно' : 'Неверно';
}
0
Эксперт PHP
5755 / 4134 / 1508
Регистрация: 06.01.2011
Сообщений: 11,276
25.09.2016, 12:38
Emilien, тут сложнее немного.
PHP
1
check('}}}{{{'); // Выдаёт "верно"
0
25.09.2016, 12:53

Не по теме:

Я чувствую скоро дойдем до

PHP
1
echo (strpos($str, '{') !== FALSE && strpos($str, '}') !== FALSE) ? 'Верно' : 'Неверно';

0
Эксперт PHP
5755 / 4134 / 1508
Регистрация: 06.01.2011
Сообщений: 11,276
25.09.2016, 14:36
Итак, вариант pav1uxa (комментарии из его сообщения):
PHP
1
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
mb_internal_encoding('utf8');
 
function validator($string){
        $length = mb_strlen($string);
        
        $counter = 0;
        
        for($i=0; $i<$length; $i++){
            $char = mb_substr($string, $i, 1);
            
            # Нашел открывающую скобку, прибавил единицу к счетчику.
            if($char === '{')
                $counter++;
            # Нашел закрывающую скобку, убавил единицу.
            elseif($char === '}')
                $counter--;
            
            # Каждый раз проверяешь - если счетчик меньше 0, ошибка.
            if($counter < 0)
                return false;
        }
        
        # Если в конце строки счетчик остался больше 0, ошибка.
        # Иначе верно.
        return !$counter;
    }
 
    var_dump(validator('{ … { … } { … { русский текст } … } … }'));
На строке в 15 МБ не укладывается и в 30 секунд.

По рецензии того же pav1uxa, доделал регулярное выражение, чтобы на подобное:
PHP
1
$string = 'asdf';
Не выдавало false.
PHP
1
2
3
4
5
6
7
function validator($string){
    $regex = '~(?(?={)[^{}]*\{([^{}]*|(?R))*\}[^{}]*|[^{}]+)~';
 
    preg_match_all($regex, $string, $matches);
 
    return implode($matches[0]) === $string;
}
На строке в 15 МБ работает ~1.5 секунды. Правда при огромной иерархии скобок выдаёт false.

Не знаю, почему pav1uxa так резко отреагировал на регулярку, но она в десятки раз быстрее работает, чем цикл. Да и кода в функции всего 3 строки.

Я бы отправил работодателю всё-таки регулярку. И пусть у него хоть глаза лопнут от нечитабельности, но на то регулярка и регулярка.

P.S. При всём при этом -- не утверждаю, что данное регулярное выражение идеально. Вероятно, можно сделать и лучше. Но главное -- циклы с треском проваливаются.
1
1943 / 1768 / 825
Регистрация: 23.01.2014
Сообщений: 6,230
25.09.2016, 14:44
Цитата Сообщение от Para bellum Посмотреть сообщение
Итак, вариант pav1uxa (комментарии из его сообщения):
Спасибо, конечно...

Но засунуть mb_substr в цикл на 5 МБ это сильно (можно нужно просто разбить на массив ДО цикла и итерировать через foreach)

Я уже не говорю о том что { во всех кодировках имеет одинаковое кодирование, и все что касается mb_ можно убрать.
0
Эксперт PHP
5755 / 4134 / 1508
Регистрация: 06.01.2011
Сообщений: 11,276
25.09.2016, 15:03
Цитата Сообщение от pav1uxa Посмотреть сообщение
Но засунуть mb_substr в цикл на 5 МБ это сильно
Это чтобы прочувствовать ситуацию.
Цитата Сообщение от pav1uxa Посмотреть сообщение
Я уже не говорю о том что { во всех кодировках имеет одинаковое кодирование, и все что касается mb_ можно убрать.
Разницы нет. Если в строке есть многобайтовые символы -- обрезать строку только так.

Добавлено через 5 минут
Цитата Сообщение от pav1uxa Посмотреть сообщение
нужно просто разбить на массив ДО цикла и итерировать через foreach
Хорошо. Разбиваю по символам:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function validator($string){
        $counter = 0;
        
        $characters = str_split($string);
 
        foreach($characters as $char){
            # Нашел открывающую скобку, прибавил единицу к счетчику.
            if($char === '{')
                $counter++;
            # Нашел закрывающую скобку, убавил единицу.
            elseif($char === '}')
                $counter--;
            
            # Каждый раз проверяешь - если счетчик меньше 0, ошибка.
            if($counter < 0)
                return false;
        }
        
        # Если в конце строки счетчик остался больше 0, ошибка.
        # Иначе верно.
        return !$counter;
    }
Скрипт выжирает память и отваливается.
0
8 / 5 / 4
Регистрация: 18.02.2014
Сообщений: 409
25.09.2016, 20:57  [ТС]
mrNTF, Нет мой код находит в вашем варианте строки ошибку, но я уже понял, что просто слишком намудрил можно было написать все короче. Видимо из-за этого и не взяли
0
1943 / 1768 / 825
Регистрация: 23.01.2014
Сообщений: 6,230
26.09.2016, 11:01
Цитата Сообщение от Para bellum Посмотреть сообщение
Скрипт выжирает память и отваливается.
Ну тут я не подумал, действительно делить 5мб строку на массив символов для PHP слишком тяжело. Вы в str_split() если 5 мб скармливаете он сам по себе отвалится, функцию можно даже не выполнять

Ну ладно, если уж так хотите парсить строки 5 мб, вот:
PHP
1
2
3
4
5
6
7
8
9
10
11
    $len = strlen($str);
    $cnt = 0;
    for ($i = 0; $i < $len; ++$i) {
        if ($str[$i] == '{')
            $cnt++;
        elseif ($str[$i] == '}')
            $cnt--;
        if ($cnt < 0)
            return false;
    }
    return ($cnt == 0) ? true : false;
Это уже "допиливание". В любом случае, лично для меня, все же очевидно, что один проход по строке ВСЕГДА будет работать быстрее чем регулярное выражение. Работа с регулярными выражениями всегда очень дорогая операция.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.09.2016, 11:01
Помогаю со студенческими работами здесь

Оцените код
Здравствуйте. В этой теме https://www.cyberforum.ru/php-oop/thread1630754.html пошла речь о том какой ужасный код. Я как бы знаю о его...

Оцените код
Собственно вот условие задачи: Дано целое число m&gt;1.Получить наибольшее целое k,при котором 4k&lt;m. Вот код программы: var m,k :...

Оцените от 1 до 10 код
Всем привет!Меня зовут Макс.Мне 14 лет и я хотел бы получить вашу оценку о коде который написал 2 дня назад.Нормально для 14 лет? ...

Оцените код
Короче первый код который я забацл сам считай без помощи интернета! Теперь пришло время его показать хоть кому-то. Если посмотреть по...

Оцените код)
Здравствуйте уважаемые программисты. Интересно ваше мнение по поводу моего кода. Вот пример: #include &lt;iostream&gt; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru