// Матрица переходов конечного автомата
// -1 - допустимое конечное состояние
// null - недопустимое состояние
const dka = [
[-1, 1, 5, 4, 10, 9, 15, 14], // 0
[-1, 2, 5, 4, 10, 9, 15, 14], // 1
[-1, 3, 5, 4, 10, 9, 15, 14], // 2
[-1, null, 5, 4, 10, 9, 15, 14], // 3
[-1, 8, 8, 7, null, null, null, null], // 4
[-1, null, null, 6, 10, 9, 15, 14], // 5
[-1, null, null, 7, 10, 9, 15, 14], // 6
[-1, null, null, 8, 10, 9, 15, 14], // 7
[-1, null, null, null, 10, 9, 15, 14], // 8
[-1, null, null, 13, 13, 12, null, null], // 9
[-1, null, null, null, null, 11, 15, 14], // 10
[-1, null, null, null, null, 12, 15, 14], // 11
[-1, null, null, null, null, 13, 15, 14], // 12
[-1, null, null, null, null, null, 15, 14], // 13
[-1, null, null, null, null, 18, 18, 17], // 14
[-1, null, null, null, null, null, null, 16], // 15
[-1, null, null, null, null, null, null, 17], // 16
[-1, null, null, null, null, null, null, 18], // 17
[-1, null, null, null, null, null, null, null], // 18
];
// Алфавит
const alphabet = 'MDCLXVI';
// Разбивает строку на лексемы
// (номера символов в алфавите, начиная с 1)
// для отсутствующих символов возвращает 0
const lexer = (str) => str.split('').map((l) => alphabet.indexOf(l) + 1);
// Проверяет корректность числа в римской записи
const check = (str) => {
const lexems = lexer(str);
let state = 0;
let idx = 0;
while (true) {
const lex = lexems[idx] ?? 0;
state = dka[state][lex];
if (state === null) {
return false;
}
if (state === -1) {
return idx === str.length;
}
idx += 1;
}
}
template< size_t ROWS, size_t COLUMNS >
struct Matrix final
{
template< size_t R = ROWS, size_t C = COLUMNS >
inline std::enable_if_t<R == C, int> GetDeterminant() const
{
return 0;
}
};
GetDeterminant
не удалось вывести из шаблона? Будет ошибка трансляции, говорящая о том, что метод не найден. Это ничего не говорит пользователю. Это просто инструктирует транслятор остановить трансляцию. Пользователь, особенно если он не искушен знаниями о SFINAE, не сможет понять причину ошибки трансляции. Такая ситуация создаст риск излишней траты времени на дознание причин ошибки.template< size_t ROWS, size_t COLUMNS >
struct Matrix final
{
template< size_t R = ROWS, size_t C = COLUMNS >
inline std::enable_if_t<R != C, int> GetDeterminant() const = delete;
template< size_t R = ROWS, size_t C = COLUMNS >
inline std::enable_if_t<R == C, int> GetDeterminant() const
{
return 0;
}
};
GetDeterminant
.template< size_t ROWS, size_t COLUMNS >
struct Matrix final
{
inline int GetDeterminant() const
{
static_assert( ROWS == COLUMNS, "Matrix should be square to calculate the determinant." );
return 0;
}
};
float power(float X, int N) {
if (N == 0) {
return 1;
}
if (N < 0) {
return 1. / power(X, -N);
}
if (N % 2 == 0) {
float b = power(X, N / 2);
return b * b;
}
return X * power(X, N - 1);
}
ArrayArray[0] = *new Array<int>{10};
ArrayArray[0]
вернет ссылку на Array<int>
.*new Array<int>{10}
выделяет память в куче под Array<int>
, вызывает инициализатор Array<int>::Array(int length)
, после чего делает разыменование получившегося указателя на Array<int>
.Array<int>
будет выполнен оператор копирования по умолчанию, функциональность которого просто скопирует поля из объекта справа в объект слева от присвоения.new Array<int>{10}
становится утекшим, т.к. указатель на него сразу становится потерян и освободить занимаемую им память становится невозможно.ArrayArray[0] = Array<int>{10};
ArrayArray[0]
вернет ссылку на Array<int>
.Array<int>{10}
инициализирует безымянный локальный объект на стеке, используя инициализатор Array<int>::Array(int length)
.T *m_data
.ArrayArray[0]
в этот момент начинает ссылаться на освобожденную память.ArrayArray
в конце работы программы пытается удалить уже освобожденную память в ArrayArray[0]
.Не выходитВышло бы только в случае ориентированного по сторонам света прямоугольника (т.е. верх строго на север, низ строго на юг, право строго на восток, лево строго на запад).
Если размер карты небольшой и кривизной земной поверхности можно пренебречь,...то можно использовать аффинное преобразование.
[DllImport("C:\\CMakeProject2.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "test")]
[SuppressUnmanagedCodeSecurity]
private static extern void Test();
function createTreeFromArray(arr, key, parentKey) {
const tree = Object.fromEntries(arr.map(n => [ n[key], { ...n } ]));
return Object.fromEntries(Object.entries(tree).filter(([ , n ]) => {
return !(tree[n[parentKey]] && ((tree[n[parentKey]].children ??= {})[n[key]] = n));
}));
}
const tree = createTreeFromArray(arr, 'uid', 'parentUID');
(int*)a
или используя касты.array[i]
) выполняет следующее действие: *(array+i)
.int*
, то после array[i]
вы получите int
, от которого уже нельзя взять второй индекс, т.к. это просто 1 int, а не массив.int **array = new int*[rowCount];
for(int i=0; i < rowCount; ++i)
array[i] = new int[colCount];
int**
и у вас будет работать оператор [][], т.к. первая индексация уже будет возвращать int*
.std::vector<std::vector<int>>
- это то же самое, что и вариант 1, но закамуфлированный под вектор :-)int (*array2)[colCount] = (int(*)[colCount]) array;
array2[i][j]
void average(int rowcount, int colcount, int aarray[rowCount][colCount])