Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#匹配数组_C#_Arrays - Fatal编程技术网

C#匹配数组

C#匹配数组,c#,arrays,C#,Arrays,我有两个数组列表(数组始终包含int对): List a=新列表 { 新int[2]{0,1}, 新int[2]{5,3}, 新int[2]{1,3}, 新int[2]{5,0}, }; 列表b=新列表 { 新int[2]{0,1}, 新int[2]{5,3}, }; 我想要得到的是列表a中b列表元素的ID 有没有比循环遍历列表a、使用if语句检查数组元素以及if为true添加这些元素更好的方法 另一个问题是,如果对为0 1翻转,则条件为真。 so0;1和0;1是真的 和 0;1和1;0是

我有两个数组列表(数组始终包含int对):

List a=新列表
{ 
新int[2]{0,1},
新int[2]{5,3},
新int[2]{1,3},
新int[2]{5,0},
};
列表b=新列表
{ 
新int[2]{0,1},
新int[2]{5,3},
};
我想要得到的是列表a中b列表元素的ID

有没有比循环遍历列表a、使用if语句检查数组元素以及if为true添加这些元素更好的方法

另一个问题是,如果对为0 1翻转,则条件为真。 so0;1和0;1是真的 和
0;1和1;0是真的

从这个问题上讲,想要得到的结果有点难;然而,显然,如果每个数组(每个数组正好有两个元素)具有相同的条目,则不管序列如何,它们都被认为是相等的。这样的谓词可以用如下相当基本的方式实现

Func<int[], int[], bool> ArrayEqual = (x,y) =>
    x.Distinct().OrderBy( z => z ).SequenceEqual( y. Distinct().OrderBy( z => z ) );
var Result = a.Where( iA => b.Any( iB => ArrayEqual( iA, iB ) ) );
编辑

如果目标是将复杂性从二次时间降低到比二次时间更好的程度,我建议采用以下方法。首先,必须对所有单个数组进行排序,这可以在线性时间内完成,因为每个单个数组有2个元素(这是一个常量)。接下来,
a
b
都必须按字典顺序排序,这可以在
O(n logn)
时间内完成,同样,两个单独数组的比较可以在固定时间内完成。接下来,可以使用两个索引对任一列表进行所需的输出;在每个步骤中,都可以在恒定时间内检查两个单独的数组是否相等,这意味着接受或拒绝输出
a
的元素。在每次迭代中,可以增加两个指标中的一个;输出本身的生成可以在线性时间内完成。总的来说,这会产生一个
O(n log n)
运行时界限。

一些注释 我想要得到的是列表a中b列表元素的ID

您的问题中没有提到ID,数据示例中也没有提到。我假设您需要索引(即匹配元素在列表a中的位置)

数组始终包含一对int

我建议使用
元组
。为了便于处理,我将在代码示例中使用该元组。但我会这样做,以便您可以从初始数组开始,以最大限度地提高与代码的兼容性

另一个问题是,如果对为01翻转,则条件为true。因此,0;1和0;1为true,0;1和1;0为true

因此,解决方案是对每个元素对(而不是元素本身的列表)进行排序,以便我们匹配整数值,而不管它们的位置如何

如果需要保留数字的顺序(出于其他目的),则必须制作数字的副本(出于此匹配算法的目的),并且只对副本进行排序


实际问题 有没有比循环遍历列表a、使用if语句检查数组元素以及if为true添加这些元素更好的方法

不完全是。您必须将每个元素A与每个元素B进行匹配。
但是,如果您谈论的是大的数据集,那么您可以通过进行一些预处理(主要是条目排序等)来获得一些性能

这在某种程度上取决于你所说的“更好的方法”的意思。你是否在尝试:

  • 最大限度地提高处理大型数据集的速度
  • 提高代码的可读性
  • 缩短代码本身

根据你的关注点,你需要一种不同的方法。你的问题目前的措辞并不清楚这一点。

首先,假设我绝对不是数学专家。我只相信:D

List a=新列表
{
新int[2]{0,1},
新int[2]{5,3},
新int[2]{1,3},
新int[2]{5,0},
};
列表b=新列表
{
新int[2]{0,1},
新int[2]{5,3},
};
var aIds=新字典(a.Count);
for(int i=0;i
:

T:System.Collections.Generic.Dictionary泛型类提供从一组键到一组值的映射。字典中的每个添加项都包含一个值及其关联的键。使用其键检索值非常快,接近O(1),因为T:System.Collections.Generic.Dictionary类是作为哈希表实现的

这通常是在处理大型集合时获得巨大性能增益的一种方法

如果wikipedia说的是事实,那么应该为字典中的每一对产生一个唯一的标识符(如果顺序不重要,则为两个)。然后,我猜,你的解决方案是O(na)+O(nb)(一个循环用于散列,另一个循环用于查找交叉点)


我从中得到了这个解决方案。在线程中可能有一些很好的技巧需要学习。

你尝试过什么吗?看看linq?期望的结果是什么?欢迎使用堆栈溢出。这不是一个好的提问方式。到目前为止,你有没有尝试过解决问题的方法?首先展示你的努力,这样人们可能会展示他们的努力。p作为一个开始,请阅读。正如一条评论所说,我尝试通过数组a循环并检查它是否包含b元素。但是对于较大的循环,此操作需要时间。我认为对于这种情况,可能有内置的东西。期望的结果是数组的b.Length。因此在这种情况下->ids{0,1}L
var Result = a.Where( iA => b.Any( iB => ArrayEqual( iA, iB ) ) );
List<int[]> a = new List<int[]>
{
    new int[2] {0, 1},
    new int[2] {5, 3},
    new int[2] {1, 3},
    new int[2] {5, 0},
};

List<int[]> b = new List<int[]>
{
    new int[2] {0, 1},
    new int[2] {5, 3},
};

var aIds = new Dictionary<double, int>(a.Count);

for (int i = 0; i < a.Count; i++)
{
    var pair = a[i];

    // id for (a;b)
    var id1 = 0.5 * (pair[0] + pair[1]) * (pair[0] + pair[1] + 1) + pair[1];
    // id for (b;a)
    var id2 = 0.5 * (pair[1] + pair[0]) * (pair[1] + pair[0] + 1) + pair[0];

    aIds[id1] = i;
    aIds[id2] = i;
}

var intersection = new List<int>();

foreach (var pair in b)
{
    int id;
    if (aIds.TryGetValue(0.5 * (pair[0] + pair[1]) * (pair[0] + pair[1] + 1) + pair[1], out id))
    {
        intersection.Add(id);
    }
}