문제

또 다른 질문의 결과로 여기서 물었습니다. 내 개체에 해시를 사용하고 싶습니다.

문자열이 포함 된 객체와 소유자에 대한 참조를 만들 것입니다.

public class Synonym
{
   private string name;
   private Stock owner;
   public Stock(string NameSynonym, Stock stock)
   {
       name=NameSynonym;
       owner=stock
   }
   // [+ 'get' for 'name' and 'owner']
}

비교가 필요하다는 것을 이해하지만 전에는 사용하지 않았습니다. 별도의 클래스를 만들어야합니까? 처럼:

public class SynonymComparer : IComparer<Synonym>
{
   public int Compare(Synonym One, Synonym Two)
   { // Should I test if 'One == null'  or  'Two == null'  ???? 
       return String.Compare(One.Name, Two.Name, true); // Caseinsesitive
   }

}

나는 다른 (독립) 클래스 대신 클래스 동의어의 일부인 함수 (또는 필요한 경우 중첩 클래스 [싱글 톤?])를 선호합니다. 이게 가능해?

사용법에 대해 : 이런 종류의 것을 사용한 적이 없으므로 클래스 동의어 내에 찾은 (문자열 이름 synononic) 기능을 작성해야한다고 가정하지만 어떻게해야합니까?

public class SynonymManager
{ 
    private HashSet<SynonymComparer<Synonym>> ListOfSynonyms;

    public SynonymManager()
    {
        ListOfSymnonyms = new HashSet<SynonymComparer<Synonym>>();
    }

    public void SomeFunction()
    { // Just a function to add 2 sysnonyms to 1 stock
        Stock stock = GetStock("General Motors");
        Synonym otherName = new Synonym("GM", stock);
        ListOfSynonyms.Add(otherName);
        Synonym otherName = new Synonym("Gen. Motors", stock);
        ListOfSynonyms.Add(otherName);
    }

    public Synonym Find(string NameSynomym)
    {
       return ListOfSynonyms.??????(NameSynonym);
    }
 }

위의 코드에서는 '찾기'메소드를 구현하는 방법을 모르겠습니다. 어떻게해야하나요?

모든 도움이 감사하겠습니다 (PS가 구현 방법에 대한 내 아이디어가 완전히 잘못된 경우 PS는 저에게 알려 주시고 구현 방법을 알려주세요)

도움이 되었습니까?

해결책

해시 세트는 필요하지 않습니다 IComparer<T> - 필요합니다 IEqualityComparer<T>, 와 같은

public class SynonymComparer : IEqualityComparer<Synonym>      
{
   public bool Equals(Synonym one, Synonym two)
   {
        // Adjust according to requirements.
        return StringComparer.InvariantCultureIgnoreCase
                             .Equals(one.Name, two.Name);

   }

   public int GetHashCode(Synonym item)
   {
        return StringComparer.InvariantCultureIgnoreCase
                             .GetHashCode(item.Name);

   }
}

그러나 현재 코드는 세트를 생성하기 때문에 컴파일됩니다. 비교 세트보다는 동의어.

또한, 나는 당신이 정말로 세트를 원한다고 생각하지 않습니다. 주어진 이름의 동의어를 찾을 수 있도록 사전이나 조회를 원한 것 같습니다.

public class SynonymManager
{ 
    private readonly IDictionary<string, Synonym> synonyms = new
        Dictionary<string, Synonym>();

    private void Add(Synonym synonym)
    {
        // This will overwrite any existing synonym with the same name.
        synonyms[synonym.Name] = synonym;
    }

    public void SomeFunction()
    { 
        // Just a function to add 2 synonyms to 1 stock.
        Stock stock = GetStock("General Motors");
        Synonym otherName = new Synonym("GM", stock);
        Add(otherName);
        ListOfSynonyms.Add(otherName);
        otherName = new Synonym("Gen. Motors", stock);
        Add(otherName);
    }

    public Synonym Find(string nameSynonym)
    {
       // This will throw an exception if you don't have
       // a synonym of the right name.  Do you want that?
       return synonyms[nameSynonym];
    }
}

위의 코드에는 다양한 경우에 어떻게 행동하기를 원하는지에 대한 몇 가지 질문이 있습니다. 운동해야합니다 바로 그거죠 당신이 원하는 것.

편집 : 단일 동의어를 위해 여러 주식을 저장하려면 효과적으로 ~을 원한다 Lookup<string, Stock> - 그러나 그것은 불변입니다. 당신은 아마도 가장 잘 보관하는 것입니다 Dictionary<string, List<Stock>>; 각 문자열에 대한 주식 목록.

오류를 던지지 않는 관점에서 Find, 당신은 봐야합니다 Dictionary.TryGetValue 키를 찾지 못한 경우 예외가 발생하지 않습니다 (및 키가 반환됩니다. ~였다 설립하다); 매핑 된 값은 OUT 매개 변수에서 "리턴"됩니다.

다른 팁

스크랩하는 것이 더 합리적이지 않을 것입니다 Synonym 전적으로 수업을하고 동의어 목록이 Dictonary (또는 그런 것이 있다면 HashDictionary) 문자열?

(나는 C# 유형에 익숙하지 않지만 이것이 일반적인 아이디어를 전달하기를 바랍니다)

내가 추천하는 대답 (편집, 이제 사건을 존중) :

    IDictionary<string, Stock>>  ListOfSynonyms = new Dictionary<string,Stock>>(); 
    IDictionary<string, string>> ListOfSynForms = new Dictionary<string,string>>(); 
    class Stock 
    {   
        ...
        Stock addSynonym(String syn) 
        {
            ListOfSynForms[syn.ToUpper()] = syn;
            return ListOfSynonyms[syn.ToUpper()] = this;
        }
        Array findSynonyms()
        {
            return ListOfSynonyms.findKeysFromValue(this).map(x => ListOfSynForms[x]);
        }
    }

    ...
    GetStock("General Motors").addSynonym('GM').addSynonym('Gen. Motors');
    ...
    try  
    {
        ... ListOfSynonyms[synonym].name ...
    }  
    catch (OutOfBounds e) 
    {
        ...
    } 
    ...
    // output everything that is synonymous to GM. This is mix of C# and Python
    ... GetStock('General Motors').findSynonyms()
    // test if there is a synonym
    if (input in ListOfSynonyms) 
    {
        ...
    }

언제든지 LINQ를 사용하여 조회를 수행 할 수 있습니다.

public Synonym Find(string NameSynomym)
{
   return ListOfSynonyms.SingleOrDefault(x => x.Name == NameSynomym);
}

그러나 대신 사전 사용을 고려해 보셨습니까? 단일 멤버를 추출하는 데 더 적합하다고 생각하며, 선택한 키를 기반으로 한 중복이 없음을 보장 할 수 있습니다.

조회 시간이 SingleordeFault인지 확신하지는 않지만 선형 (O (N))인지 확신합니다. 따라서 조회 시간이 중요하면 사전이 O (1) 조회 시간을 제공합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top