使用String索引器列出<t> BinarySearch </t>

时间:2014-09-30 17:55:23

标签: c# .net list binary-search

所以我有一个CreditCard类,它有一些属性,其中一个是卡号作为字符串(public string Number { get; set; })。我将CreditCard对象存储在具有变量List(private List<CreditCard> cclist = new List<CreditCard>();)的CreditCardList类中。我希望能够通过首先对List进行排序,然后使用List上的BinarySearch方法,通过其卡号检索CreditCard。我还想通过将数字的String索引器传递给BinarySearch方法以及比较器(如果需要的话)来做到这一点。

这是我到目前为止获得CreditCard匹配数字的方法,但Visual Studio 2013在行上给出了一个错误:int index = cclist.BinarySearch(cclist[input], new CreditCardComparer());“'System.Collections的最佳重载方法匹配。 Generic.List.this [int]'有一些无效的参数。“我认为这是因为我使用字符串索引器错误或其他。

public List<CreditCard> GetCardByNumber (string input)
{
    List<CreditCard> tempList = new List<CreditCard>();

    // save the current unsorted list to a temporary list to revert back to after sorting
    List<CreditCard> originalList = new List<CreditCard>(cclist.Capacity);

    for (int i = 0; i < cclist.Capacity; i++)
    {
        originalList[i] = cclist[i];
    }

    // begin sorting for binary search of card number
    cclist.Sort();

    int index = cclist.BinarySearch(cclist[input], new CreditCardComparer());

    if (index < 0)
    {
        tempList.Add(cclist[input]);
    }

    // revert back to the original unsorted list
    for (int i = 0; i < originalList.Capacity; i++)
    {
        cclist[i] = originalList[i];
    }

    // return the found credit card matching the specified number
    return tempList;
}// end GetCardByNumber (string input)

这是我的int和字符串索引器:

public CreditCard this[int i]
{
    get
    {
        if (i < 0 || i >= cclist.Count)
        {
            throw new ArgumentOutOfRangeException("index " + i + " does not exist");
        }

        return cclist[i];
    }
    set
    {
        if (i < 0 || i >= cclist.Count)
        {
            throw new ArgumentOutOfRangeException("index " + i + " does not exist");
        }

        cclist[i] = value;
        saveNeeded = true;
    }
}// end CreditCard this[int i]

public CreditCard this[string input]
{
    get
    {
        foreach (CreditCard cc in cclist)
        {
            if (cc.Number == input)
            {
                return cc;
            }
        }

        return null;
    }
}// end CreditCard this[string number]

这是我的比较者课程:

public class CreditCardComparer : IComparer<CreditCard>
{
    public override int Compare(CreditCard x, CreditCard y)
    {
        return x.Number.CompareTo(y.Number);
    }
}// end CreditCardComparer : IComparer<CreditCard>

最后,这是我的列表排序的必需品,而不是......

class CreditCard : IEquatable<CreditCard>, IComparable<CreditCard>
{
    public bool Equals (CreditCard other)
    {
        if (this.Number == other.Number)
        {
            return true;
        }
        else
        {
            return false;
        }
    }// end Equals(CreditCard other)

    public int CompareTo(CreditCard other)
    {
        return Number.CompareTo(other.Number);
    }// end CompareTo(CreditCard other)
}

是否真的有可能做我正在尝试的事情,即发送一个字符串索引器,它将基于字符串的CreditCard对象返回到List的BinarySearch方法中?

另外,如果有必要,我可以提供更多代码,但我觉得这有点开头。

2 个答案:

答案 0 :(得分:1)

System.Collections.Generic.List使用int作为索引器属性,它不允许您使用字符串。

如果您想使用字符串作为索引器(主键),则应该使用Dictionary<string,CreditCard>代替。

答案 1 :(得分:0)

您的GetCardByNumber方法中有一些不妥之处。首先,该方法返回整个列表而不是单个CreditCard,这与方法名称相反。其次,甚至不需要二进制搜索,因为您首先在字符串索引器中进行搜索:

public CreditCard this[string input]
{
    get
    {
        foreach (CreditCard cc in cclist)
        {
            if (cc.Number == input)
            {
                return cc;
            }
        }

        return null;
    }
}

到目前为止,您已经在CreditCard中找到了您需要的信息,那么为什么还要在BinarySearch中再次搜索它?第三,正如landoncz的回答所述,你不能使用字符串作为List<T>的索引。您可能打算使用的是CreditCardList而不是List<CreditCard>

CreditCardList creditCardList = new CreditCardList();
creditCardList["1234"]; //correct

List<CreditCard> cclist = new List<CreditCard>();
cclist["1234"]; //incorrect. This is where your error is coming from.

如果您正在尝试访问实现它的类中的索引器属性(我假设您尝试在GetCardByNumber方法中执行此操作),请使用this[index]:< / p>

public class CreditCardList
{
    public CreditCard this[string s] { /*Implementation*/ }

    public CreditCard GetCard(string s)
    {
        return this[s]; // right here!
    }
}

现在......根据你的评论,&#34; Retrieve the CreditCard with a specified number if it exists using the BinarySearch method in List<T> in the implementation of a String indexer.&#34;,在我看来,作业要求你沿着这些方向做点什么。 (需要注意的是,我不确定您的整个CreditCard类的实现,所以请原谅以下代码中的天真实例化)

public class CreditCardList
{
    private List<CreditCard> cclist = new List<CreditCard>();

    public CreditCardList()
    {
        //For the sake of an example, let's magically populate the list.
        MagicallyPopulateAList(cclist);
    }

    public CreditCard this[string s] /* In the implementation of a String indexer... */
    {
        get
        {
            CreditCard ccToSearchFor = new CreditCard() { Number = value };
            cclist.Sort();

            /* ...use the BinarySearch method... */
            int index = cclist.BinarySearch(ccToSearchFor);

            if (index >= 0)
                return cclist[index]; /* ...to retrieve a CreditCard. */
            else
                throw new ArgumentException("Credit Card Number not found.");
        }
    }
}