将 2 个排序的整数列表合并为一个,按升序排列。我的方法太乱了
merging 2 sorted integer list into one ,in ascending order. my method is getting too messy
static List<int>Merge(List<int> list_a, List<int> list_b)
{
List<int> list_c=new List<int>();
int countA = 0, countB = 0;
for (int i =0;i< list_a.Count + list_b.Count-2;i++)
{
if (list_a[countA]<=list_b[countB])
{
list_c.Add(list_a[countA]);
countA ++;
}
else
{
list_c.Add(list_b[countB]);
countB ++;
}
}
return list_c;
}
我的想法是通过 for 循环的次数与最后 list_c 元素的数量一样多
比较两个列表中的每个元素,然后添加 list_c 中的最小元素
我已经有办法检查两个列表是否按升序排列
当我用
测试它时
List<int> myList1 = new List<int> { 1, 2, 3, 7, 8, 9 };
List<int> myList2 = new List<int> { 4, 5, 6};
Console.WriteLine("new list :{ " + string.Join(",", Merge(myList1, myList2)));
countB 一旦添加了列表 b 中的最后一个元素,就会越界,该 for 循环中的下一个比较将无效,因为它比较 list_b[3]
考虑到您要使用循环:
public static List<int> Merge(List<int> list_a, List<int> list_b)
{
int firstListIndexer = 0, secondListIndexer = 0;
List<int> list_c = new List<int>();
// Traverse lists, until one of them run out of the elements
while (firstListIndexer < list_a.Count && secondListIndexer < list_b.Count)
{
if (list_a[firstListIndexer] < list_b[secondListIndexer])
list_c.Add(list_a[firstListIndexer++]);
else
list_c.Add(list_b[secondListIndexer++]);
}
// Store remaining elements of first list
while (firstListIndexer < list_a.Count)
list_c.Add(list_a[firstListIndexer++]);
// Store remaining elements of second list
while (secondListIndexer < list_b.Count)
list_c.Add(list_b[secondListIndexer++]);
return list_c;
}
此外,您还可以阅读 this 以提高您对该主题的了解。
您在较短数组上的索引超出了其最大索引。需要检查Count
是否超过最大索引。
class Program {
static List<int> Merge(List<int> list_a, List<int> list_b) {
List<int> list_c = new List<int>();
int countA = 0, countB = 0;
for (int i = 0; i < list_a.Count + list_b.Count; i++) {
if (countA < list_a.Count && countB < list_b.Count) {
if (list_a[countA] <= list_b[countB]) {
list_c.Add(list_a[countA]);
countA++;
}
else {
list_c.Add(list_b[countB]);
countB++;
}
}
else if (countA < list_a.Count) {
list_c.Add(list_a[countA]);
countA++;
}
else {
list_c.Add(list_b[countB]);
countB++;
}
}
return list_c;
}
static void Main(string[] args) {
List<int> myList1 = new List<int> { 1, 2, 3, 7, 8, 9 };
List<int> myList2 = new List<int> { 4, 5, 6 };
Console.WriteLine("new list :{ " + string.Join(",", Merge(myList1, myList2)) + "}");
}
}
如果我们可以假设两个列表都是按升序排列的,那么您可以像这样合并集合以遵守升序。
static List<int> MergeTowAscendinglyOrderedCollections(IEnumerable<int> collectionA, IEnumerable<int> collectionB)
{
var result = new List<int>();
IEnumerator<int> iteratorA = collectionA.GetEnumerator();
IEnumerator<int> iteratorB = collectionB.GetEnumerator();
bool doesIteratorAHaveRemainingItem = iteratorA.MoveNext();
bool doesIteratorBHaveRemainingItem = iteratorB.MoveNext();
void SaveIteratorAsCurrentAndAdvanceIt()
{
result.Add(iteratorA.Current);
doesIteratorAHaveRemainingItem = iteratorA.MoveNext();
}
void SaveIteratorBsCurrentAndAdvanceIt()
{
result.Add(iteratorB.Current);
doesIteratorBHaveRemainingItem = iteratorB.MoveNext();
}
do
{
if (iteratorA.Current < iteratorB.Current)
{
if (doesIteratorAHaveRemainingItem) SaveIteratorAsCurrentAndAdvanceIt();
else SaveIteratorBsCurrentAndAdvanceIt();
}
else if (iteratorA.Current > iteratorB.Current)
{
if (doesIteratorBHaveRemainingItem) SaveIteratorBsCurrentAndAdvanceIt();
else SaveIteratorAsCurrentAndAdvanceIt();
}
else if (iteratorA.Current == iteratorB.Current)
{
SaveIteratorAsCurrentAndAdvanceIt();
SaveIteratorBsCurrentAndAdvanceIt();
}
} while (doesIteratorAHaveRemainingItem || doesIteratorBHaveRemainingItem);
return result;
}
为了防止重复,我已将两个数字都添加到合并列表中,但根据您的业务需求,您可以调整代码以从结果中省略一个或两个值。
你可以做一个联盟
List<int> myList1 = new List<int> { 1, 2, 3, 7, 8, 9 };
List<int> myList2 = new List<int> { 4, 5, 6};
var merged = myList1.Union(myList2).OrderBy(o=>o).ToList();
foreach(int number in merged)
Console.WriteLine(number);
输出如下
1
2个
3个
4个
5个
6个
7
8个
9
如果你必须实现你的 serlf:
使用协程在短短几行中实现没有计数器和索引:
class Program {
static void Main() {
List<int> l1 = new List<int>() { 9,8, 7, 5, 3, 1 };
List<int> l2 = new List<int>() {12 ,10, 8, 6, 4, 2 };
IEnumerable<int> res = MergeAscending(sl1, sl2);
foreach (int item in res) {
Console.Write($"{item},");
}
Console.Read();
}
static IEnumerable<T> MergeAscending<T>(IEnumerable<T> l1, IEnumerable<T> l2) where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable {
IEnumerator<T> e1 = l1.AsParallel().OrderBy(e => e).GetEnumerator();
IEnumerator<T> e2 = l2.AsParallel().OrderBy(e => e).GetEnumerator();
IEnumerator<T> longest; //to yield longest list remains
//First move needed to init first "Current"
e1.MoveNext();
e2.MoveNext();
//yields smaller current value and move its IEnumerable pointer
//breaks while loop if no more values in some Enumerable and mark the other one as longest
while (true) {
if (e1.Current.CompareTo(e2.Current) < 0) {
yield return e1.Current;
if (!e1.MoveNext()) { longest = e2; break; }
}
else {
yield return e2.Current;
if (!e2.MoveNext()) { longest = e1; break; }
}
}
//finish the longest Enumerator
do {
yield return longest.Current;
} while (longest.MoveNext());
}
}
不管怎样,我的推荐和Siavash在评论中的一样:
var merged = myList1.Union(myList2).AsParallel().OrderBy(e => e).ToList();
static List<int>Merge(List<int> list_a, List<int> list_b)
{
List<int> list_c=new List<int>();
int countA = 0, countB = 0;
for (int i =0;i< list_a.Count + list_b.Count-2;i++)
{
if (list_a[countA]<=list_b[countB])
{
list_c.Add(list_a[countA]);
countA ++;
}
else
{
list_c.Add(list_b[countB]);
countB ++;
}
}
return list_c;
}
我的想法是通过 for 循环的次数与最后 list_c 元素的数量一样多 比较两个列表中的每个元素,然后添加 list_c 中的最小元素 我已经有办法检查两个列表是否按升序排列 当我用
测试它时List<int> myList1 = new List<int> { 1, 2, 3, 7, 8, 9 };
List<int> myList2 = new List<int> { 4, 5, 6};
Console.WriteLine("new list :{ " + string.Join(",", Merge(myList1, myList2)));
countB 一旦添加了列表 b 中的最后一个元素,就会越界,该 for 循环中的下一个比较将无效,因为它比较 list_b[3]
考虑到您要使用循环:
public static List<int> Merge(List<int> list_a, List<int> list_b)
{
int firstListIndexer = 0, secondListIndexer = 0;
List<int> list_c = new List<int>();
// Traverse lists, until one of them run out of the elements
while (firstListIndexer < list_a.Count && secondListIndexer < list_b.Count)
{
if (list_a[firstListIndexer] < list_b[secondListIndexer])
list_c.Add(list_a[firstListIndexer++]);
else
list_c.Add(list_b[secondListIndexer++]);
}
// Store remaining elements of first list
while (firstListIndexer < list_a.Count)
list_c.Add(list_a[firstListIndexer++]);
// Store remaining elements of second list
while (secondListIndexer < list_b.Count)
list_c.Add(list_b[secondListIndexer++]);
return list_c;
}
此外,您还可以阅读 this 以提高您对该主题的了解。
您在较短数组上的索引超出了其最大索引。需要检查Count
是否超过最大索引。
class Program {
static List<int> Merge(List<int> list_a, List<int> list_b) {
List<int> list_c = new List<int>();
int countA = 0, countB = 0;
for (int i = 0; i < list_a.Count + list_b.Count; i++) {
if (countA < list_a.Count && countB < list_b.Count) {
if (list_a[countA] <= list_b[countB]) {
list_c.Add(list_a[countA]);
countA++;
}
else {
list_c.Add(list_b[countB]);
countB++;
}
}
else if (countA < list_a.Count) {
list_c.Add(list_a[countA]);
countA++;
}
else {
list_c.Add(list_b[countB]);
countB++;
}
}
return list_c;
}
static void Main(string[] args) {
List<int> myList1 = new List<int> { 1, 2, 3, 7, 8, 9 };
List<int> myList2 = new List<int> { 4, 5, 6 };
Console.WriteLine("new list :{ " + string.Join(",", Merge(myList1, myList2)) + "}");
}
}
如果我们可以假设两个列表都是按升序排列的,那么您可以像这样合并集合以遵守升序。
static List<int> MergeTowAscendinglyOrderedCollections(IEnumerable<int> collectionA, IEnumerable<int> collectionB)
{
var result = new List<int>();
IEnumerator<int> iteratorA = collectionA.GetEnumerator();
IEnumerator<int> iteratorB = collectionB.GetEnumerator();
bool doesIteratorAHaveRemainingItem = iteratorA.MoveNext();
bool doesIteratorBHaveRemainingItem = iteratorB.MoveNext();
void SaveIteratorAsCurrentAndAdvanceIt()
{
result.Add(iteratorA.Current);
doesIteratorAHaveRemainingItem = iteratorA.MoveNext();
}
void SaveIteratorBsCurrentAndAdvanceIt()
{
result.Add(iteratorB.Current);
doesIteratorBHaveRemainingItem = iteratorB.MoveNext();
}
do
{
if (iteratorA.Current < iteratorB.Current)
{
if (doesIteratorAHaveRemainingItem) SaveIteratorAsCurrentAndAdvanceIt();
else SaveIteratorBsCurrentAndAdvanceIt();
}
else if (iteratorA.Current > iteratorB.Current)
{
if (doesIteratorBHaveRemainingItem) SaveIteratorBsCurrentAndAdvanceIt();
else SaveIteratorAsCurrentAndAdvanceIt();
}
else if (iteratorA.Current == iteratorB.Current)
{
SaveIteratorAsCurrentAndAdvanceIt();
SaveIteratorBsCurrentAndAdvanceIt();
}
} while (doesIteratorAHaveRemainingItem || doesIteratorBHaveRemainingItem);
return result;
}
为了防止重复,我已将两个数字都添加到合并列表中,但根据您的业务需求,您可以调整代码以从结果中省略一个或两个值。
你可以做一个联盟
List<int> myList1 = new List<int> { 1, 2, 3, 7, 8, 9 };
List<int> myList2 = new List<int> { 4, 5, 6};
var merged = myList1.Union(myList2).OrderBy(o=>o).ToList();
foreach(int number in merged)
Console.WriteLine(number);
输出如下
1 2个 3个 4个 5个 6个 7 8个 9
如果你必须实现你的 serlf:
使用协程在短短几行中实现没有计数器和索引:
class Program {
static void Main() {
List<int> l1 = new List<int>() { 9,8, 7, 5, 3, 1 };
List<int> l2 = new List<int>() {12 ,10, 8, 6, 4, 2 };
IEnumerable<int> res = MergeAscending(sl1, sl2);
foreach (int item in res) {
Console.Write($"{item},");
}
Console.Read();
}
static IEnumerable<T> MergeAscending<T>(IEnumerable<T> l1, IEnumerable<T> l2) where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable {
IEnumerator<T> e1 = l1.AsParallel().OrderBy(e => e).GetEnumerator();
IEnumerator<T> e2 = l2.AsParallel().OrderBy(e => e).GetEnumerator();
IEnumerator<T> longest; //to yield longest list remains
//First move needed to init first "Current"
e1.MoveNext();
e2.MoveNext();
//yields smaller current value and move its IEnumerable pointer
//breaks while loop if no more values in some Enumerable and mark the other one as longest
while (true) {
if (e1.Current.CompareTo(e2.Current) < 0) {
yield return e1.Current;
if (!e1.MoveNext()) { longest = e2; break; }
}
else {
yield return e2.Current;
if (!e2.MoveNext()) { longest = e1; break; }
}
}
//finish the longest Enumerator
do {
yield return longest.Current;
} while (longest.MoveNext());
}
}
不管怎样,我的推荐和Siavash在评论中的一样:
var merged = myList1.Union(myList2).AsParallel().OrderBy(e => e).ToList();