首页 > 解决方案 > 如何在数组之间分离和移动非负值和正值?

问题描述

如何编写将非负值(在两个给定数组中找到)移动到第一个数组中,然后将负值(在两个给定数组中找到)移动到第二个数组中的方法?例如:对于 {1, -2, 5} 和 {-2, 4, -9},我们应该收到 {1, 5, 4} 和 {-2, -2, -9}。不保证非负数/负数之间的偶数分裂。数组的大小可以更改。

    static void Arrays(ref int[] tab1, ref int[] tab2){
        int[] tempNegative = new int[3];
        int[] tempNonNegative = new int[3];

        for (int i = 0; i < tab1.Length; i++)
        {
            for (int j = 0; j < tab2.Length; j++)
            {
                if (tab1[j] < 0)
                {
                    tempNegative[j] = tab1[j];
                }
                else
                {
                    tempNonNegative[i] = tab1[j];
                }
            }

        }

        tab1 = tempNonNegative;
        tab2 = tempNegative;
    }

在主程序中使用此方法后,我收到 {5, 5, 5} 和 {0, -2, 0}。我知道应该有另一个循环来检查第二个数组中的值。问题是如何将值放在这些数组中的适当位置?

标签: c#

解决方案


您的问题中有 2 条证据导致我采用以下方法来解决它:

  1. 您声明“可以更改数组的大小”
  2. ref在向方法声明参数时使用

我已经评论了为什么第一个实际上是一个谬误,但是将这两个放在一起意味着有两种方法可以为您的问题编写解决方案。

  1. 使用 LINQ
  2. 手动进行

我会先手动完成。

最简单的方法是声明两个列表,如果是负数则将每个数字放入一个,如果不是,则放入另一个,然后在最后将参数重新分配给一个新数组,如下所示:

static void Arrays(ref int[] tab1, ref int[] tab2)
{
    var negatives = new List<int>();
    var positives = new List<int>();

    foreach (var item in tab1)
        if (item < 0)
            negatives.Add(item);
        else
            positives.Add(item);
    foreach (var item in tab2)
        if (item < 0)
            negatives.Add(item);
        else
            positives.Add(item);

    tab1 = positives.ToArray();
    tab2 = negatives.ToArray();
}

现在,如果我们允许一点点LINQ,我们可以将两个数组合并到一个集合中,从而降低到一个 foreach:

static void Arrays(ref int[] tab1, ref int[] tab2)
{
    var negatives = new List<int>();
    var positives = new List<int>();

    foreach (var item in tab1.Concat(tab2))
        if (item < 0)
            negatives.Add(item);
        else
            positives.Add(item);

    tab1 = positives.ToArray();
    tab2 = negatives.ToArray();
}

第二种方法是完全使用 LINQ:

static void Arrays(ref int[] tab1, ref int[] tab2)
{
    var negatives = tab1.Concat(tab2).Where(i => i < 0).ToArray();
    tab1 = tab1.Concat(tab2).Where(i => i >= 0).ToArray();
    tab2 = negatives;
}

它必须使用一个临时变量,negatives否则我们会tab2在我们开始计算要放入什么之前破坏 的内容tab1

如果我们使用更新的 C# 语法重写整个方法,例如 Expression-bodied members (C# 6+) 和 Tuples (C# 7+),我们得到:

static void Arrays(ref int[] tab1, ref int[] tab2)
    => (tab1, tab2) = (
        tab1.Concat(tab2).Where(i => i >= 0).ToArray(),
        tab1.Concat(tab2).Where(i => i < 0).ToArray()
    );

推荐阅读