Форум программистов, компьютерный форум, киберфорум
JavaScript для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/12: Рейтинг темы: голосов - 12, средняя оценка - 5.00
82 / 50 / 2
Регистрация: 31.12.2019
Сообщений: 418
1

Усовершенствование функции (определитель массива)

22.04.2020, 22:43. Показов 2458. Ответов 5

Author24 — интернет-сервис помощи студентам
Функция находит определитель массива, работает правильно (вроде);
Хотелось бы усовершенствовать ее, то есть слегка укоротить, оставляя принцип решения таким же(если это совместимо).
(Полная функция в самом конце)
Теперь конкретно:
1) хотелось бы заменить эту часть (а в последствии и для длинны =5)

Javascript
1
2
3
4
5
6
7
8
 } else if (arr.length == 4) {
            return arr[0][0] * deter(arr.slice(1).map((x)=> x.slice(1)))
               
                - arr[0][1] * deter(arr.slice(1).map((x)=>[...x.slice(0,1), ...x.slice(2)]))
                
                + arr[0][2] * deter(arr.slice(1).map((x)=>[...x.slice(0,2), ...x.slice(3)]))
                                    
                - arr[0][3] * deter(arr.slice(1).map((x)=>x.slice(0,3)));
на что-нибудь такое (не соображу как правильно оформить, хотя и вижу что что-то не так с return, и конечно выдает не правильный ответ), если это возможно:

Javascript
1
2
3
4
5
6
} else if (arr.length == 4) {
//          for (let i = 0; i < arr.length; i++) {
//            if( (i % 2) == 0 ) { return arr[0][i] * deter(arr.slice(1).map((x)=>[...x.slice(0,i), ...x.slice(i+1)]));
//                        } else { return -arr[0][i] * deter(arr.slice(1).map((x)=>[...x.slice(0,i), ...x.slice(i+1)]))
//                                      }
//          }
2) можно ли заменить все ту же часть из пункта 1, используя метод call/apply?
(Для чего? -чтобы, возможно, сократить, да и просто интересно как это выглядит).
к примеру, тут мы бы вместо этого + arr[0][2] * deter(arr.slice(1).map((x)=>[...x.slice(0,2), ...x.slice(3)]))
подставляли что -нибудь типа: ... * deter(cut.apply(this, ... и значение) ,
а функция бы уже обрезала по заданным параметрам?


Javascript
1
2
3
4
5
6
//  function cut(array, a) {
//    console.log(arguments[0])
//    return  [].slice.call(arguments[0], a);
//
//    
//    }
только обрезать она должна уже вот примерно по такому шаблону arr.slice(1).map((x)=>[...x.slice(0,a), ...x.slice(a+1)])
или я 'перемудрил'?))


Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function deter (arr) {
        if (arr.length == 2) {
            return arr[0][0] * arr[1][1] - arr[0][1] * arr[1][0];
        
        } else if (arr.length == 3) {
           return arr[0][0] * deter([[arr[1][1], arr[1][2]], [arr[2][1], arr[2][2]]]) 
                - arr[0][1] * deter([[arr[1][0], arr[1][2]], [arr[2][0], arr[2][2]]]) 
                + arr[0][2] * deter([[arr[1][0], arr[1][1]], [arr[2][0], arr[2][1]]]);
        
        } else if (arr.length == 4) {
//          for (let i = 0; i < arr.length; i++) {
//            if( (i % 2) == 0 ) {  arr[0][i] * deter(arr.slice(1).map((x)=>[...x.slice(0,i), ...x.slice(i+1)]));
//                        } else {  -arr[0][i] * deter(arr.slice(1).map((x)=>[...x.slice(0,i), ...x.slice(i+1)]))
//                                      }
//          }
            return arr[0][0] * deter(arr.slice(1).map((x)=> x.slice(1)))
               
                - arr[0][1] * deter(arr.slice(1).map((x)=>[...x.slice(0,1), ...x.slice(2)]))
                
                + arr[0][2] * deter(arr.slice(1).map((x)=>[...x.slice(0,2), ...x.slice(3)]))
                                    
                - arr[0][3] * deter(arr.slice(1).map((x)=>x.slice(0,3)));
                                     
        }else if (arr.length == 5) {
return arr[0][0] * deter(arr.slice(1).map((x)=> x.slice(1)))
            - arr[0][1] * deter(arr.slice(1).map((x)=>[...x.slice(0,1), ...x.slice(2)]))                  
            + arr[0][2] * deter(arr.slice(1).map((x)=>[...x.slice(0,2), ...x.slice(3)]))
            - arr[0][3] * deter(arr.slice(1).map((x)=>[...x.slice(0,3), ...x.slice(4)]))
            + arr[0][4] * deter(arr.slice(1).map((x)=>x.slice(0,4)));
        }
    }
console.log(deter([[2,3,0,5], [4,-3,-1,1], [2,5,1,3], [2,7,2,-2]])) //42
    console.log(deter([[2,3,0,5,3], [4,-3,-1,1,9], [2,5,0,1,3], [2,4,7,2,-2], [2,4,-7,2,5]])) //2408
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.04.2020, 22:43
Ответы с готовыми решениями:

Найти определитель массива по теореме Лапласа
Дан массив размера М х N найти определитель данного массива по теореме лапласа (размер массива...

Написать программу, оформив ее в виде функции: вычислить определитель матрицы 4 порядка.
№6 Написать программу, оформив ее в виде функции: вычислить определитель матрицы 4 порядка.

Определитель, минимальный и максимальный элементы двумерного массива (матрицы)
 Написать программу, которая вычисляет определитель квадратной матрицы второго порядка. ...

Если количество четных элементов массива меньше нечетных то подсчитать определитель
дан массив 7х7, если количество четное элементов меньше не четных то подщетать определитель,в...

5
6219 / 2467 / 725
Регистрация: 11.04.2015
Сообщений: 3,986
Записей в блоге: 43
23.04.2020, 00:42 2
Лучший ответ Сообщение было отмечено Schulzkafer как решение

Решение

Schulzkafer, вот смотри... тебе нужно определить логику нахождения алгебраического дополнения элемента массива, то есть массив, такой же как этот, только из него исключен определенный ряд и столбец. Ну и выдели эту логику в отдельную функцию, принимающую индексы ряда и столбца и возвращающую массив поменьше. Сначала фильтруем ряды, пропуская ненужный, потом оставшемуся делаем мэп, внутри которого тем же способом фильтруем уже отдельные элементы.
Javascript
1
2
3
4
5
6
        function det(mx)
        {
            const aj = (i, j) => mx.filter((v, ri) => i != ri)
                .map(v => v.filter((vv, ci) => j != ci));                
          
        }
Далее поскольку здесь явно рекурсивная логика, нужно определить для матрицы второго порядка нерекурсивную ветвь, что несложно, а для остальных - рекурсивную.Ну и собственно
Javascript
1
2
3
4
5
6
function det(mx)
{
    const aj = (i, j) => mx.filter((v, ri) => i != ri) .map(v => v.filter((vv, ci) => j != ci));                
    if (mx.length == 2) return mx[0][0] * mx[1][1] - mx[1][0] * mx[0][1];
    else return mx[0].map((v, i) => ((-1) ** i) * v * det(aj(0, i))).reduce((p, c) => p + c, 0);
}
Для проверки вычислил пару определителей в экселе
Javascript
1
2
3
4
5
6
7
8
console.log(det([[1,2,3],[4,5,6],[7,8,10]]),-3);
 
        let mx = [
            [34, 66, 78, 95],
            [67, 333, 76, 37],
            [4, 7, 88, 9],
            [8, 33, 13, 0]];
        console.log(det(mx), -5080227);
0
82 / 50 / 2
Регистрация: 31.12.2019
Сообщений: 418
23.04.2020, 04:17  [ТС] 3
У вас продвинутое решение для меня(т.к. я пока делаю акцент на циклах, а не на методах), пришлось слегка поразбиратьс
Но все понял, спасибо большое!
0
6219 / 2467 / 725
Регистрация: 11.04.2015
Сообщений: 3,986
Записей в блоге: 43
23.04.2020, 07:53 4
Лучший ответ Сообщение было отмечено Schulzkafer как решение

Решение

Цитата Сообщение от Schulzkafer Посмотреть сообщение
я пока делаю акцент на циклах
С циклами чуть длиннее будет, но логика сохраняется та же
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        function det2(mx)
        {
            if (mx.length == 2) return mx[0][0] * mx[1][1] - mx[1][0] * mx[0][1];
            else
            {
                const aj = (i, j) =>
                {
                    let copy = JSON.parse(JSON.stringify(mx));
                    copy.splice(i, 1);
                    for (let r of copy) r.splice(j, 1);
                    return copy;
                }
                let acc = 0;
                for (let i = 0; i < mx[0].length; i++)
                    acc += ((-1) ** i) * mx[0][i] * det2(aj(0, i));
                return acc;
            }
 
        }
        console.log(det2([[1, 2], [3, 4]]), -2);
        console.log(det2([[1, 2, 3], [4, 5, 6], [7, 8, 10]]), -3);
        console.log(det2(mx), -5080227);
1
82 / 50 / 2
Регистрация: 31.12.2019
Сообщений: 418
23.04.2020, 21:22  [ТС] 5
очень круто!! по мне это решение даже лучше чем первое, что вы написали!
Самое интересное, что я пытался тоже применить здесь let copy = JSON.parse(JSON.stringify(mx));
,о котором мы в прошлый раз говорили, но так и не додумался как его здесь исп-ть.
Ну и, стыдно об этом сказать, я даже не подумал об этом ((-1) ** i) тут, а именно этого момента мне и не хватало для изменения +-.

Добавлено через 14 минут
А какие способы еще существуют, кроме этого ((-1) ** i), или лучше сказать - можно применить тут, для все той же смены знаков? Я, например, думал об делении %, но не смог правильно написать остальную часть(как я писал выше), часть с return

Добавлено через 2 часа 54 минуты
Извиняюсь за излишнее беспокойство, я сразу не подумал об отличиях, толко потом, как обычно:

Javascript
1
2
3
4
5
6
7
8
9
10
  let acc = 0;
                for (let i = 0; i < mx[0].length; i++) 
                   if ( (i % 2) == 0)  { acc+= mx[0][i] * det2(aj(0, i)); 
                } else {
                    acc+= -mx[0][i] * det2(aj(0, i)); 
                }
                return acc;
            
            }
        }
Потому здесь это уже работает
0
6219 / 2467 / 725
Регистрация: 11.04.2015
Сообщений: 3,986
Записей в блоге: 43
24.04.2020, 14:32 6
Лучший ответ Сообщение было отмечено Schulzkafer как решение

Решение

Цитата Сообщение от Schulzkafer Посмотреть сообщение
acc+= -mx[0][i] * det2(aj(0, i));
Есть еще такой оператор -=, можно его использовать
Javascript
1
acc -= mx[0][i] * det2(aj(0, i))
Или покороче содержимое цикла можно записать так
Javascript
1
2
let r = mx[0][i] * det2(aj(0, i);
acc += i % 2 == 0 ? r : -r;
Или вторую строчку даже так
Javascript
1
acc += i % 2 ? -r : r;
0
24.04.2020, 14:32
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.04.2020, 14:32
Помогаю со студенческими работами здесь

Усовершенствование кода
Добрый вечер форумчане. Только вхожу в C++ и объектно-ориентированное программирование на нём,...

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

усовершенствование кода
как сделать чтобы он сначало показевал что написано в файле а уже потом просил изменить какоето...

Усовершенствование кода
Добрый вечер, хочу чтобы входные данные были (Введите значение функции: ) Но никак не получается...

усовершенствование скрипта
Здравствуйте, Имею рабочий скрипт который выводит Меню Родителей и детей. соответственно 2 цикла ...

Оптимизация и усовершенствование
Здравствуйте, совсем недавно начал изучать язык программирования &quot;С++&quot;. Решил попрактиковаться,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru