Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перебор массива/коллекции, Эффективный способ рекурсивного перебора 
V
    Опции темы
tepkuh
Дата 13.5.2010, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 23.4.2008

Репутация: нет
Всего: нет



Добрый день уважаемые,
Я вот который час подряд уже бьюсь с эффективным способом перебора массива. Ну никак не выходит что то красивое, помогите плиз.
Суть такая:
Есть коллекция HashMap<String, Set>
Выглядит так:
1->[a,b,c,d]
2->[s,r,h,j,k,l,a,...]
3->[v,x,g,q,a,z,p,a...]
4->[x,f,a,c,e,y...]

Длинна ХэшМапа большая, может измеряться сотнями столбцов. Длинна Set измеряется десятками\сотнями позиций. 
Каждый столбец и каждая позиция используется только один раз, 
например первая итерация:
a+s+y+x
Вторая
a+s+y+f
Третья 
a+s+y+a 
и так далее...
Если пробую рекурсию ухожу в нехватку стека. Увеличивать стек не вариант ибо не красиво)

Памажите идей плиз) 
PM MAIL   Вверх
AntonSaburov
Дата 13.5.2010, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

Репутация: 51
Всего: 118



Не очень понятно, что за алгоритм надо реализовать. Из примера ничего не понял.
Какие столбцы и какие позиции ? Где они ? В Set ? В каждом ? Или в разбивку ?
PM MAIL WWW ICQ   Вверх
Sibit
Дата 14.5.2010, 05:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 96
Регистрация: 6.10.2009
Где: NSK

Репутация: нет
Всего: 1



Рекурсию на больших объемах данных лучше вообще не использовать, т.к. паять жрет она токо так.

А что в результате получить нужно?
PM MAIL   Вверх
MisterCleric
Дата 14.5.2010, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 5
Всего: 38



 smile 
Цитата

А что в результате получить нужно? 


Я так думаю хочет написать программку подбора паролей...

По-моему, надо милицию вызывать


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
tepkuh
Дата 14.5.2010, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 23.4.2008

Репутация: нет
Всего: нет



Цитата(AntonSaburov @ 13.5.2010,  18:30)
Не очень понятно, что за алгоритм надо реализовать. Из примера ничего не понял.
Какие столбцы и какие позиции ? Где они ? В Set ? В каждом ? Или в разбивку ?

Да тут без поллитры не объяснить)
Надо просто перебрать все столбцы и строки по сути. У меня массив просто в виде коллекции где строки это коллекция Set, а столбцы это коллекция Map.
Т.е. у меня есть таблица определенного количества строк, каждая строка в таблице имеет разное число столбцов, выглядит примерно так:

Код

1|a|b|c|d|
2|s|r|h|j|k|a|
3|v|x|g|q|a|z|p|

Так же оговорюсь что таблица это может быть большой и она динамическая(может иметь разное количество строк и столбцов, как большое число строк\столбцов так и малое), настолько большой, что рекурсией перебрать не получится, просто не хватает стека. Т.е. это у нас данные. 

Перебор данных осуществляется так что берется  только одно значение из каждой строки. 

Показываю свой индус-код, чисто поржать, но ничего умнее не идет.
Код

public static void main(String[] args){

        Map<String,Set> tmp_map = new TreeMap<String,Set>();//По сути это строки массива
        Set<String> tmp_set1 = new TreeSet<String>();//Столбецы 
        Set<String> tmp_set2 = new TreeSet<String>();//Столбецы 
        Set<String> tmp_set3 = new TreeSet<String>();//Столбецы 
        tmp_set1.add("a1");//Ячейка первой строки, 1го стольбца
        tmp_set1.add("b1");//Ячейка первой строки, 2го стольбца
        tmp_set1.add("c1");//Ячейка первой строки, 3го стольбца
        tmp_set1.add("d1");//Ячейка первой строки, 4го стольбца

        tmp_set2.add("a2");//Ячейка второй строки, 1го стольбца
        tmp_set2.add("b2");//Ячейка второй строки, 2го стольбца
        tmp_set2.add("c2");//Ячейка второй строки, 3го стольбца
        tmp_set2.add("d2");//Ячейка второй строки, 4го стольбца
        tmp_set2.add("e2");//Ячейка второй строки, 5го стольбца
        tmp_set2.add("f2");//Ячейка второй строки, 6го стольбца

        tmp_set3.add("a3");
        tmp_set3.add("b3");
        tmp_set3.add("c3");
        tmp_set3.add("d3");
        tmp_set3.add("e3");       

        tmp_map.put("1", tmp_set1);
        tmp_map.put("2", tmp_set2);
        tmp_map.put("3", tmp_set3);
        
        //Дальше можно смеяться, пошел идус-код, преобразую Map в Аrray, потому что с Итератором в данном случаи не удобно работать, так как его просто фиг склонируешь.
        Object[] objectArray = tmp_map.entrySet().toArray();
        Vector result = new Vector(); //Сюда мы пишем результат
        Plunk2(objectArray, result);//Собственно индус функция

public static void Plunk2(Object[] obj, Vector result) {
        try{
            //Выводим результат на экран 
            if (obj.length-1<0){
                for(int i=0;i<result.size();i++){
                    System.out.print(result.get(i));
                }
                System.out.println();
                return;
            }
            //Убираем одну строку из нашего массива с данными
            Object[] obj2 = new Object[obj.length-1];
            for(int i=1;i<obj.length;i++){
                obj2[i-1] = obj[i];
            }
            //Мега индус-рекурсия тут осуществляется
            for(int i=0;i<obj.length;i++){
                Map.Entry entry = (Map.Entry)obj[i];
                Set synons = (Set)entry.getValue();
                Iterator iter_synons = synons.iterator();
                while(iter_synons.hasNext()){
                    String synon = (String)iter_synons.next();
                    result.add(synon);
                    Plunk2(obj2,result);
                    result.remove(result.lastElement());
                }
            }
        }
        catch (Exception q) {
            q.printStackTrace();
        }
    }

Код

сам результат работы моей магии кода:
a1a2a3
a1a2b3
a1a2c3
a1a2d3
a1a2e3
a1b2a3
a1b2b3
a1b2c3
a1b2d3
a1b2e3
a1c2a3
a1c2b3
a1c2c3
a1c2d3
a1c2e3
a1d2a3
a1d2b3
a1d2c3
a1d2d3
a1d2e3
a1e2a3
a1e2b3
a1e2c3
a1e2d3
a1e2e3
a1f2a3
a1f2b3
a1f2c3
a1f2d3
a1f2e3
a1a3a3
a1a3b3
a1a3c3
a1a3d3
a1a3e3
a1b3a3
a1b3b3
a1b3c3
a1b3d3
a1b3e3
a1c3a3
a1c3b3
a1c3c3
a1c3d3
a1c3e3
a1d3a3
a1d3b3
a1d3c3
a1d3d3
a1d3e3
a1e3a3
a1e3b3
a1e3c3
a1e3d3
a1e3e3
b1a2a3
b1a2b3
...


Добавлено @ 11:35
Цитата(MisterCleric @  14.5.2010,  09:43 Найти цитируемый пост)
Я так думаю хочет написать программку подбора паролей...

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

Это сообщение отредактировал(а) tepkuh - 14.5.2010, 13:08
PM MAIL   Вверх
pathfinder
Дата 14.5.2010, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 3.3.2010

Репутация: 2
Всего: 10



Почти псевдокод )

Код

int mapSize = map.size();

Object[][] setArray;
int[] indexArray;
int[] setLengthArray;

Object[] resultArray;

// todo : перегнать Map -> setArray
// todo : инициализировать setLengthArray: setLengthArray[i] = i-ой Set.size()

main_loop:
while (true) {
    
    // собираем результат
    for (int i=0; i<mapSize; i++) {
        resultArray[i] = setArray[i][indexArray[i]];
    }
    
    // обрабатываем результат ...
    
    // увеличиваем индексы сверху-вниз ...
    for (int i=0; i<mapSize; i++) {
        indexArray[i] = indexArray[i] + 1;
        if (indexArray[i] < setLengthArray[i]) {
            break;
        }
        indexArray[i] = 0;
        if (i + 1 == mapSize) {
            break main_loop;
        }
    }
    
}

PM MAIL   Вверх
tepkuh
Дата 14.5.2010, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 23.4.2008

Репутация: нет
Всего: нет



Цитата(pathfinder @  14.5.2010,  12:19 Найти цитируемый пост)
// todo : перегнать Map -> setArray

кхм... думал об этом.
У меня размерность таблицы моей может доходить до нескольких тысяч строк вниз, и столько же вправо.
Для того чтобы их перегнать(а я так понял их перегонять только циклом) это должен крутануть цикл до нескольких лимонов раз. Только на инициализацию setArray.
Мой Индус-код быстрее получится даже имхо так как Вам этот цикл надо крутать дважды(перегнон в setArray) а дальше еще пройтись по каждой ячейки
PM MAIL   Вверх
pathfinder
Дата 14.5.2010, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 3.3.2010

Репутация: 2
Всего: 10



А если так

Код

int mapSize = map.size();

Set[] setArray = new Set[mapSize];
Iterator[] iteratorArray = new Iterator[mapSize];
Object[] resultArray = new Object[mapSize];

// todo заполнить setArray из Map
// todo заполнить iteratorArray: iteratorArray[i] = setArray[i].iterator();

for (int i=0; i<mapSize; i++) {
    resultArray[i] = iteratorArray[i].next();
}

main_loop:
while(true) {
    
    // handle resultArray ...
    
    for (int i=0; i<mapSize; i++) {
        if (iteratorArray[i].hasNext()) {
            resultArray[i] = iteratorArray[i].next();
            break;
        } else {
            if (i + 1 == mapSize) {
                break main_loop;
            }
            iteratorArray[i] = setArray[i].iterator();
            resultArray[i] = iteratorArray[i].next();
        }
    }
}

PM MAIL   Вверх
tepkuh
Дата 14.5.2010, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 23.4.2008

Репутация: нет
Всего: нет



у меня дает результат 825 вариантов перебора, у вас 155 =). Выпадает чиво то)

Код Ваш с Инициализацией:
Код

        int mapSize = tmp_map.size();
        Set[] setArray = new Set[mapSize];
        Iterator[] iteratorArray = new Iterator[mapSize];
        //Пошла Инициализация
        Iterator iter = tmp_map.entrySet().iterator();
        int k=0;
        while(iter.hasNext()){
            setArray[k]=  (Set)((Map.Entry)iter.next()).getValue();
            iteratorArray[k] = setArray[k].iterator();
            k++;
        }
         //Кончилась Инициализация 
        Object[] resultArray = new Object[mapSize];
        for (int i=0; i<mapSize; i++) {
            resultArray[i] = iteratorArray[i].next();
        }
        for(int q=0;q<resultArray.length;q++){
            System.out.print(resultArray[q]);
        }
        System.out.println();

        main_loop:
        while(true) {
            // handle resultArray ...
            for (int i=0; i<mapSize; i++) {
                if (iteratorArray[i].hasNext()) {
                    resultArray[i] = iteratorArray[i].next();
                    for(int q=0;q<resultArray.length;q++){
                        System.out.print(resultArray[q]);
                    }
                    System.out.println();
                    break;
                }
                else {
                    if (i + 1 == mapSize) {
                        break main_loop;
                    }
                    iteratorArray[i] = setArray[i].iterator();
                    resultArray[i] = iteratorArray[i].next();
                    for(int q=0;q<resultArray.length;q++){
                        System.out.print(resultArray[q]);
                    }
                    System.out.println();
                }
            }
        }


Добавлено через 11 минут и 21 секунду
+у вас идут повторения переборов) где то ошибка у Вас в коде) Пытаюсь воткнуть что хотели написать)ы

Это сообщение отредактировал(а) tepkuh - 14.5.2010, 14:00
PM MAIL   Вверх
pathfinder
Дата 14.5.2010, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 3.3.2010

Репутация: 2
Всего: 10



Для просмотра результата надо подставить

Код

for(int q=0;q<resultArray.length;q++){
                        System.out.print(resultArray[q]);
                    }
                    System.out.println();


вместо

Код

// handle resultObject


и вопрос в догонку - при количестве колонок около 1000 и количестве элементов в колонке > 10, разве потребное количество итераций не будет пропорционально 10^1000(или точнее произведению длин колонок)?


Это сообщение отредактировал(а) pathfinder - 14.5.2010, 14:14
PM MAIL   Вверх
tepkuh
Дата 14.5.2010, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 23.4.2008

Репутация: нет
Всего: нет



Цитата(pathfinder @  14.5.2010,  14:14 Найти цитируемый пост)
или точнее произведению длин колонок

да, точное произведение длин всех колонок) Итераций много) выйдет. Но это даже хорошо) Чем их больше тем я буду счастливей. 
Спасибо вам большое действительно все работает) (это у меня не работало))Вы очень очень мне помогли)
PM MAIL   Вверх
pathfinder
Дата 14.5.2010, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 3.3.2010

Репутация: 2
Всего: 10



Всегда пожалуйста ) Если вопрос решен тему желательно закрывать.
PM MAIL   Вверх
tepkuh
Дата 15.5.2010, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 23.4.2008

Репутация: нет
Всего: нет



Помечаем что вопрос решен)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1334 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.