2

2 つのリストがあります。

List<int> list2 = new List<int>(new[] { 1, 2, 3, 5, 6 }); // missing: 0 and 4
List<int> list1 = new List<int>(new[] { 0, 1, 2, 3, 4, 5, 6 });

2 つのリストを比較し、List1 で欠落している数字を見つけて、これらの数字を List1 から削除するにはどうすればよいですか? より正確には、比較のために開始位置と終了位置を指定する方法を見つける必要があります。

プロセスはこれに非常に似ているはずだと思います:

ステップ1。

int start_num = 3; // we know that comparisons starts at number 3
int start = list2.IndexOf(start_num); // we get index of Number (3)
int end = start + 2; // get ending position
int end_num = list2[end]; // get ending number (6)

これで、List2 (3,5,6) で比較するための数値 (および数値自体) の位置が得られました。

ステップ 2.比較のために List1 内の数値の位置を取得するには、次のようにします。

int startlist1 = list1.IndexOf(start_num); // starting position
int endlist1 = list1.IndexOf(end_num); // ending position

範囲は次のとおりです: (3,4,5,6)

ステップ 3. 比較。トリッキーな部分はここから始まり、助けが必要です

基本的に、(3,5,6) の list2 と (3,4,5,6) の list1 を比較する必要があります。欠番は「4」です。

// I have troubles with this step but the result will be:

int remove_it = 4; // or int []

ステップ 4. 奇数の除去。

int remove_it = 4;
list1 = list1.Where(a => a != remove_it).ToList();

うまくいきますが、欠落した数字が 2 つある場合はどうなるでしょうか? すなわち

int remove_it = 4 // becomes int[] remove_it = {4, 0}

結果ご想像のとおり、結果は新しい List1 で、番号 4 は含まれていません。

richTextBox1.Text = "" + string.Join(",", list1.ToArray()); // output: 0,1,2,3,5,6

textBox1.Text = "" + start + " " + start_num; // output: 2 3
textBox3.Text = "" + end + " " + end_num; // output: 4 6

textBox2.Text = "" + startlist1; // output: 3
textBox4.Text = "" + endlist1; // output: 6

ステップ3で私を助けてくれますか、それとも正しい方向に向けてくれますか?

また、開始番号(start_num)が最後の番号である場合にどうなるか教えていただけますか?次の 2 つの番号を取得する必要がありますか? 上記の例では、数値は3,5,6でしたが、 5,6,0または6,0,1または0,1,2と変わらないはずです。

4

10 に答える 10

3

最初の部分に答えるだけです:

 var list3 = list1.Intersect(list2);

これはに設定さlist3れます{ 0, 1, 2, 3, 4, 5, 6 } - { 0, 4 } = { 1, 2, 3, 5, 6 }

そしてステップ1への反応 :

int start_num = 3; //比較は3番から始まることがわかってい
ますintstart= list2.IndexOf(start_num); // Number(3)のインデックスを取得します
int end = start + 2; //終了位置を取得します

これらすべてのマジックナンバー(3、+ 2)はどこから入手できますか?

あなたはこれをたくさん考えすぎていると思います。

于 2012-04-10T13:26:35.097 に答える
1
var result = list1.Intersect(list2)

.ToList結果をリストにする必要がある場合は、最後にを追加できます。

于 2012-04-10T13:26:34.787 に答える
1
        List<int> list2 = new List<int>(new[] { 1, 2, 3, 5, 6 }); // missing: 0 and 4 
        List<int> list1 = new List<int>(new[] { 0, 1, 2, 3, 4, 5, 6 });

        // find items in list 2 notin 1
        var exceptions = list1.Except(list2);

        // or are you really wanting to do a union? (unique numbers in both arrays)
        var uniquenumberlist = list1.Union(list2);

        // or are you wanting to find common numbers in both arrays
        var commonnumberslist = list1.Intersect(list2);
于 2012-04-10T13:38:43.733 に答える
0

リストの代わりに OrderedList を使用する必要があるかもしれません...

于 2012-04-10T13:27:11.060 に答える
0

わかりました、問題を十分に説明していないようです。申し訳ありません。興味のある人は、このコードを見れば、私が何を意味したかを理解できます。

        List<int> list2 = new List<int>() { 1, 2, 3, 5, 6 }; // missing: 0 and 4
        List<int> list1 = new List<int>() { 0, 1, 2, 3, 4, 5, 6 };

        int number = 3; // starting position

        int indexer = list2.BinarySearch(number);
        if (indexer < 0)
        {
            list2.Insert(~index, number); // don't look at this part
        }

        // get indexes of "starting position"
        int index1 = list1.Select((item, i) => new { Item = item, Index = i }).First(x => x.Item == number).Index;
        int index2 = list2.Select((item, i) => new { Item = item, Index = i }).First(x => x.Item == number).Index;

        // reorder lists starting at "starting position"
        List<int> reorderedList1 = list1.Skip(index1).Concat(list1.Take(index1)).ToList(); //main big
        List<int> reorderedList2 = list2.Skip(index2).Concat(list2.Take(index2)).ToList(); // main small


        int end = 2; // get ending position: 2 numbers to the right
        int end_num = reorderedList2[end]; // get ending number

        int endlist1 = reorderedList1.IndexOf(end_num); // ending position

        //get lists for comparison
        reorderedList2 = reorderedList2.Take(end + 1).ToList();
        reorderedList1 = reorderedList1.Take(endlist1 + 1).ToList();

        //compare lists
        var list3 = reorderedList1.Except(reorderedList2).ToList();
        if (list3.Count != 0)
        {
            foreach (int item in list3)
            {
                list1 = list1.Where(x => x != item).ToList(); // remove from list
            }
        }
        // list1 is the result that I wanted to see

このコードを最適化する方法があれば教えてください。乾杯。

于 2012-04-10T20:11:07.650 に答える
0

このようなもの:

list1.RemoveAll(l=> !list2.Contains(l));
于 2012-04-10T13:29:36.300 に答える
0

および とIntersect組み合わせて使用​​すると、交差ロジックを範囲と組み合わせて取得できます (ここでは、スキップするため、0 が欠落しているという事実を無視します)。SkipTake

static void Main(string[] args)
{
    var list1 = new List<int> { 1, 2, 3, 4, 5 };
    var list2 = new List<int> { 0, 1, 2, 3, 5, 6 };

    foreach (var i in list2.Skip(3).Take(3).Intersect(list1))
        Console.WriteLine(i); // Outputs 3 then 5.

    Console.Read();
}

正直に言うと、何を聞かれているのかわかりません。唯一確かなのは交差部分です。

var list1 = new List<int> { 1, 2, 3, 4, 5 };
var list2 = new List<int> { 0, 1, 2, 3, 5, 6 };

foreach (var i in list2.Intersect(list1))
    Console.WriteLine(i); // Outputs 1, 2, 3, 5.
于 2012-04-10T13:30:37.107 に答える
0

list1に存在するが存在しない番号を取得するには、次の拡張メソッドlist2を使用します。Except

IEnumerable<int> missing = list1.Except(list2);

この結果をループして から削除するにはlist1、結果を認識する必要があります。そうしないと、変更中にリストから読み取られ、例外が発生します。

List<int> missing = list1.Except(list2).ToList();

これで、それらを削除できます:

foreach (int number in missing) {
  list1.Remove(number);
}
于 2012-04-10T13:31:46.403 に答える
0

私はあなたの問題を理解しているかどうか確信が持てません.私があなたに与える解決策があなたにとって良いことを願っています.

2 つのリストがあります:

List list2 = new List(new[] { 1, 2, 3, 5, 6 }); // 行方不明: 0 と 4 List list1 = new List(new[] { 0, 1, 2, 3, 4, 5, 6 });

list1 から list2 の欠落しているすべての番号を削除するには、次の解決策をお勧めします: 欠落している番号を含む新しいリストを作成します。

List diff = new List();

次に、削除する必要があるすべての番号をこのリストに入れます。これで、削除プロセスは簡単になりました。diff に追加したすべての要素を取り、list2 から削除するだけです。

于 2012-04-10T13:32:39.053 に答える
0

アルゴリズムは次のとおりであることを正しく理解しましたか? list2.?

于 2012-04-10T13:37:06.667 に答える