【问题标题】:How can i resize the array while summing two element?如何在对两个元素求和时调整数组的大小?
【发布时间】:2019-02-25 17:41:31
【问题描述】:

想象一下我有一个这样的数组{7, 2, 8, 9, 4, 13, 7, 1, 9, 10} 我想要这个数组{9, 17, 17, 8, 19}

原始列表中的第一对被折叠成 9 (7 + 2),第二对被折叠成 17 (8 + 9),依此类推。

我的问题是如何在 C# 中调整初始数组的大小?

我不想使用初始数组一半大小的另一个数组,我不能使用 List。

【问题讨论】:

  • 使用通用的List 并且不用担心重新调整硬编码数组的大小?
  • 请注意,OP 提到他们不能使用 List。 @mobikaoxox 有什么理由不这样做吗?这部分作业是否只涉及数组?
  • 您遇到了问题的哪一部分:1)求和对,2)折叠集合?您是否在文档中查找了可用的 Array 方法?你试过什么?
  • 当您的限制阻止您使用完美的解决方案(在本例中为List)时,您需要解释原因。
  • 唯一且真正的解决方案是自定义类,带有数组 this[int] 访问器实现和接口 IList、ICollection,可能带有 WeakReference 和 IDisposable 项容器实现

标签: c# arrays .net


【解决方案1】:

唯一可以调整数组大小的方法是Array.Resize()。但是,正如评论中所述:

此方法分配一个指定大小的新数组,将旧数组中的元素复制到新数组中,然后用新数组替换旧数组。

意思是你问的实际上是不可能的。

现在我们可以质疑原因。你为什么不想要另一个数组?

您可以用这个替换旧阵列,垃圾收集器将负责清理旧阵列。但这与使用 Resize() 方法相同。

你可以使用 List,但显然你不能。您能否详细说明这是为什么? List 在所有 .Net 框架和库中都可用。

根据您的要求,这看起来很像 XY Problem

【讨论】:

  • 是的,抽象 Array 类在设计上不包含收缩自身的方法,这主要是因为与 GC 和内存管理有关。除了 Span,Memory 结构体也不能收缩数组。
【解决方案2】:

您不能在 C# 中调整初始数组的大小。 C# 中的 Arrays 不可调整大小。 https://docs.microsoft.com/en-us/dotnet/api/system.array?view=netframework-4.7.2

int[] array = { 7, 2, 8, 9, 4, 13, 7, 1, 9, 10 };

您无法调整此数组的大小。

【讨论】:

    【解决方案3】:

    请查看this code example

    看来你需要使用Array.Resize方法(MSDN链接是here)。

    代码sn-p:

    var arr = int[10] {7, 2, 8, 9, 4, 13, 7, 1, 9, 10};
    for (int i=0; i<5; i++)
    {
       arr[i]=arr[i] + arr[i+1];
    }
    Array.Resize(ref arr, 5);
    

    【讨论】:

      【解决方案4】:

      我只使用数组编写了一个简单的实现。首先,我们遍历数组,每隔一个元素执行求和。然后删除第二个元素,并在他的位置放置一个标志 (-1000)。

      然后我使用冒泡排序算法的简单逻辑,但我们只在找到我们的标志时交换。因此我们所有的和都在数组的左边,同时标志在右边。

      然后我使用 Take 方法取一半的结果。

              int flag = -1000;
              int[] myValues = new int[] { 7, 2, 8, 9, 4, 13, 7, 1, 9, 10 };
              for (int i = 0; i < myValues.Length; i++)
              {
                  if (i % 2 != 0 && i != 0)
                  {
                      myValues[i - 1] = myValues[i] + myValues[i - 1];
                      myValues[i] = flag;
                  }
              }
              //clean up remove unwanted flags
              for (int i = 0; i < myValues.Length; i++)
              {
                  for (int j = i + 1; j < myValues.Length; j++)
                  {
                      if (myValues[i] == flag)
                      {
                          var temp = myValues[j];
                          myValues[j] = myValues[i];
                          myValues[i] = temp;
                      }
                  }
              }
      
              myValues = myValues.Take(myValues.Length / 2).ToArray(); 
      

      【讨论】:

        【解决方案5】:

        将第i个和第i+1个元素的和放在第i个位置,删除第i+1个元素,重复。

          private static List<int> solution(List<int> arr) {
            int s = arr.Count;
            for (int i = 0; i < s; i += 1) {
              arr[i] = arr[i] + arr[i + 1];
              arr.RemoveAt(i + 1);
              s -= 1;
            }
            return arr;
          }
        

        【讨论】:

        • 这不是调整初始数组的大小
        • 你能详细说明为什么会这样吗?
        • 按照设计,抽象类 Array 没有缩小其大小的方法,并且您在回答中根本没有使用C# arrays,因此它与问题how can be initial array be shrinked half in size 无关。答案是 - 在您使用 C# 数组之前,您无法做到这一点,而不是 Span&lt;T&gt;Memory&lt;T&gt; 或其他结构,反正这不是 C# 数组。
        • 我使用的是 List 泛型类,而不是抽象类 Array。你的意思是说不能调整 List 泛型类的大小吗?如果是这样,我相信你是不正确的。不过,我没有看到问题的陈述,即他们“不能使用列表”,所以你是正确的,这个答案是无关紧要的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-31
        • 2013-03-15
        • 1970-01-01
        • 2012-12-16
        • 1970-01-01
        相关资源
        最近更新 更多