私は以下のように2つのソートされたリストを持っています:
var list1 = new List<int>() { 1, 1, 1, 2, 3 };
var list2 = new List<int>() { 1, 1, 2, 2, 4 };
出力を次のようにします。{1, 1, 2}
C#でこれを行う方法は?Linqを使用する方法はありますか?
使用Intersect
:
var commonElements = list1.Intersect(list2).ToList();
Intersect
余分な1は、セットを返すため 使用できないことを意味します。
必要なことを実行するコードは次のとおりです。
var list1 = new List<int>() { 1, 1, 1, 2, 3 };
var list2 = new List<int>() { 1, 1, 2, 2, 4 };
var grouped1 =
from n in list1
group n by n
into g
select new {g.Key, Count = g.Count()};
var grouped2 =
from n in list2
group n by n
into g
select new {g.Key, Count = g.Count()};
var joined =
from b in grouped2
join a in grouped1 on b.Key equals a.Key
select new {b.Key, Count = Math.Min(b.Count, a.Count)};
var result = joined.SelectMany(a => Enumerable.Repeat(a.Key, a.Count));
CollectionAssert.AreEquivalent(new[] {1, 1, 2}, result);
これはうまく機能します:
var list1 = new List<int>() { 1, 1, 1, 2, 3 };
var list2 = new List<int>() { 1, 1, 2, 2, 4 };
var lookup1 = list1.ToLookup(x => x);
var lookup2 = list2.ToLookup(x => x);
var results = lookup1.SelectMany(l1s => lookup2[l1s.Key].Zip(l1s, (l2, l1) => l1));
@Austin Salonenのソリューションと@Enigmativityのソリューションはどちらも特定のリストに対して機能しますが、どちらもリストがソートされているというOPの条件を利用していません。
両方のリストが順序付けられることを考えるとO(n + m)
、nとmが各リストの長さである時間内に検索を実行できます。以前のソリューションのパフォーマンスが大きいかどうかは完全にはわかりませんが、それよりも明らかに遅くなりO(n + m)
ます。
基本的には、両方のリストをたどり、比較チェックに基づいて一方または両方の列挙子を移動します。
var results = new List<int>();
var e1 = list1.GetEnumerator();
var e2 = list2.GetEnumerator();
var hasNext = e1.MoveNext() && e2.MoveNext();
while (hasNext) {
var value1 = e1.Current;
var value2 = e2.Current;
if (value1 == value2) {
results.Add(value1);
hasNext = e1.MoveNext() && e2.MoveNext();
} else if (value1 < value2) {
hasNext = e1.MoveNext();
} else if (value1 > value2) {
hasNext = e2.MoveNext();
}
}
それでおしまい!results
一致するものが見つからない場合は、空のリストになります。これは、両方のリストが昇順であることを前提としていることに注意してください。降順の場合は、<
and>
演算子を反転するだけです。
私はこの質問に答えるのが遅れています、これは将来の訪問者を助けるかもしれません。
List<int> p = new List<int> { 1, 1, 1, 2, 3 };
List<int> q = new List<int> { 1, 1, 2, 2, 4 };
List<int> x = new List<int>();
for (int i = 0; i < p.Count; i++ )
{
if (p[i] == q[i])
{
x.Add(p[i]);
}
}