Они и сделали ту очередь, чтоб не видно было, что с работой не справляются. Окно всего на месяц, условно сразу всё занято. В итоге не видно, сколько людей нуждается в услуге, очередей сумасшедших не наблюдается. Короче, обычный гриншифтинг вместо работы.
Не по всім. В Болгарії на жаль досі немає
Однак для компаній, які шукають висококваліфікованих кадрів за відносно низьку вартість, ця ситуація може бути вигідною.
Хіба що продуктові, які і так працюють в Україні. Для замовників аутсорса це дешевше але ризикованіше, для аутсорсінгових компаній це погіршення якості замовників.
Можна обмежитись тим, що вона багатопарадигмова з повним доступом до ресурсів, а також історично широковживана. Але тоді статті не буде :)
Та й чи треба більше? Навіть того, що є в нас, якщо є можливість масштабуватись, а також якщо є доступ до промислових систем та зброї, цілком достатньо. Або, як інший варіант м’якої сили, людством цілком успішно керують політикани, маркетологи та журналісти. І для того їм не потрібен якийсь супер інтелект
Хм, така цікава тема, такий лонгрід, але жодної діаграми, жодного числа, майже окрім 20 років. Як так?
Опять таки я срезаю углы, отдавая приоритет удалению свежесозданных пар в зоне склейки, а не более «старым» парам из правой части. Ну, вроде запрета не было.
Тогда результат
ABBBBBBBBBBBB -> BBBBBBBBBBB
ABCDABBACD ->
#include <iostream> int16_t constexpr ch2case(char c1, char c2) { return (c2 << 8) | c1; } char *clean1(char *str) { if (!*str || !str[1]) return str; char *p1 = str, *p2 = str+2; do{ switch(*((int16_t *)p1)) { case ch2case('A', 'B'): case ch2case('B', 'A'): case ch2case('C', 'D'): case ch2case('D', 'C'): if (p1 != str) p1--; else { *p1 = *p2; if (*p2) p2++; } break; default: p1++; break; } p1[1] = *p2; }while(*(p2++)); return str; } int main(int argc, char *argv[]) { char str1[] = "ABBBBBBBBBBBB"; std::cout << str1 << " -> " << clean1(str1) << std::endl; char str2[] = "ABCDABBACD"; std::cout << str2 << " -> " << clean1(str2) << std::endl; }
В общем, в случаях, когда у нас есть возможность решить задачу в один проход по строке коротким окном и на каждый символ совершать считанные простые операции, рекурсивный метод очень вряд ли может быть быстрее. Вам нужно, грубо говоря, за счёт более оптимальной обработки компенсировать затраты на работу со стеком и ещё что-то выиграть. Затраты на стек это, как минимум, копирование адреса, куда вернуться, и переменных.
Вариант простого удаления пар тоже можно сделать по аналогии, удаляя не последний символ, а всю пару. Т.к. на «стыках» опять возможно возникновение пары, то по идее p1 нужно декрементить после удаления, кроме случая начальной позиции. Удаления по существу не будет, как и в предыдущем случае. Просто копирование следующего символа из р2.
Опять таки O(n) и дешёвые операции на каждом цикле.
Кода будет почти столько же
Код вроде нормально выложился, похоже только include iostream подпортило.
С мобильного пишу, если что
Результат:
ABBBBBBBBBBBB -> A
ABCDABBACD -> ACAAC
#include <iostream> int16_t constexpr ch2case(char c1, char c2) { return (c2 << 8) | c1; } char *clean1(char *str) { if (!*str || !str[1]) return str; char *p1 = str, *p2 = str+2; do{ switch(*((int16_t *)p1)) { case ch2case('A', 'B'): case ch2case('B', 'A'): case ch2case('C', 'D'): case ch2case('D', 'C'): break; default: p1++; break; } p1[1] = *p2; }while(*(p2++)); return str; } int main(int argc, char *argv[]) { char str1[] = "ABBBBBBBBBBBB"; std::cout << str1 << " -> " << clean1(str1) << std::endl; char str2[] = "ABCDABBACD"; std::cout << str2 << " -> " << clean1(str2) << std::endl; }
Ничего нигде не сохраняется. Вместо исходной строки по тому же адресу появляется очищенная при определённой трактовке условия в свою пользу по принципу разрешено всё, что не запрещено. Полностью стейтлес.
Если под повторяющимися понимаем некий патерн, который повторяется n раз в строке, либо в строках подаваемых на вход, то опять таки не будет быстрее. Даже само по себе вычисление хеша съест больше, чем описанное решение в один проход
Можно удалить А и результирующая строка BBBBBBBBBBBB отвечает условию задачи. Но почему А это неправильный ответ я не понял. В условии просят избавиться от AB. Строка А построена на базе исходной путём удаления из неё лишних символов. Всё честно
Уже в формулировании условия задачи огромная дыра. Нет условия сберечь максимальное количество символов. Т.е. АВВВВВВВВВВВВ -> А.
Что ж, ок.
Если не заботимся об оптимальном решении, то в простейшем случае решения в лоб на с++ при итеративном методе инмемори это 2 указателя. Первый — указатель на предпоследний символ в уже почищенной строке (вначале указывает на начало исходной строки) , второй — движение по строке в конец (указывает на начало непочищенной правой части, в начале указывает на смещение 2). По первому указателю switch по *(int16*)p1 (проверяемые сочетания все 2х байтные). Не нашли — инкремент 1го указателя, нашли — копируем символ *(p1+1)=*(p2++). Зиро терминейтед стринг — последний 0 тоже копируется, указывая на конец сформированной строки. Завершение при *(p2) == 0.
O(n), никаких строковых операций сравнения, память требуется аж под два указателя.
Наверное данные пользователей продавать будут и рекламу крутить.
Ні, це приблизно, як HR. Він має пояснити, чому вам добре :)