WedX - журнал о программировании и компьютерных науках

Java - сгладить массив с помощью рекурсии

Я практиковал алгоритмы, и рекурсия всегда была моим слабым местом. Эта проблема требует свести вложенный массив в один массив. Это было бы просто, если использовать цикл, дающий решение O (n ^ 3) [с учетом трехмерного массива одинакового размера].

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

Я хочу двух вещей: можно ли как-то исправить мой текущий код, чтобы получить правильный вывод, и есть ли более простой и менее запутанный способ написать этот код с использованием рекурсии, спасибо!

Бонусные вопросы: если бы я не знал размеров вложенного массива, как бы я решил эту проблему, используя рекурсию?

EDIT Итак, после жесткого кодирования (чего я не хочу делать) мне удалось заставить это работать. Но код теперь жестко запрограммирован и очень запутан, можно ли как-то очистить код или найти более простой способ решить эту проблему с помощью рекурсии?

EDIT2 Я пытаюсь повторить эту проблему, используя рекурсию вспомогательного метода. Я посмотрю, повезет ли мне больше, используя этот стиль

import java.io. * ;
    import java.util. * ;
    class Solution {
    // static int oneLen = 0;
    //static int twoLen = 0;
    //static int threeLen = 0;

    static int oneCnt = 0;
            static int twoCnt = 0;
            static int threeCnt = 0;
            static ArrayList < Integer > result = new ArrayList < Integer > ();
            public static ArrayList < Integer > flatten(int [][][] arr){

    if (oneCnt < arr[threeCnt][twoCnt].length && !(oneCnt == 2 && twoCnt == 2 && threeCnt == 2))
    {


    if (oneCnt == 0 && twoCnt == 0 && threeCnt == 0){
    result.add(arr[threeCnt][twoCnt][oneCnt]);
            oneCnt++;
            result.add(arr[threeCnt][twoCnt][oneCnt]);
            System.out.println("Line One");
            System.out.println("Count1:  " + oneCnt);
            System.out.println("Count2:  " + twoCnt);
            System.out.println("Count3:  " + threeCnt);
    }
    oneCnt++;
            if (oneCnt != 3){
    result.add(arr[threeCnt][twoCnt][oneCnt]); }






    System.out.println("Line One");
            System.out.println("Count1:  " + oneCnt);
            System.out.println("Count2:  " + twoCnt);
            System.out.println("Count3:  " + threeCnt);
            flatten(arr);
    }     else if (oneCnt == arr[threeCnt][twoCnt].length && twoCnt < arr[threeCnt].length - 1){


    //oneLen = 0;    
    oneCnt = 0;
            // twoLen++;


            twoCnt++;
            result.add(arr[threeCnt][twoCnt][oneCnt]);
            System.out.println("Line Two");
            System.out.println("Count:1  " + oneCnt);
            System.out.println("Count:2  " + twoCnt);
            System.out.println("Count:3  " + threeCnt);
            flatten(arr);
    }

    else if (oneCnt == arr[threeCnt][twoCnt].length && twoCnt == arr[threeCnt].length - 1 && threeCnt < arr.length - 1){

    oneCnt = 0;
     twoCnt = 0;
            threeCnt++;
            result.add(arr[threeCnt][twoCnt][oneCnt]);
            System.out.println("Line Three");
            System.out.println("Count:1  " + oneCnt);
            System.out.println("Count:2  " + twoCnt);
            System.out.println("Count:3  " + threeCnt);
            flatten(arr);
    }
    return result;
    }
    public static void main(String[] args) {
    int[][][] array =
    {  { {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} } };
            flatten(array);
            for (int i = 0; i < result.size(); i++){
    System.out.print(result.get(i) + ",");
    }
    }
    }

вывод: 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,

Edit3 После использования вспомогательной рекурсии у меня почти есть ответ, но последний элемент не добавляется в список массивов.

import java.io. * ;
    import java.util. * ;
    class Solution {



    static ArrayList < Integer > result = new ArrayList < Integer > ();
            public static void flatten(int [][][] arr){
    int oneLen = 0;
            int twoLen = 0;
            int threeLen = 0;
            flattenHelper(arr, oneLen, twoLen, threeLen);
    }

    public static void flattenHelper(int [][][] arr, int oneLen, int twoLen, int threeLen){

    if (oneLen < arr[threeLen][twoLen].length - 1){
    System.out.println("Line One");
            System.out.println("Count:1  " + oneLen);
            System.out.println("Count:2  " + twoLen);
            System.out.println("Count:3  " + threeLen);
            result.add(arr[threeLen][twoLen][oneLen]);
            flattenHelper(arr, oneLen + 1, twoLen, threeLen);
    }
    else if (twoLen < arr[threeLen].length - 1){
    System.out.println("Line Two");
            System.out.println("Count:1  " + oneLen);
            System.out.println("Count:2  " + twoLen);
            System.out.println("Count:3  " + threeLen);
            result.add(arr[threeLen][twoLen][oneLen]);
            flattenHelper(arr, oneLen = 0, twoLen + 1, threeLen);
    }     else if (threeLen < arr.length - 1){
    System.out.println("Line Two");
            System.out.println("Count:1  " + oneLen);
            System.out.println("Count:2  " + twoLen);
            System.out.println("Count:3  " + threeLen);
            result.add(arr[threeLen][twoLen][oneLen]);
            flattenHelper(arr, oneLen = 0, twoLen = 0, threeLen + 1);
    }

    }

    public static void main(String[] args) {
    int[][][] array =
    {  { {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} } };
            flatten(array);
            for (int i = 0; i < result.size(); i++){
    System.out.print(result.get(i) + ",");
    }
    }
    }

вывод: 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,

21.10.2016

Ответы:


1

Это рекурсивно, вам не нужно менять структуру ввода, и ему не нужно знать размер вашего массива. Вы можете сойти с ума и смешивать массивы, списки и другие объекты, он вернет ArrayList :

package stackOverflow;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

public class Solution
{
    public static void main(String[] args) {
        int[][][] int3dArray = { { { 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 } } };
        String[][] string2dArray = { { "He, llo" }, { "Wo", "rld" } };
        String[] stringArray = { "Hello", "World" };
        Object[] objectArray = { "Hell", 0, "W", 0, "rld" };

        List<Object> mixList = new ArrayList<Object>();
        mixList.add("String");
        mixList.add(3);
        mixList.add(string2dArray);

        System.out.println(flatten(int3dArray));
        System.out.println(flatten(flatten(int3dArray)));
        System.out.println(flatten(3));
        System.out.println(flatten(stringArray));
        System.out.println(flatten(string2dArray));
        System.out.println(flatten(objectArray));
        System.out.println(flatten(mixList));
    }

    private static List<Object> flatten(Object object) {
        List<Object> l = new ArrayList<Object>();
        if (object.getClass().isArray()) {
            for (int i = 0; i < Array.getLength(object); i++) {
                l.addAll(flatten(Array.get(object, i)));
            }
        } else if (object instanceof List) {
            for (Object element : (List<?>) object) {
                l.addAll(flatten(element));
            }
        } else {
            l.add(object);
        }
        return l;
    }
}

Он выводит:

[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]
[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]
[3]
[Hello, World]
[He, llo, Wo, rld]
[Hell, 0, W, 0, rld]
[String, 3, He, llo, Wo, rld]

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

Вот мое оригинальное решение, которое отображало только результаты, но возвращало void :

package stackOverflow;

import java.lang.reflect.Array;


public class Solution
{
    public static void main(String[] args) {
        int[][][] array = { { { 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 } } };
        flatten(array);
    }

    private static void flatten(Object object) {
        if (object.getClass().isArray()) {
            for (int i = 0; i < Array.getLength(object); i++) {
                flatten(Array.get(object, i));
            }
        } else {
            System.out.print(object + ",");
        }
    }
}

Он возвращает: 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,

22.10.2016
  • Благодарю вас! Это именно то, что я искал с точки зрения ответов на бонусные вопросы, которые у меня были. 22.10.2016
  • Могу я спросить, что делает библиотека Reflect и как она соотносится с этими решениями? Пытаюсь найти документацию по нему, спасибо. 22.10.2016
  • Вот хорошее начало: docs.oracle.com/javase/tutorial/reflect По сути, это делает Java немного менее жесткой и предоставляет некоторые методы, которые чаще встречаются в таких языках, как Python и Ruby. Иногда вы не можете знать все во время компиляции, и вам нужно дождаться времени выполнения. Например: я знаю, что этот объект будет выглядеть как массив, это может быть int[][] или это может быть ArrayList‹Integer›, я просто хочу перебрать все элементы. 22.10.2016

  • 2

    Если вы можете изменить данные как массивы Integer вместо int, вы можете проверить элементы переданного массива и выполнить рекурсию для элементов, которые являются массивами, или просто добавить их непосредственно в результат, если нет.

    public static ArrayList<Integer> flatten(Object [] arr) {
        ArrayList<Integer> result = new ArrayList<>();
    
        for (int i = 0; i < arr.length; i++) {
            if (arr[i].getClass().isArray()){
                result.addAll(flatten((Object[])arr[i]));
            } else {
                result.add((int)arr[i]);
            }
        }
    
        return result;
    }
    
    21.10.2016
    Новые материалы

    Как создать диаграмму градиентной кисти с помощью D3.js
    Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


    Для любых предложений по сайту: [email protected]