查找锯齿状字符串数组中的异常 (C#)

发布于 2024-11-17 23:24:30 字数 461 浏览 4 评论 0原文

我有一些数据读入锯齿状的字符串数组中。此类数组的一个示例:

string[] row = { "John", "Apple", "Orange", "Banana" };

我将有一个数组来保存这些字符串行。很长的一篇。

我想要做的是找到具有相同名称的所有行(“John”)。然后比较这些行以查看它们是否相同。如果有任何异常,则打印所有名称,否则继续下一个名称。

例如,如果我有 10 行“John”,我想检查所有 10 行的属性是否完全是“Apple”、“橙色”和“香蕉”。除了“John”之外,我还想对数千个名字执行同样的操作。

有没有一个有效的算法来做到这一点?我将用 C# 编写它。

I have some data that I read into a jagged array of strings. An example of such arrays:

string[] row = { "John", "Apple", "Orange", "Banana" };

and I will have an array to hold these rows of strings. A very long one.

What I want to do is find all the rows with the same name ("John"). Then compare these rows to see if they are identical. Print all of them if there are any exceptions, otherwise continue to next name.

So for example if I have 10 rows of "John"s, I want to check whether the attributes on all 10 of them are exactly "Apple", "Orange" and "Banana". And I will have thousands of names other than "John" that I want to do the same thing with.

Is there an efficient algorithm to do this? I will be writing it in C#.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

瀟灑尐姊 2024-11-24 23:24:30

使用 Linq,您可以执行以下操作:

var rows = new string[][]
{
    new string[] {"John", "Apple", "Orange", "Banana"},
    new string[] {"John", "Apple", "Orange", "Banana"},
    new string[] {"John", "Apple", "Lemon", "Banana"},
    new string[] {"John", "Apple", "Orange", "Grape"},
    new string[] {"Sam", "Apple", "Orange", "Banana"},
    new string[] {"Sam", "Apple", "Orange", "Banana"},
};

var results = (from f in rows
              where f.Contains("Sam")
              select f).Distinct(new ArrayComparer());

但是,这确实需要创建自定义比较器类,如下所示:

class ArrayComparer : IEqualityComparer<string[]>
{
    public bool Equals(string[] x, string[] y)
    {
        if (x.Length != y.Length)
            return false;

        var left = x.OrderBy(s => s).ToArray();
        var right = y.OrderBy(s => s).ToArray();

        for (int index = 0; index < x.Length; index++)
        {
            if (left[index] == right[index])
            {
                continue;
            }
            else
            {
                return false;
            }
        }

        return true;
    }

    public int GetHashCode(string[] obj)
    {
        int hash = 23;
        foreach (var element in obj.OrderBy(s => s))
        {
            hash = hash * 37 + element.GetHashCode();
        }

        return hash;
    }
}

使用 John 的结果将是 3 行,使用 Sam 的结果将是 2 行。如果您想忽略大小写,只需将 OrderBy(s => s) 更改为 OrderBy(s => s, StringComparer.OrdinalIgnoreCase)

Using Linq you could do the following:

var rows = new string[][]
{
    new string[] {"John", "Apple", "Orange", "Banana"},
    new string[] {"John", "Apple", "Orange", "Banana"},
    new string[] {"John", "Apple", "Lemon", "Banana"},
    new string[] {"John", "Apple", "Orange", "Grape"},
    new string[] {"Sam", "Apple", "Orange", "Banana"},
    new string[] {"Sam", "Apple", "Orange", "Banana"},
};

var results = (from f in rows
              where f.Contains("Sam")
              select f).Distinct(new ArrayComparer());

However, this does require the creation of a custom comparer class as follows:

class ArrayComparer : IEqualityComparer<string[]>
{
    public bool Equals(string[] x, string[] y)
    {
        if (x.Length != y.Length)
            return false;

        var left = x.OrderBy(s => s).ToArray();
        var right = y.OrderBy(s => s).ToArray();

        for (int index = 0; index < x.Length; index++)
        {
            if (left[index] == right[index])
            {
                continue;
            }
            else
            {
                return false;
            }
        }

        return true;
    }

    public int GetHashCode(string[] obj)
    {
        int hash = 23;
        foreach (var element in obj.OrderBy(s => s))
        {
            hash = hash * 37 + element.GetHashCode();
        }

        return hash;
    }
}

The results of using John would be 3 rows and the results with Sam would be 2 rows. If you want to ignore case you would just have to change OrderBy(s => s) to OrderBy(s => s, StringComparer.OrdinalIgnoreCase)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文