Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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#_Sorting - Fatal编程技术网

C# 将两个列表合并为一个列表并对项目进行排序

C# 将两个列表合并为一个列表并对项目进行排序,c#,sorting,C#,Sorting,是否有一种方法可以将两个给定的列表合并(无重复的联合)为一个列表,并使用一个for循环以排序方式存储项目 另外,我正在寻找一种不使用API方法(如union、sort等)的解决方案 示例代码 private static void MergeAndOrder() { var listOne = new List<int> {3, 4, 1, 2, 7, 6, 9, 11}; var listTwo = new List<int> {1, 7, 8, 3, 5, 10,

是否有一种方法可以将两个给定的列表合并(无重复的联合)为一个列表,并使用一个for循环以排序方式存储项目

另外,我正在寻找一种不使用API方法(如union、sort等)的解决方案

示例代码

private static void MergeAndOrder() 
{
var listOne = new List<int> {3, 4, 1, 2, 7, 6, 9, 11}; 
var listTwo = new List<int> {1, 7, 8, 3, 5, 10, 15, 12}; 

//Without Using C# helper methods...
//ToDo.............................

//Using C# APi.
var expectedResult = listOne.Union(listTwo).ToList(); 
expectedResult.Sort();//Output: 1,2,3,4,5,6,7,8,9,10,11,12,15
//I need the same result without using API methods, and that too by iterating over items only once.


}
private静态无效合并器()
{
var listOne=新列表{3,4,1,2,7,6,9,11};
var listwo=新列表{1,7,8,3,5,10,15,12};
//如果不使用C#helper方法。。。
//待办事项。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
//使用C#APi。
var expectedResult=listOne.Union(listwo.ToList();
expectedResult.Sort();//输出:1,2,3,4,5,6,7,8,9,10,11,12,15
//我需要在不使用API方法的情况下得到相同的结果,并且只对项目迭代一次。
}

PS:我在一次采访中被问到这个问题,但还没有找到答案。

你可以编写一个循环,合并和重复列表,并使用二进制搜索方法将新值插入目标列表。

为什么不能使用api方法?重新发明轮子是愚蠢的。而且,是
.ToList()
调用让你心烦意乱。永远不要调用
.ToList()
.ToArray()
,除非你必须这样做,因为它们会破坏你的惰性评估

按此操作,您将列出所需最低金额的列表:

var expectedResult = listOne.Union(listTwo).OrderBy(i => i);
这将使用哈希集在一个循环中完成联合,而延迟执行意味着排序的基本过程将在联合上进行。但是我认为不可能在一次迭代中完成排序,因为排序不是一个O(n)操作;
var listOne = new List<int> { 3, 4, 1, 2, 7, 6, 9, 11 };
var listTwo = new List<int> { 1, 7, 8, 3, 5, 10, 15, 12 };
var result = listOne.ToList();

foreach (var n in listTwo)
{
  if (result.IndexOf(n) == -1)
    result.Add(n);
}
var listwo=新列表{1,7,8,3,5,10,15,12}; var result=listOne.ToList(); foreach(列表2中的变量n) { 如果(结果IndexOf(n)=-1) 结果:添加(n); }
如果没有在合并+排序操作之前对两个列表进行排序的先决条件,则无法在O(n)时间内完成此操作(或“使用一个循环”)

加上这个前提条件,问题就很简单了

保留两个迭代器,每个列表一个迭代器。在每个循环中,比较每个列表中的元素并选择较小的元素。递增该列表的迭代器。如果要在最终列表中插入的元素已经是该列表中的最后一个元素,请跳过插入

在伪代码中:

List a = { 1, 3, 5, 7, 9 }
List b = { 2, 4, 6, 8, 10 }
List result = { }
int i=0, j=0, lastIndex=0
while(i < a.length || j < b.length)
    // If we're done with a, just gobble up b (but don't add duplicates)
    if(i >= a.length)
        if(result[lastIndex] != b[j])
            result[++lastIndex] = b[j]
        j++
        continue

    // If we're done with b, just gobble up a (but don't add duplicates)
    if(j >= b.length)
        if(result[lastIndex] != a[i])
            result[++lastIndex] = a[i]
        i++
        continue

    int smallestVal

    // Choose the smaller of a or b
    if(a[i] < b[j])
        smallestVal = a[i++]
    else
        smallestVal = b[j++]

    // Don't insert duplicates
    if(result[lastIndex] != smallestVal)
        result[++lastIndex] = smallestVal
end while
列表a={1,3,5,7,9}
列表b={2,4,6,8,10}
列表结果={}
int i=0,j=0,lastIndex=0
而(i=a.length)
如果(结果[lastIndex]!=b[j])
结果[++lastIndex]=b[j]
j++
持续
//如果我们完成了b,只需吞下a(但不要添加重复项)
如果(j>=b.长度)
如果(结果[lastIndex]!=a[i])
结果[++lastIndex]=a[i]
我++
持续
int smallestVal
//选择a或b中较小的一个
if(a[i]
我看到的最接近的解决方案是,在知道整数有界的情况下,将数组分配给某个值

int[] values = new int[ Integer.MAX ]; // initialize with 0
int size1 = list1.size();
int size2 = list2.size();

for( int pos = 0; pos < size1 + size2 ; pos++ )
{
     int val =  pos > size1 ? list2[ pos-size1 ] : list1[ pos ] ;
     values[ val ]++;
}
int[]值=新的int[Integer.MAX];//用0初始化
int size1=list1.size();
int size2=list2.size();
对于(int pos=0;possize1?列表2[pos-size1]:列表1[pos];
值[val]++;
}

然后你可以说你有一个“特殊”形式的排序数组:-)为了得到一个干净的排序数组,你需要遍历
数组,用
0
count跳过所有位置,然后构建最终的列表。

这只适用于整数列表,但幸运的是这就是你拥有的

List<int> sortedList = new List<int>();
foreach (int x in listOne)
{
    sortedList<x> = x;
}
foreach (int x in listTwo)
{
    sortedList<x> = x;
}
List sortedList=new List();
foreach(列表一中的int x)
{
分类列表=x;
}
foreach(列表2中的int x)
{
分类列表=x;
}
这是使用每个列表中的值作为存储值的索引位置。任何重复的值都将覆盖该索引位置的上一个条目。它只满足对值进行一次迭代的要求

当然,这意味着列表中将有“空”位置

我怀疑这个职位现在已经有人了,不过…-)

private static void mergetwortosterdarray(int[]第一,int[]第二)
{
//抛出新的NotImplementedException();
int[]结果=新int[first.Length+second.Length];
int i=0,j=0,k=0;

虽然(i 类合并分类列表 { 静态void Main(字符串[]参数){

var list1=新列表(){
1,3,5,9,11
};
var list2=新列表(){
2,5,6,11,15,17,19,29
};
foreach(SortedAndMerged(list1.GetEnumerator(),list2.GetEnumerator())中的变量c){
控制台。写入(c+“”);
}
Console.ReadKey();
}
私有静态IEnumerable(IEnumerator e1、IEnumerator e2){
e2.MoveNext();
e1.MoveNext();
做{
而(e1.电流
试试这个:

      public static IEnumerable<T> MergeWith<T>(IEnumerable<T> collection1, IEnumerable<T> collection2,
            IComparer<T> comparer)
        {
            using (var enumerator1 = collection1.GetEnumerator())
            using (var enumerator2 = collection2.GetEnumerator())
            {
                var isMoveNext1 = enumerator1.MoveNext();
                var isMoveNext2 = enumerator2.MoveNext();

                do
                {
                    while (comparer.Compare(enumerator1.Current, enumerator2.Current) < 0 || !isMoveNext2)
                    {
                        if (isMoveNext1)
                            yield return enumerator1.Current;
                        else
                            break;

                        isMoveNext1 = enumerator1.MoveNext();
                    }

                    if (isMoveNext2)
                        yield return enumerator2.Current;

                    isMoveNext2 = enumerator2.MoveNext();
                } while (isMoveNext1 || isMoveNext2);
            }
        }
公共静态IEnumerable合并(IEnumerable collection1、IEnumerable collection2、,
IComparer(比较器)
{
使用(var enumerator1=collection1.GetEnumerator())
使用(var enumerator2=collection2.GetEnumerator())
{
var isMoveNext1=enumerator1.MoveNext();
        var list1 = new List<int?>() {
            1,3,5,9,11
        };

        var list2 = new List<int?>() {
            2,5,6,11,15,17,19,29
        };

        foreach (var c in SortedAndMerged(list1.GetEnumerator(), list2.GetEnumerator())) {
            Console.Write(c+" ");
        }

        Console.ReadKey();
    }

    private static IEnumerable<int> SortedAndMerged(IEnumerator<int?> e1, IEnumerator<int?> e2) {
        e2.MoveNext();
        e1.MoveNext();

        do {
            while (e1.Current < e2.Current) {
                if (e1.Current != null) yield return e1.Current.Value;
                e1.MoveNext();
            }

            if (e2.Current != null) yield return e2.Current.Value;
            e2.MoveNext();
        } while (!(e1.Current == null && e2.Current == null));
    }
}
      public static IEnumerable<T> MergeWith<T>(IEnumerable<T> collection1, IEnumerable<T> collection2,
            IComparer<T> comparer)
        {
            using (var enumerator1 = collection1.GetEnumerator())
            using (var enumerator2 = collection2.GetEnumerator())
            {
                var isMoveNext1 = enumerator1.MoveNext();
                var isMoveNext2 = enumerator2.MoveNext();

                do
                {
                    while (comparer.Compare(enumerator1.Current, enumerator2.Current) < 0 || !isMoveNext2)
                    {
                        if (isMoveNext1)
                            yield return enumerator1.Current;
                        else
                            break;

                        isMoveNext1 = enumerator1.MoveNext();
                    }

                    if (isMoveNext2)
                        yield return enumerator2.Current;

                    isMoveNext2 = enumerator2.MoveNext();
                } while (isMoveNext1 || isMoveNext2);
            }
        }