Показать сообщение отдельно
Старый 23.11.2010, 02:26   #14  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от gl00mie Посмотреть сообщение
извечные проблемы с итераторами
если честно, то очень хочется использовать рекурсию.
но рекурсия - слишком расточительное удовольствие.

может изменить постановку? может не нужно списка, а достаточно всего лишь одной пары?
Тогда
1. в метод передаются два множества.
2. метод возвращает одну пару для замены (или пустое значение)
3. метод (или вызывающий код) убирает полученную пару из множеств
4. снова вызвать метод

тогда на псевдокоде это будет выглядеть так
X++:
[oldKey, newKey] getPair(oldSet, NewSet)
{
    if( oldSet.empty() )
        return []; // нечего менять - поэтому ничего менять не нужно 

    if( newSet.empty() )
        return []; // не на что менять - поэтому ничего менять не нужно 

    seedSet = Set::difference( newSet, oldSet ); // зародыши: новые значения будут браться отсюда
    if( seedSet.empty() )
        return []; // нет новых значений (уже использованы или множества совпадают) - ничего менять не нужно 

    deadSet = Set::difference( oldSet, newSet ); // мертвенькие: они исчезнут
    if( deadSet.empty() )
        return []; // все старые значения уже есть в новых (или множества совпадают) - ничего менять не нужно 

    newKey = seedSet.anyValue(); // любое значение из множества зародышей
    oldKey = deadSet.anyValue(); // любое значение из множества мертвеньких
    return [oldKey, newKey];
}

pair = getPair( oldSet, newSet );
while( pair != [] )
{
    [oldKey, newKey] = pair;
    // do something with oldKey, newKey

    // next iteration
    oldSet.remove(oldKey);
    newSet.remove(newKey);
    pair = getPair( oldSet, newSet );
}
другими словами:
а) если множество старых и множество новых совпадают, то ничего менять не нужно
б) стараемся совпадающее не трогать (чтобы уменьшить число операций с базой)

как-то так.
главное - по ходу множества уменьшаются. Типа псевдорекурсия. И никаких итераторов

в качестве дальнейшей оптимизации можно подумать о совмещении difference+anyValue.
Но не уверен, что реализованный на X++ метод difference получится быстрее, чем в ядре.

============
Спасибо за интересную задачу.
У меня RU6 поставился. Пойду спать
__________________
полезное на axForum, github, vk, coub.