【问题标题】:Represent significant integers of two arrays into one [duplicate]将两个数组的有效整数表示为一个[重复]
【发布时间】:2020-01-16 17:08:21
【问题描述】:

我试图将两个数组整数成员的总和表示为一个,如下例所示:

      int[] array1 = {1,0}
      int[] array2 = {5} 
      int[] result = {1,5}
  OR
      int[] array1 = {2,4}
      int[] array2 = {3,6} 
      int[] result = {6,0}

(也注意求和进位))等等......,下面是我的尝试,但是它没有通过所有测试场景,有没有遗漏的部分?

public static int[] Process(int[] arr1, int[] arr2)
{
    int sum = 0;
    int length1 = 0;
    int length2 = 0;
    int size = 0;
    int carry = 0;

    if (arr1.Length > arr2.Length) { size = arr1.Length; }
    else { size = arr2.Length; }

    int[] RepArray = new int[size+1];

    for (int i = 0; i < size; i++)
    {

        sum = ( (length1 - i >= 0) ? arr1[length1  - i] : 0) + ( (length2 - i >= 0) ? arr2[length2 - i] : 0) + carry;

        RepArray[(size - i)] = sum % 10;
        carry = sum / 10;
    }

    return RepArray;


}

【问题讨论】:

  • 能否分享您遇到错误的输入?
  • {1,2,3} 和 {1,2};但错误或输入不是重点,重点是它自身的逻辑
  • 不考虑进位可能加多少位数,如何提前知道大小?
  • 你能解释一下规则吗,即 {1,0} + {5} = {1,5} 是怎么回事?看在 $DEITY 的份上——你为什么要这么做??
  • 好吧,忽略我的第二个问题,为什么不简单地将数组转换为单个数字,然后进行算术运算,然后将其转换回这个奇数数组表示形式?

标签: c# arrays algorithm data-structures


【解决方案1】:
static void Main(string[] args)
{
    int[] left = { 1, 0 };
    int[] right = { 5 };
    int[] actual = Sum(left, right);
    int[] expected = { 1, 5 };
    bool ok = actual.SequenceEqual(expected); // true
}

static int[] Sum(int[] left, int[] right)
{
    var length = Math.Max(left.Length, right.Length);
    left = Pad(left, length);
    right = Pad(right, length);
    var max = length - 1;

    bool carry = false;
    var stack = new Stack<int>(left.Zip(right, (Left, Right) => new { Left, Right })
        .Reverse()
        .Select((i, index) =>
        {
            var res = i.Left + i.Right;
            if (carry)
                res++;
            carry = res > 9 && index < max;
            if(carry)
                res %= 10;
            return res;
        }));

    var last = stack.Pop();
    return stack.Concat(new[]
                        {
                            last % 10,
                            last / 10 // remove this line to prevent array expanding
                        })
                .Reverse()
                .SkipWhile(i => i == 0) // remove this line to prevent array shrinking
                .ToArray();
}

static int[] Pad(int[] array, int length) =>
    new string(array.Select(i => i.ToString().Single()).ToArray())
        .PadLeft(length, '0')
        .Select(c => int.Parse(c.ToString()))
        .ToArray();

或者正如@iakobski 所说:

static void Main(string[] args)
{
    int[] left = { 1, 0 };
    int[] right = { 5 };
    int[] actual = Sum(left, right);
    int[] expected = { 1, 5 };
    bool ok = actual.SequenceEqual(expected); // true

    int[] Sum(int[] arg1, int[] arg2) =>
        ToArray(ToInt(arg1) + ToInt(arg2));

    int ToInt(int[] array) =>
        int.Parse(new string(array.Select(i => i.ToString().Single()).ToArray()));

    int[] ToArray(int i) =>
        i.ToString().Select(c => int.Parse(c.ToString())).ToArray();
}

【讨论】:

  • 我没有想到字符串化方法,但是是的,它也很有效,非常好。 +1
【解决方案2】:

迭代方法:

private static int[] process(int[] arr1, int[] arr2) {
  int len = Math.max(arr1.length, arr2.length);
  int[] shorter = arr1.length < len ? arr1 : arr2;
  int[] longer = arr1.length == len ? arr1 : arr2;
  int offset = longer.length - shorter.length;

  int[] result = new int[len];
  int carry = 0;

  for (int i = shorter.length - 1; i >= 0; i--) {
    int sum = shorter[i] + longer[offset + i] + carry;
    carry = (sum > 9) ? 1 : 0;
    result[offset + i] = sum - 10 * carry;
  }

  for (int j = offset - 1; j >= 0; j--) {
    int sum = longer[j] + carry;
    carry = (sum > 9) ? 1 : 0;
    result[j] = sum - 10 * carry;
  }

  if (carry > 0) {
    return resizeByOne(carry, result);
  }

  return result;
}

private static int[] resizeByOne(int positionZero, int[] digitsSum) {
  int[] resized = new int[digitsSum.length + 1];
  resized[0] = positionZero;
  for (int i = 1; i < resized.length; i++) {
    resized[i] = digitsSum[i - 1];
  }
  return resized;
}

BigInteger 方法:

private static int[] process(int[] arr1, int[] arr2) {
  BigInteger num1 = toNumber(arr1);
  BigInteger num2 = toNumber(arr2);
  BigInteger sum = num1.add(num2);
  return toArray(sum);
}

private static int[] toArray(BigInteger number) {
  String digits = number.toString();
  return IntStream.range(0, digits.length())
                  .map(digits::charAt)
                  .map(Character::getNumericValue)
                  .toArray();
}

private static BigInteger toNumber(int[] digits) {
  return new BigInteger(
          Arrays.stream(digits)
                .mapToObj(String::valueOf)
                .collect(Collectors.joining()));
}

【讨论】:

    猜你喜欢
    • 2017-03-22
    • 2019-08-04
    • 2014-06-29
    • 2016-02-26
    • 2021-07-05
    • 2011-09-28
    • 2011-06-09
    • 2021-12-17
    相关资源
    最近更新 更多