• Kак сортировать стрoку, которая содержит 0 и 1?

    Набросок алгоритма:

    int sort(char *line)
    {
        unsigned prefix = strlen(line);
        while (prefix > 5 && !sorted(line)) {
            prefix = prefix - 1;
            if (*(line + prefix) == '0') {
                char const * at = stdchr(line, '1');
                if (at == line) {
                    swap(line, line + 2);
                    swap(line + 1, line + length - 1);
                }
                else {
                    swap(at - 1, line + length - 1);
                }
            }
        }
        if (!sorted(line) && !bruteforce(line, prefix))
            return 0;
        return 1;
    }


    Тут не хватает:

    1. Нужных заголовков
    2. Реализации функции sorted, которая возвращает 0, если строка уже отсортирована, и не 0 иначе
    3. Реализации функции swap, которая меняет местами две неперсекающиеся пары по указателям
    4. Реализации функции bruteforce, которая сортирует префикс строки длинной не более 5 символов перебором перестановок, и возвращает 0, если не удалось отсортировать префикс (например, для строки "101" или "1010"), и не 0, если удалось отсортировать.

    Инвариант алгоритма простой, prefix - длина неотсортированной части строки. Более того все символы за пределами префикса равны '1'. Мы каждый раз уменьшаем длину префикса на 1, пока не отсортируем последовательность, либо пока префикс не станет равен или меньше 5.

    Откуда берется число 5? Все последовательности длинны 5 и более можно отсортировать меняя пары, для меньших последовательностей это не всегда возможно.

    Последовательностей длинны <= 5 всего 62 (32 + 16 + 8 + 4 + 2), так что bruteforce занимает не очень много времени, но возможно есть и более разумный вариант сортировки коротких последовательностей. Вообще говоря все несортируемые последовательности легко перечислить.

    Алгоритм понятное дело не оптимальный.
    Ответ написан
    Комментировать
  • Какие есть серьезные программы на С?

    https://www.kernel.org/ (ну и freebsd, openbsd и тд)
    httpd.apache.org
    www.openssl.org
    www.whatcanidoformozilla.org/#!/progornoprog/proglang/c

    очень много всего.
    Ответ написан
    Комментировать
  • Little endian to Big endian conversion в C++, необходим ли для бинарной сериализации?

    Функция htonl конвертирует host порядок байт в сетевой порядок байт (т. е. в Big Endian), независимо от того, какой на самом деле на host используется порядок, т. е. вся препроцессорная логика не нужна (она уже есть в htonl).

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

    Если говорить о бинарной сериализации, то фиксировать нужно не только порядок байт, но и размер, т. е. использовать типы вроде uint32_t. Функции hton* и так их используют, но у тебя в коде используется int, что не очень хорошо.
    Ответ написан
    Комментировать
  • Как в C++ создать массив структур неизвестной длины внутри функции?

    Кроме упомянутых выше ошибок с использованием scanf (и сомнительности использования gets), есть еще одна ошибка связанная с передачей указателя в функцию input - он передается по значению, и изменяется версия внутри функции, но не значение переменной books из main, соответственно, delete [] books - делает совсем не то, что вы ожидаете.
    Ответ написан
    Комментировать