如何比较两个“数字”与多个点?

时间:2011-11-08 19:41:09

标签: c#

我有一个无序列表,看起来像这样:

1
2.2
1.1.1
3

当我对列表进行排序时,1.1.1变得大于3和2.2,而2.2变得大于3.

这是因为Double.Parse删除了点并使其成为整数。

这是我用来排序的方法:

public class CompareCategory: IComparer<Category>
{
    public int Compare(Category c1, Category c2)
    {
        Double cat1 = Double.Parse(c1.prefix);
        Double cat2 = Double.Parse(c2.prefix);

        if (cat1 > cat2)
            return 1;
        else if (cat1 < cat2)
            return -1;
        else
            return 0;
    }
}

我该如何解决这个问题? 感谢

4 个答案:

答案 0 :(得分:10)

这些版本是偶然的吗?你能用the Version class吗?它按照您的需要对每个部件进行排序,尽管它最多只能处理4个部件。我不建议像你一样解析成数值。

它有一个IComparable接口。假设您的输入是字符串,这是一个示例:

public class CompareCategory: IComparer<Category>
{
    public int Compare(Category c1, Category c2)
    {
        var cat1 = new Version(c1.prefix);
        var cat2 = new Version(c2.prefix);

        if (cat1 > cat2)
            return 1;
        else if (cat1 < cat2)
            return -1;
        else
            return 0;
    }
}

如果你需要超过4个“部分”的东西,我想我会创建一个比较器,它在点处分割字符串,然后将每个元素解析为整数并用数字进行比较。请务必考虑1.002.3和1.3.3之类的情况(您希望排序顺序是什么?)。

更新,这是我的意思的样本。经过轻微测试:

    public class CategoryComparer : Comparer<Category>
    {
        public override int Compare(Category x, Category y)
        {
            var xParts = x.prefix.Split(new[] { '.' });
            var yParts = y.prefix.Split(new[] { '.' });

            int index = 0;
            while (true)
            {
                bool xHasValue = xParts.Length > index;
                bool yHasValue = yParts.Length > index;
                if (xHasValue && !yHasValue)
                    return 1;   // x bigger
                if (!xHasValue && yHasValue)
                    return -1;  // y bigger
                if (!xHasValue && !yHasValue)
                    return 0;   // no more values -- same
                var xValue = decimal.Parse("." + xParts[index]);
                var yValue = decimal.Parse("." + yParts[index]);
                if (xValue > yValue)
                    return 1;   // x bigger
                if (xValue < yValue)
                    return -1;  // y bigger
                index++;
            }
        }
    }
    public static void Main()
    {
        var categories = new List<Category>()
        {
            new Category { prefix = "1" },
            new Category { prefix = "2.2" },
            new Category { prefix = "1.1.1" },
            new Category { prefix = "1.1.1" },
            new Category { prefix = "1.001.1" },
            new Category { prefix = "3" },
        };

        categories.Sort(new CategoryComparer());
        foreach (var category in categories)
            Console.WriteLine(category.prefix);
    }

输出:

1
1.001.1
1.1.1
1.1.1
2.2
3

答案 1 :(得分:1)

public class CodeComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        var xParts = x.Split(new char[] { '.' });
        var yParts = y.Split(new char[] { '.' });
        var partsLength = Math.Max(xParts.Length, yParts.Length);
        if (partsLength > 0)
        {
            for (var i = 0; i < partsLength; i++)
            {
                if (xParts.Length <= i) return -1;// 4.2 < 4.2.x
                if (yParts.Length <= i) return 1;

                var xPart = xParts[i];
                var yPart = yParts[i];

                if (string.IsNullOrEmpty(xPart)) xPart = "0";// 5..2->5.0.2
                if (string.IsNullOrEmpty(yPart)) yPart = "0";

                if (!int.TryParse(xPart, out var xInt) || !int.TryParse(yPart, out var yInt))
                {
                    // 3.a.45 compare part as string
                    var abcCompare = xPart.CompareTo(yPart);
                    if (abcCompare != 0)
                        return abcCompare;
                    continue;
                }

                if (xInt != yInt) return xInt < yInt ? -1 : 1;
            }
            return 0;
        }
        // compare as string
        return x.CompareTo(y);
    }
}

答案 2 :(得分:0)

也许你可以对它进行字符串比较?

答案 3 :(得分:0)

我很惊讶Double.Parse不会对那些小数位多的数字抛出异常。

你真的需要写一些关于如何比较这些字符串的规则。

我会在点字符上使用String.Split()拆分字符串,然后遍历创建的两个列表,并且只要其中一个级别包含比另一个更低或更高的数字,或者如果你用完了其中一个列表中的项目然后您将根据需要返回1或-1。如果你在循环的同一次迭代中到达两个列表的末尾,那么它们是相同的并返回0.

我会写代码,但我没有VS在我面前。