Ответы пользователя по тегу Программирование
  • Как написать функцию удаления лишних пробелов в строке?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Лишние пробелы - это те, которых больше одного подряд?
    List *delSpaces(List *p) {
        for(List **a=&p;*a;){
            if((*a)->c==' ' && (*a)->next && (*a)->next->c==' ') *a=(*a)->next;
            else a=&((*a)->next);
        }
        return p;
    }

    Не проверялось.
    Ответ написан
  • Возможно создать искусственный интеллект используя современные технологии?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Множество "всех случаев жизни" имеет тенденцию расширяться. ИИ придётся научиться самому писать скрипты для новых ситуаций. А для этого - находить в этой ситуации объекты, их взаимосвязи, закономерности поведения и реакцию на действия ИИ. И после этого решать задачу оптимального управления. И всё это в реальном времени.
    Ответ написан
    Комментировать
  • Как составить алгоритм решения задачи на ДП или Рекурсию (Задача на лесенку)?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Решить задачу легко - заводите массив A[N,N], в каждой клетке [K,M] которого будет записано число лесенок из K кубиков, нижний слой которых состоит из M кубиков. Число будет ненулевым, когда M <= K <= M*(M+1)/2.
    Массив заполняется начиная со строчки K=1 по формуле A[K,M]=sum(A[K-M,r],r=1..M-1). Сумма элементов в строчке K=N будет искомым числом.

    В решении, ссылку на которое вы дали, последовательно вычисляется число лестниц из j кубиков, нижний ряд которых не длиннее, чем i кубиков. Чтобы найти это число, надо к уже найденным лестницам, нижний ряд которых не длиннее, чем i-1 кубик (их мы оставляем без изменения), прибавить лестницы из j-i кубиков с нижним рядом не длиннее, чем i-1 кубик (к ним мы добавим ряд из i кубиков). Что и делается во внутреннем цикле.
    Ответ написан
    5 комментариев
  • Что такое машина Тьюринга и какое отношение она имеет к программированию?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    В первую очередь - это формальное определение алгоритма. Задача считается алгоритмически разрешимой тогда и только тогда, когда её решение можно запрограммировать на машине Тьюринга (или каким-нибудь другим эквивалентным способом). Это определение даёт, например, возможность предъявить алгоритмически неразрешимые задачи. Позволяет ввести понятие "Тьюринг-полного" языка - если на языке можно реализовать машину Тьюринга, то на нём можно написать любой алгоритм (язык С таким не является, а C# - является).
    В общем, МТ - способ определить некоторый класс алгоритмов:
    - некоторые задачи можно решить конечным автоматом;
    - для некоторых потребуется конечный автомат со стековой памятью;
    - для других достаточно машины Тьюринга;
    - для остальных требуется божественное откровение или другие неалгоритмизируемые методы.
    Ответ написан
    7 комментариев
  • Как получить массив случайных чисел, сумма которых равна 500?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Предположим, что числа нужны целые неотрицательные. Если числа могут быть нулевыми, делаете так:
    n1=irand(501); // от 0 до 500
    n2=irand(501); // от 0 до 500
    n3=irand(501); // от 0 до 500
    sort(n1,n2,n3); // сортируете по возрастанию любым подходящим способом
    x0=n1; x1=n2-n1; x3=n3-n2; x4=500-n3;

    Если числа могут быть только положительными, то поступаете аналогично:
    n1=irand(497); // от 0 до 496
    n2=irand(497); // от 0 до 496
    n3=irand(497); // от 0 до 496
    sort(n1,n2,n3); // сортируете по возрастанию любым подходящим способом
    x0=n1+1; x1=n2-n1+1; x3=n3-n2+1; x4=496-n3+1;

    Распределение будет слегка неравномерным (наборы, содержащие нули в первом случае и единицы - во втором, будут встречаться чуть реже), но и это можно исправить, слегка усложнив программу.
    Ответ написан
    Комментировать
  • Переменная vs цикл в данном случае?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Зависит от статистики обращений.
    Если проверки идут намного чаще, чем изменения массива - то переменная. Причём при "удалении" цифры придётся не просто очищать ячейку, а пройтись по всему массиву - нет ли там ещё одной такой цифры.
    Если проверки и изменения идут сериями (много изменений - много проверок), то две переменных. В одной - индекс, в другой признак того, не испортился ли он. Тогда при проверке с "испортившимся" индексом придётся пройтись по массиву и посмотреть, где теперь цифра. Хотя можно просто проверить, что лежит сейчас в ячейке с индексом. Если не нужная цифра - новый проход по массиву. Но здесь уже надо смотреть, какая ячейка портится чаще - та, в которой цифра появилась раньше всего, или та, где она появилась позже всего.
    Если проверки идут достаточно редко, то цикл.
    В сложных случаях - когда в массиве не 10, а 1000 ячеек, цифр может быть много, меняются они часто, и нужно часто проверять, есть ли цифра, и где именно - надо будет хранить индексы ячеек с этими цифрами в какой-нибудь структуре. Например, в двусвязном списке, построенном на двух массивах, параллельных рабочему. Тогда все изменения и проверки будут работать за O(1).
    В общем, всё зависит от ситуации.
    Ответ написан
    Комментировать
  • Сколько времени и нервов потребуется чтобы заново восстановить информационную "часть" мира?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Думаю, что если такая цель будет поставлена, то через десяток лет появится первый микропроцессор (до того будут схемы на лампах или полупроводниках). И потом снова пойдёт гонка за мегагерцами и нанометрами. Лет 25-30 должно хватить.
    Ответ написан
    Комментировать
  • Какой вариант оптимальней?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    В первом случае варианты не эквивалентны. При a=3, b=4 в первом варианте CallMe() вызовется дважды, а во втором - только один раз.
    Первый вариант написан оптимально. Чтобы заставить его вести себя, как второй вариант (с одним вызовом CallMe()), достаточно вставить else:
    if(a == 3)    CallMe();
    else if(b == 4) {
        CallMe();
        Giveme();
    }

    Это будет оптимально по времени. Если же вместо CallMe() стоит более сложный вызов или длинный блок, и вас волнует длина кода (например, на микроконтроллере), то берите второй вариант. Если при этом и общее условие сложнее, чем b==4, то придётся его запомнить:
    bool cond1=(sin(x)>=sin(y));
    if(cond1 || cos(x)<cos(y)) Draw(tan(x),tan(y));
    if(cond1) CloseLine();


    Во втором случае, второй вариант короче (по коду) и слегка быстрее - программе надо хранить на одну переменную меньше, и оказывается больше возможностей для регистровой оптимизации. Но это при условии, что порядок вызовов не важен, и что обработка индексов в обратном порядке не даст проигрыша по сравнению с прямым.
    Ответ написан
    Комментировать
  • Как самому подсчитать расстояние в километрах по координатам долготы и широты?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Формула "гаверсинуса":
    const double R=6371;  // Earth's radius
    double sin1=sin((lat1-lat2)/2);
    double sin2=sin((lon1-lon2)/2);
    return 2*R*asin(sqrt(sin1*sin1+sin2*sin2*cos(lat1)*cos(lat2)));

    где lat1,lat2 - широты, а lon1,lon2 - долготы точек, выраженные в радианах.
    Стоит ли ради этого подключать библиотеку?
    Ответ написан
    2 комментария
  • Как найти определенную "фигуру" в двумерном массиве?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Если длина строк меньше 32, то можно искать с помощью битовых масок. Но для выбора оптимального алгоритма нужно знать полный набор масок для поиска. Искомые фигуры состоят только из нулей, или могут быть сочетания нулей и единиц?
    Ответ написан
    Комментировать
  • Пара вопросов. Стоит ли так использовать функции? Как лучше завершать выполнение функции?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Если a и b глобальные, то лучше сделать одну глобальную функцию, которая на них будет смотреть:
    int CmpAB(int same,int diff){ return a==b ? same : diff; }

    и положить её рядом с переменными. Потом туда же перетаскивать и другие обращения к ним. Глядишь, и соберётся класс с какими-нибудь осмысленными свойствами.
    return - вещь хорошая, но если возвращать значение, то в нём должен быть смысл. Ради сокращения пары скобок придумывать тип возврата не стоит. Так что
    if(a == b){
       print("test");
       return;
    }
    // код, если a != b
    Ответ написан
    Комментировать
  • Могут ли в ближайшей перспективе появиться квантовые компьютеры?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Надеюсь, что оптические появятся раньше. От них пользы больше будет.
    Ответ написан
    Комментировать
  • Время жизни объекта, если передали ссылку его поля в статический класс?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Будет. Ссылка идёт не на поле объекта, а на объект, который когда-то лежал в этом поле. После чистки останется только объект d. Вот если бы в d при конструировании была ссылка на b, как на "родителя", то b бы тоже остался.
    Ответ написан
    Комментировать
  • Не работает 2D передвижение?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Если константа Rad2Deg определена, как 180/pi, то в функции Move надо не умножать на неё, а делить.
    И вообще, неплохо бы хотя бы кратко описывать - что хотите получить, а что получается.
    Ответ написан
    1 комментарий
  • Как верно реализовать внешнюю сортировку естественным слиянием с порогом?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Не очень понятно, зачем здесь Z. Если 1000 структур помещается в памяти, и мы их можем отсортировать, то казалось бы - читаем из файла 10 раз по 1000 структур (по порядку, за один проход), каждый раз структуры сортируем и в отсортированном порядке помещаем в новый файл. Всего получается 10 файлов. Дальше - обычный merge. Кстати, слить можно сразу все 10 файлов, если их можно открыть одновременно. Если нет - сливаем два самых маленьких файла, пока не останется один (выгодно, чтобы сливаемые файлы были примерно одинакового размера - как группы символов в коде Хаффмана).
    Возможно, Z придумали, чтобы файлы были не совсем одинаковыми, чтобы алгоритм не закладывался на одинаковость размера. Но тогда лучше было бы, например, "случайное число от 500 до 1000". В любом случае, если брать не максимум, то алгоритму только хуже.
    Ответ написан
    Комментировать
  • Не доходит до меня тема коллекций, что я не так решаю?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    А вам нужно удалить всех людей, или одного оставить?
    Во втором случае накапливаете множество имён, и если у очередного человека имя принадлежит множеству, его удаляете. Если не принадлежит - добавляете в множество имён.
    Если надо удалить всех Иванов:
    - заводите два множества: имена, которые встретились, и имена, которые встретились более одного раза.
    - в цикле по таблице: если очередного имени в первом множестве нет, добавляете его туда, а если есть - добавляете во второе множество.
    - удаляете из таблицы всех людей, имена которых есть во втором множестве.
    Ответ написан
  • Где применяется комбинаторика в информатике?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Мало применяется. В информатике она, скорее всего, понадобится в анализе сложности различных алгоритмов, выборе оптимальной стратегии перебора. В олимпиадном программировании встречается постоянно. В реальной жизни - в основном, когда комбинаторные формулы требуются для расчётов вероятностей, а те, в свою очередь, для проверки статистических гипотез.
    Ещё комбинаторика может пригодиться в задачах, связанных со статистической физикой, когда через число состояний оценивается энтропия системы, а через неё - дальнейшее поведение или устойчивость. Возможно, она нужна для алгоритмов вроде сверхбыстрого умножения чисел. Но всё это очень далёкий уровень, при взгляде с которого элементарная комбинаторика уже неотличима от таблицы умножения.

    UPD. Можно вспомнить одно место, где комбинаторика требуется в обычных задачах. Это когда у нас есть множество каких-нибудь подмножеств, перестановок, слов над алфавитом, или ещё чего-нибудь, что обычно считает комбинаторика. И мы хотим по элементу этого множества найти его индекс. И наоборот.
    Задача возникает не часто, но если возникла, то без комбинаторных формул не обойтись никак.
    Ответ написан
    Комментировать
  • Почему у int и float разный диапазон?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Потому что значения int на всём промежутке идут равномерно, с шагом 1, то у float шаг между соседними значениями меняется: в окрестности единицы он примерно 10^(-7), а в окрестности миллиарда - около 100. Приблизительно можно сказать, что равномерно идёт логарифм float. За счёт этого (выигрыш в точности на малых числах, но заметный проигрыш на больших) они и расширили диапазон.
    Играясь с соотношением числа бит на мантиссу и порядок, можно менять диапазон на точность, и наоборот.
    Ответ написан
    Комментировать
  • Как и где в программировании используется математическая логика?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Математическая логика - правила вывода, системы аксиом, теории, логические системы и т.п. - практически не используется. Возможно, какая-то её часть нужна при разработке компиляторов (формализация вывода типов, доказательства допустимости оптимизаций...) и экспертных систем.
    Булева алгебра нужна гораздо чаще. Но если вы выучите и поймёте правила преобразования логических выражений, этого будет достаточно. Даже предполные классы, скорее всего, не понадобятся. Хотя, если судьба забросит в программирование ПЛИС... там всё может быть.
    Проходят ли в дискретной математике графы - не помню. Даже если да, то совсем не на том уровне (и не в том направлении), в котором они нужны в программировании.
    Что могло бы пригодиться - конечные автоматы. Они нужны более, чем в одном месте. Но, опять же, в дискретной математике могут дать, разве что, общие факты про них.
    Так что, в целом - это предмет для расширения кругозора и любителей головоломок разных уровней.
    Ответ написан
    1 комментарий
  • Как повторить текущую итерацию while C#?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Я бы сделал так:
    while (условие) {
        do {
            код код код код
            код код код код
        }while (условие);
    
        код код код код
        код код код код
    }


    Но это если "перезапустить текущую итерацию" не требует дополнительного кода. Если требует - поставить вместо do...while бесконечный цикл for(;;) с break незадолго до конца.
    Ответ написан
    Комментировать