Модераторы: Partizan, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Есть ли в dot.net класс реализующий двойную карту? Как Dictionary только в обе стороны. 
V
    Опции темы
Lavitar
Дата 11.5.2006, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Необходим класс, который мог бы работать как Dictionary только в обе стороны. Тоесть ключ является также значением, а значение также ключом.
Код

Class DualList<T1, T2>
{
    ...
    public T2 this[T1 key]
    .....
    public T1 this[T2 key]
}

Что-нибудь вроде такого синтаксиса.
PM MAIL   Вверх
HalkaR
Дата 11.5.2006, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пуфыстый назгул
****


Профиль
Группа: Экс. модератор
Сообщений: 2132
Регистрация: 8.12.2002
Где: В Москве

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



Код

class DoubleDict<T1, T2>
{
    private Dictionary<T1, T2> ValueToKey = new Dictionary<T1,T2>();
    private Dictionary<T2, T1> KeyToValue = new Dictionary<T2,T1>();
    public T1 this[T2 key]
    {
        get
        {
            return KeyToValue[key];
        }
        set
        {
            KeyToValue[key] = value;
            ValueToKey[value] = key;
        }
    }
    public T2 this[T1 key]
    {
        get
        {
            return ValueToKey[key];
        }
        set
        {
            KeyToValue[value] = key;
            ValueToKey[key] = value;
        }
    }        
}
Что-то подное?  

Это сообщение отредактировал(а) HalkaR - 11.5.2006, 22:32
PM MAIL   Вверх
Lavitar
Дата 11.5.2006, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Да...толькоя ищу готовый класс, который хорошо работает, ну разумеется грамотно написанный с поддержкой интерфейсов - IEnumerable, ICollection... 
PM MAIL   Вверх
arilou
Дата 12.5.2006, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Великий МунаБудвин
****


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

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



Lavitar, так в чем проблема? Используя вышеописанный класс можно сделать все что угодно. 


--------------------
user posted imageuser posted image
PM WWW ICQ   Вверх
Leksey
Дата 12.5.2006, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



А если нужна поддержка индексирования как в обычном массиве? 
PM MAIL   Вверх
ivashkanet
Дата 12.5.2006, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

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



Цитата(Leksey @  12.5.2006,  10:55 Найти цитируемый пост)
А если нужна поддержка индексирования как в обычном массиве? 

В сем проблема?
Сюда тоже можно добавить индексатор. 
PM MAIL WWW ICQ   Вверх
Lavitar
Дата 12.5.2006, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



arilou, 
Во-первых я спрашиал про готовый компонент, тоесть уже написанный класс. Так как заниматься велосипедами я не люблю. Ну если такого нет так и быть придется написать.
ЗЫ
HalkaR,  Твоя реализация заранее плоха так как использует два Dictionary, что не очень производительно. 
PM MAIL   Вверх
mr.DUDA
Дата 12.5.2006, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


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

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



Помнится, в STL был такой multimap. В фреймворке такой коллекции нет. Если брать по аналогии, то код типа:

Код
using System;
using System.Collections.Generic;

public class Pair<TFirst, TSecond>
{
    private TFirst _first;
    public TFirst First
    {
        get
        {
            return _first;
        }
        set
        {
            _first = value;
        }
    }

    private TSecond _second;
    public TSecond Second
    {
        get
        {
            return _second;
        }
        set
        {
            _second = value;
        }
    }


    public Pair(TFirst first, TSecond second)
    {
        _first = first;
        _second = second;
    }


    public override int GetHashCode()
    {
        int ret = 0;
        if (_first != null) ret = _first.GetHashCode();
        if (_second != null) ret ^= _second.GetHashCode();
        return ret;
    }
}

public class DoubleDictionary<TKey, TValue> : Dictionary<Pair<TKey, TValue>, Pair<TKey, TValue>>
{
    public void Add(TKey first, TValue second)
    {
        Pair<TKey, TValue> value = new Pair<TKey, TValue>(first, second);
        base.Add(value, value);
    }

    public TKey FindByValue(TValue value)
    {
        Pair<TKey, TValue> found = null;
        Pair<TKey, TValue> search = new Pair<TKey,TValue>(default(TKey), value);
        if (base.TryGetValue(search, out found))
            return found.First;
        return default(TKey);
    }

    public TValue FindByKey(TKey key)
    {
        Pair<TKey, TValue> found = null;
        Pair<TKey, TValue> search = new Pair<TKey, TValue>(key, default(TValue));
        if (base.TryGetValue(search, out found))
            return found.Second;
        return default(TValue);
    }
}

class TestApp
{
    static void Main(string[] args)
    {
        DoubleDictionary<string, string> d = new DoubleDictionary<string, string>();
        d.Add("A", "B");
        d.Add("124", "asldkfj");

        Console.WriteLine(d.FindByKey("A"));
        Console.WriteLine(d.FindByValue("B"));
    }
}


к сожалению не катит, потому что хэшкод вычисляется 1 раз и Pair с одним из элементов = null имеет хэшкод не такой, как у пары с обоими не-null элементами. Других идей в голову не приходит, возможно что вариант с двумя Dictionary, как выше, прокатит. Или на codeproject.com, там этих коллекций целая туева хуча. 


--------------------
user posted image
PM MAIL WWW   Вверх
Lavitar
Дата 12.5.2006, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



mr.DUDA, 
multimap из STL жто совсем не то. multimap это карта, в которой могут быть повторяющиеся ключи, и более от обычной карты она не чем не отличается. 
PM MAIL   Вверх
mr.DUDA
Дата 12.5.2006, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


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

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



Ну значит перепутал smile
Помню был какой-то контейнер, а как назывался - не помню. Может и не в STL smile 


--------------------
user posted image
PM MAIL WWW   Вверх
Lavitar
Дата 12.5.2006, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



mr.DUDA, 
Тогда я выложу свою реализацию, может она будет кому полезна. 
PM MAIL   Вверх
Leksey
Дата 12.5.2006, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(ivashkanet @  12.5.2006,  11:02 Найти цитируемый пост)
В сем проблема?
Сюда тоже можно добавить индексатор. 

Я думаю что для Dictionary операция индексирования не имеет смысла, а во-вторых в примере HalkaR  и так два индексатора.
А если один из типов окажеться Int то будет все не очень хорошо. 
PM MAIL   Вверх
Lavitar
Дата 13.5.2006, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вот код, который реализует DualList с возможностью индексированного доступа. Возможны реализации с более быстрым доступом по ключу, но без индексации.
Код

using System;
using System.Collections.Generic;
using System.Text;

namespace FCGLogic
{
    public class Pair<T1,T2>
    {
        private T1 t1;
        private T2 t2;

        public T1 First
        {
            get
            {
                return t1;
            }
        }

        public T2 Second
        {
            get
            {
                return t2;
            }
        }

        public Pair(T1 first,T2 second)
        {
            this.t1 = first;
            this.t2 = second;
        }
    }

    public class DualList<T1,T2> : IEnumerable< Pair<T1,T2> >
    {
        private List<T1> elemList1 = new List<T1>();
        private List<T2> elemList2 = new List<T2>();

        public DualList()
        {
        }

        public bool ContainsFirst(T1 first)
        {
            return elemList1.Contains(first);
        }

        public bool ContainsSecond(T2 second)
        {
            return elemList2.Contains(second);
        }

        public void Add(T1 first, T2 second)
        {
            elemList1.Add(first);
            elemList2.Add(second);
        }

        public void RemoveByFirst(T1 first)
        {
            int ind = elemList1.IndexOf(first);
            elemList2.RemoveAt(ind);
            elemList1.RemoveAt(ind);
        }

        public void RemoveBySecond(T2 second)
        {
            int ind = elemList2.IndexOf(second);
            elemList1.RemoveAt(ind);
            elemList2.RemoveAt(ind);
        }

        public T1 this[T2 second]
        {
            get
            {
                return elemList1[elemList2.IndexOf(second)];
            }
        }

        public T2 this[T1 first]
        {
            get
            {
                return elemList2[elemList1.IndexOf(first)];
            }
        }

        public int Count
        {
            get
            {
                return elemList1.Count;
            }
        }

        public Pair<T1,T2> At(int index)
        {
            return new Pair<T1, T2>(elemList1[index],elemList2[index]);
        }

        public int IndexOf(T1 t1)
        {
            return elemList1.IndexOf(t1);
        }


        public int IndexOf(T2 t2)
        {
            return elemList2.IndexOf(t2);
        }

        public void RemoveAt(int index)
        {
            elemList1.RemoveAt(index);
            elemList2.RemoveAt(index);
        }


        #region IEnumerable<Pair<T1,T2>> Members

        public IEnumerator<Pair<T1, T2>> GetEnumerator()
        {
            return new DualListEnumerator<T1,T2>(this);
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return new DualListEnumerator<T1, T2>(this);
        }

        #endregion
    }

    public class DualListEnumerator<T1,T2>: IEnumerator<Pair<T1,T2>>
    {
        private DualList<T1, T2> dList;
        private int position = -1;

        public DualListEnumerator(DualList<T1, T2> dList)
        {
            this.dList = dList;
        }

        #region IEnumerator<Pair<T1,T2>> Members

        public Pair<T1, T2> Current
        {
            get 
            {
                if (position < 0 || position > dList.Count - 1)
                {
                    throw new InvalidOperationException("The enumerator is positioned before the first element of the collection or after the last element.");
                }
                else
                {
                    return dList.At(position);
                }
            }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
        }

        #endregion

        #region IEnumerator Members

        object System.Collections.IEnumerator.Current
        {
            get { return Current; }
        }

        public bool MoveNext()
        {
            if ( ++position > dList.Count - 1)
            {
                return false;
            }
            return true;
        }

        public void Reset()
        {
            position = -1;
        }

        #endregion
    }
}

 
PM MAIL   Вверх
Void
Дата 13.5.2006, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

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



Lavitar, зачем вручную писать IEnumerator при наличии yield?
Код
public IEnumerator<Pair<T1, T2>> GetEnumerator()
{
    for (int i = 0; i < elemList1.Count; ++i)
        yield return new Pair<T1, T2>(elemList1[i], elemList2[i]);
}

Надеюсь, этот класс не будут использовать для хранения больших коллекций и частого доступа по ключу. O(N) однако… 


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
mr.DUDA
Дата 13.5.2006, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


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

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



Странно, что выбран List а не Dictionary. 


--------------------
user posted image
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

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


 




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


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

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