• Как понять, где ссылка и где копия?

    tsarevfs
    @tsarevfs Куратор тега C++
    C++ developer
    С управляемой кучей я все понял, еще я не могу понять, как можно вернуть псевдоним (ссылку) на тип, который размещается не в управляемой куче и вообще почему на него можно создать указатель

    На самом деле разница между "кучей" и "не кучей" не такая и большая с точки зрения указателей.
    У нас есть 3 варианта размещения переменных:
    1. Куча. int* a = new int(3);
    2. Стек. int b = 5;
    3. Константная память, инициализируемая на старте приложения. char* c = "hello world";


    С точки зрения процесса есть большой непрерывный кусок памяти, который называется виртуальная память.
    Куча это кусок этой памяти, который хранит сами данные плюс некоторую служебную информацию, которая позволяет например находить свободные места в памяти.
    Стек это другой кусок, для которого дополнительно хранится указатель на "голову", который мы сдвигаем при push и pop. Но данные по прежнему в том же большом куске виртуальной памяти с той же адресацией.
    Константная память это третья зона с самым простым устройством. Туда записываются значения при старте программы и больше не меняются до конца ее работы.

    Также полезно понимать что ссылка и указатель это по сути одно и то же "под капотом". Просто в языке работа с ними выглядит немного по-разному. Ну и ссылка имеет меньше возможностей (а значить меньше простор для ошибки) вроде указывания в никуда (nullptr).

    Таким образом мы можем взять указатель или ссылку на переменную вне зависимости от ее местоположения. По сути это просто порядковый номер ее начала в виртуальной памяти.

    Копия это отдельный участок в памяти. Указатели на оригинал и копию будут иметь разные значения. при изменении копии оригинал не будет затронут.
    Аналогия с почтовыми адресами более чем уместна. Адрес дома записанный на бумаге - указатель. Сам дом по этому адресу - значение. Создание копии - построить такой же дом в другом месте города. Адрес у копии дома будет разумеется другой.
    Ответ написан
    2 комментария
  • Работа с Яндекс Алиса?

    tsarevfs
    @tsarevfs
    C++ developer
    Вам нужен https://tech.yandex.ru/speechkit/.
    Но смысловую обработку вам придется реализовывать отдельно. С Алисой все так же. По сути то, что они недавно выкатили в "Диалогах" это возможность интегрироваться с приложением-"чатом".
    Ответ написан
    Комментировать
  • Какими способами можно ускорить работу с объектами на сцене при большм удалении?

    tsarevfs
    @tsarevfs Куратор тега C++
    C++ developer
    1. Лодирование -- не показывать и не давать выделить мелкие объекты на таком масштабе.
    2. Кластеризация. Объединяем близкие объекты в группы по близости. Например так работают маркеры на яндекс картах. Если производительность упирается в обновление множества объектов, групповое изменение можно сделать асинхронным и ленивым.
    3. Можно сделать что-то среднее между 1 и 2. Если граф сцены хорошо группирует объекты логически, то можно прописать лодирование для этих узлов. Например на верхнем уровне у нас есть машина, при увеличении мы можем выделять и двигать отдельные узлы: двери, колеса...
    Ответ написан
    Комментировать
  • Где искать репетиторов по английскому в скайпе?

    tsarevfs
    @tsarevfs
    C++ developer
    Занимаюсь на скайинг . Средняя цена, организованно достаточно удобно. Русскоязычные преподаватели дешевле, но на уроках я использую максимум пару слов на русском. Русскоязычные имеют дипломы высшего образования, а вот англоязычным достаточно курсов. С англоязычным имеет смысл с upper intermediate заниматься.
    Ответ написан
  • Когда пишу функцию. Как понять - когда создавать для нее класс, а когда написать ее в классе типа Helper (т.е. классе для вспомогательных ф-ий)?

    tsarevfs
    @tsarevfs
    C++ developer
    Класс или файл helper как правило плохая идея. Он притягивает к себе мусор и велосипеды.
    Ничего плохого в отдельных функциях нет. Но если привыкнуть к ООП, то большинство функций естественным образом становятся методами классов.
    Ответ написан
    Комментировать
  • Как найти наибольшую поседовательность за O(n)?

    tsarevfs
    @tsarevfs
    C++ developer
    Хранить hash map, в которой ключ - значение последнего элемента в последовательности встреченной раньше, а значение -- длина. И дальше проходим по массиву и заполняем.
    Ответ написан
    2 комментария
  • Как сделать, что бы все значения сохранялись в программе Python \ PyQt?

    tsarevfs
    @tsarevfs
    C++ developer
    QSettings отличный вариант для сохранения настроек. В том числе путь до последнего открытого файла можно записать туда. По умолчанию в Windows они пишут в реестр, а под linux в ini файл, который создается в ~/.config.
    Ответ написан
    Комментировать
  • Какой алгоритм построения графиков выбрать?

    tsarevfs
    @tsarevfs
    C++ developer
    Комментировать
  • Когда выйдут процессоры без Meltdown и Spectre? И не могли бы вы пояснить позицию Линуса?

    tsarevfs
    @tsarevfs
    C++ developer
    Там смысл в том, что Интел предлагает выключить защиту по умолчанию и возложить на пользователя ее включение. Интелу очень не хочется чтобы показатели производительности упали на бенчмарках с "настройками по умолчанию".
    Ответ написан
    Комментировать
  • Как отрисовать трек движения?

    tsarevfs
    @tsarevfs
    C++ developer
    Рекомендация 1. Найдите библиотеку для геометрии, если ваша задача не в том чтобы научиться решать задачи вычислительной геометрии. Проверка находится ли точка внутри полигона реализована в каждой первой такой библиотеке.

    Рекомендация 2. Разбейте вашу задачу на отдельные части. Считывание данных - функция или метод, вычисления -- еще одна, отрисовка -- третья.

    Рекомендация 3. Если все же пишете геометрию сами, заведите классы для Point, Segment, Polyline, Polygon. Вместо передачи отдельных координат используйте их.

    Рекомендация 4. Функция определения пересечений содержит много делений, и если какой-то из делителей будет близок к нулю, то все будет плохо. Рекомендую посмотреть реализацию http://e-maxx.ru/algo/segments_intersection, где есть проверки на маленький делитель.
    Ответ написан
    1 комментарий
  • Как сделать перекрестные структуры?

    tsarevfs
    @tsarevfs Куратор тега C++
    C++ developer
    Реализацию метода отделить, плюс передавать по константной ссылке вместо копии forInt(const forFloat& arg);
    Ответ написан
    1 комментарий
  • Как в графе найти самый "большой" полный подграф?

    tsarevfs
    @tsarevfs
    C++ developer
    Хм, придумалось судя по всему неправильное решение (жадное). Но интересно где проблема.
    UPD: Понял где проблема.
    Лемма 1 Два полных непересекающихся подграфа (без общих вершин) размера m и n соответственно между вершинами которых есть m*n ребер образуют полный подграф с m*n вершин.
    Запихиваем все вершины в СНМ (Система непересекающихся множеств). Каждая вершина -- полный подграф размера 1. Дальше в процессе обхода "сливаем" полные подграфы.
    Для этого храним map: (subgraph1, subgraph1) -> numOfConnections. Каждый раз когда встречаем ребро -- с помощью СНМ находим к каким подграфам относятся вершины и увеличиваем значение в map (или добавляем единицу, если ключа не было). Если значение оказалось больше чем произведение размеров подграфов -- сливаем их.

    UPD: проблема жадного алгоритма в том, что мы получим не максимальный подграф. Иногда делать очередное слияние не выгодно. Например есть маленький подграф А, и 2 больших B и C. B можно слить с С или с А, но все 3 не образуют полный граф. Тогда если мы сольем B и A, то оптимальное решение уже не получится.
    Ответ написан
  • Где ошибка в реализации алгоритма QuickSort?

    tsarevfs
    @tsarevfs Куратор тега C++
    C++ developer
    Вектор передаете по значению. При каждом вызове функции будет создаваться копия. Исправить эту ошибку так: void Quicksort(vector<int> &A, int p, int r)
    Ответ написан
  • Почему выражение делится на 6?

    tsarevfs
    @tsarevfs
    C++ developer
    Да вроде не правда это. m=2, n=1, 2^5 - 1^10 = 32 - 1 = 31
    Ответ написан
    1 комментарий
  • Как правильно собрать кроссплатформенный проект?

    tsarevfs
    @tsarevfs Куратор тега C++
    C++ developer
    MyClass_L.cpp и MyClass_W.cpp нужно тоже целиком завернуть в ifdef
    Либо, что наверно более правильно, надо сказать вашей системе сборки (qmake я так понимаю), что надо собирать только нужные cpp.
    doc.qt.io/archives/qt-4.8/qmake-tutorial.html "Adding Platform-Specific Source Files"
    Ответ написан
  • Как создать дерево, каждая вершина которого содержит указатель на элемент данных void*?

    tsarevfs
    @tsarevfs Куратор тега C++
    C++ developer
    Если это не лаба, которую нужно было сдать вчера, то стоит начать с чего-то более простого (в противном случае вам к фрилансерам). Возможно что-то из этого вы уже делали, но из вашего вопроса кажется, что вы не знаете с чего начать. Задание сложное для начинающего, будьте готовы потратить на него несколько дней из новогодних праздников.

    Структуры. Ключевое слово struct. Именно они будут элементами. Прочитайте про них.
    Структуры данных на указателях. Дерево -- сложная структура. Начните с односвязного списка. Примеров куча в сети. Тут вам не обойтись без функций. А еще лучше написать класс LinkedList.
    Итераторы. Когда написан список, попробуйте разобраться с итераторами. Написать итератор для списка не сложно, но тут уже нужно иметь минимальные представления о классах, методах, перегрузке операторов.
    Если сложно, то можно обойтись без них, задача не сильно пострадает.
    Деревья. После того как написан список, разобраться с деревьями будет проще. Забейте на "элемент данных void*", пусть у вас это будет то же что и в любом понравившемся примере из интернета. Тем более, в C++ стараются избегать void*.
    Обход дерева. Итераторы предполагают, что вы сможете перебирать элементы дерева в некотором порядке. В основном используют 2 подхода: обход в глубину и обход в ширину. Первый несколько проще реализовывать с помощью рекурсии. Для второго может потребоваться структура данных очередь, которую будет полезно написать на основе односвязного списка.
    Дерево поиска. Вас просят сделать так, чтобы меньшие элементы были ближе к корню дерева. Есть структура данных "куча"(обычно бинарная куча) , которая это обеспечивает. Но на практике чаще используют деревья поиска, которые тоже это гарантируют. Это достаточно непростая тема, к ней можно вернуться как закончите с остальным.
    Ответ написан
    1 комментарий
  • Как сравнить 2 вектора и удалить элементы из второго?

    tsarevfs
    @tsarevfs Куратор тега C++
    C++ developer
    Первый вариант -- просто сделать это:
    std::erase(
    	std::remove_if(myVec.begin(), myVec.end(), 
    		[&newVec](const A &a)
    		{
    			return std::find_if(newVec.begin(), newVec.end(), [&a](const A &newA){ return a.id ==  newA.id; }) == newVec.end();
    		}),
    	myVec.end());


    Для упрощения можно перегрузить оператор == для A так, чтобы он сравнивал id:
    struct A
    {
    	//...
    	bool operator==(const A &other) const
    	{
    		return a.id == other.id;
    	}
    	//...
    };
    
    std::erase(
    	std::remove_if(myVec.begin(), myVec.end(), 
    		[&newVec](const A &a)
    		{
    			return std::find(newVec.begin(), newVec.end(), a) == newVec.end();
    		}),
    	myVec.end());


    Эти решения будут пробегать по всем элементам из newVec для каждого элемента в myVec. Уже при размере в 1000 элементов для каждого, надо будет сделать 1 000 000 сравнений. ВЫход -- использовать set или unordered_set:

    namespace std
    {
    	//для unordered_set
    	template<>
    	struct hash<A>
    	{
    		std::size_t operator()(const A &a)
    		{
    			return std::hash<int>()(a.id);
    		}
    	}
    
    	//для std::set
    	template<>
    	struct less<A>
    	{
    		bool operator()(const A &lha, const A &rha)
    		{
    			return lha.id < rha.id;
    		}
    	}
    }
    
    std::unordered_set<A> newSet;
    //std::set<A> newSet
    
    newSet.insert(a);
    newSet.insert(b);
    newSet.insert(d);
    
    std::erase(
    	std::remove_if(myVec.begin(), myVec.end(), 
    		[&newSet](const A &a)
    		{
    			return newSet.find(a) == newSet.end();
    		}),
    	myVec.end());
    Ответ написан
    Комментировать
  • Алгоритм выполнения следующей задачи?

    tsarevfs
    @tsarevfs Куратор тега C++
    C++ developer
    Если нужны идеи, то это частный случай задачи о рюкзаке или задачи о сумме подмножеств.
    Ответ написан
    Комментировать
  • Как повернуть матрицу на одну позицию по часовой стрелке?

    tsarevfs
    @tsarevfs Куратор тега C++
    C++ developer
    Функции очень помогут вам разбить задачу на более простые части.
    ///Повернуть рамку на 1 позицию
    ///\param top номер строки левого верхнего угла рамки в исходной матрице
    ///\param left номер колонки левого верхнего угла рамки в исходной матрице
    ///\param width ширина рамки (количество колонок)
    ///\param width height высота рамки (количество строк)
    ///         left
    ///          | w
    ///       ************
    ///  top--***abcdef***
    ///      h***n****g***
    ///       ***mlkjih***
    ///       ************
    ///
    /// rotateFrame(matrix, 1, 3, 6, 3)
    void rotateFrame(int **matrix, int top, int left, int width, int height)
    {
        if (width == 1)
        {
            int copyOfLast = shiftColumn(matrix, top, left, height, true);
            matrix[top][left] = copyOfLast
            return;
        }
    
        if (height == 1)
        {
            int copyOfLast = shiftRow(matrix, top, left, width, true);
            matrix[top][left] = copyOfLast
            return;
        }
    
        //верхняя строка
        int copyOfLast = shiftRow(matrix, top, left, width, true);
        
        //левый столбец
        shiftColumn(matrix, top, left, height, false);
    
        //нижняя строка
        shiftRow(matrix, top + height  - 1, left, width, false);
    
        //правый столбец
        shiftColumn(matrix, top, left + width - 1, height, true);
    
        //восстанавливаем элемент из правого верхнего угла
        matrix[top + 1][left + width - 1] = copyOfLast;
    }
    
    ///Сдвинуть участок строки длинной length на одну позицию в лево или право в зависимости от shiftLeft.
    ///Первый элемент не изменяется, последний пропадает.
    ///Возвращает элемент, который будет утрачен.
    
    ///   **abcd** -> **aabc** (shiftLeft == true), возвращаем d
    ///   **abcd** -> **bcdd** (shiftLeft == false), возвращаем a
    int shiftRow(int **matrix, int top, int left, int length, bool shiftLeft)
    {
    
    }
    
    ///Аналогично shiftRow, но для столбца
    int shiftColumn(int **matrix, int top, int left, int length, bool shiftDown)
    {
    
    }
    Ответ написан
  • При 3d визуализации сливаются грани и рёбра меша. Как исправить?

    tsarevfs
    @tsarevfs
    C++ developer
    Нужно добавить освещение. Тогда поверхности под разным углом к свету будут визуально отличаться.

    https://myogre.wordpress.com/2011/10/17/man2/
    Посмотрите секцию "Создание источников света".
    Ответ написан
    4 комментария