【问题标题】:sum of two arrays element wise?两个数组元素之和?
【发布时间】:2017-02-01 06:46:15
【问题描述】:

有一个问题,其中给出了两个随机整数数组,其中从 0 到 9 的数字出现在每个索引处(即单个数字整数出现在两个给定数组的每个索引处)。我需要找到输入数组表示的数字的总和,并将结果放入另一个数组中。

我相信我的代码一切正常,因为我对不同的数组执行了近 50 到 60 次。但是当我在学校的在线评委中提交时,它只接受了 4 个测试用例,而拒绝了另外两个。我不知道在哪种情况下它会给出错误的输出。需要一点帮助。

这是我的代码

public static int[] sumOfTwoArrays(int[] arr1, int[] arr2){
    int size1 = arr1.length;
    int size2 = arr2.length;
    int carry = 0,sum,s,r;
    if(size1 == size2) {
        int arr3[] = new int[size1+1];
        for(int i=arr1.length-1;i>=-1;i--) { 
            if(i==-1) {
                arr3[i+1] = carry;
                //System.out.println(i+1+" "+arr3[i+1]);
            } else {
                sum = arr1[i] + arr2[i];
                if(sum>9) {
                    s =sum;
                    r = s % 10;
                    arr3[i+1] = carry + r;
                    carry = 1;
                    //System.out.println(i+" "+arr3[i]);    
                } else {
                    if(sum==9 && carry==1) {
                        s =sum+carry;
                        r = s % 10;
                        arr3[i+1] = r;
                    } else {
                        arr3[i+1] = sum+carry;
                        carry=0; 
                    }
                    //System.out.println(i+" "+arr3[i]);
                }  
            }      
        }
        return arr3;
    } else if (size1>size2) {
       int arr3[] = new int[size1+1];
       int diff = arr1.length - arr2.length;
       for(int i=arr1.length-1;i>=-1;i--) {
           if(i==-1) {
               arr3[i+1] = carry;
           } else {
               if(i>=diff) {
                   sum = arr1[i] + arr2[i-diff];
                    if(sum>9) {
                        s =sum;
                        r = s % 10;
                        arr3[i+1] = carry + r;
                        carry = 1;
                    } else {
                        if(sum==9 && carry==1) {
                            s =sum+carry;
                            r = s % 10;
                            arr3[i+1] = r;
                        } else {
                            arr3[i+1] = sum+carry;
                            carry=0; 
                        }
                    } 
                }  // end of diff i
                else {
                   arr3[i+1] =  arr1[i];
                   carry = 0;
                }
            }      
        }
        return arr3;
    } else {
        int arr3[] = new int[size2+1];
        int diff = arr2.length - arr1.length;
        for(int i=arr2.length-1;i>=-1;i--) {
            if(i==-1) {
                arr3[i+1] = carry;
            } else {
                if(i>=diff) {
                    sum = arr2[i] + arr1[i-diff];
                    if(sum>9) {
                        s =sum;
                        r = s % 10;
                        arr3[i+1] = carry + r;
                        carry = 1;
                    } else {
                        if(sum==9 && carry==1) {
                            s =sum+carry;
                            r = s % 10;
                            arr3[i+1] = r;
                        } else {
                            arr3[i+1] = sum+carry;
                            carry=0; 
                        }
                    }  
                }  // end of diff i
                else {
                    arr3[i+1] =  arr2[i];
                    carry = 0;
                }
            }      
        }
        return arr3;
    }   
}

示例输入:

int[] arr1 = {8,5,3,9,6};
int[] arr2 = {3,3,3,3,3};

样本输出:

{1,1,8,7,2,9}

示例输入:

int[] arr1 = {8,5,3,9,6};
int[] arr2 = {1,0,5}; 

样本输出:

{0,8,5,5,0,1}

【问题讨论】:

  • 这可能包含对算法、输入和输出的一些解释。
  • 真的需要在你最后的输出中领先0吗?不应该是{8,5,5,0,1}吗?
  • @Roland 你不能轻易确定结果是否需要额外的数字来进行进位,所以我认为 OPs 方法是可以的。
  • 嗯,这是真的。但我更想知道它是否真的需要?如果测试表明不允许使用前导 0 怎么办?
  • @PrinceVijayPratap 在我的解决方案中,我添加了您的错误的原因。

标签: java arrays


【解决方案1】:

嗯,我有这个基于 Eran 解决方案的算法(正在努力修复他后来纠正的错误),我会分享它,因为我使用的数组更少。

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

    int len1 = arr1.length;
    int len2 = arr2.length;
    int len = Math.max(len1, len2);

    int arr3[] = new int[len + 1];

    for (int i = 1; i <= len; i++) {
        sum =
            (len1 - i >= 0 ? arr1[len1-i] : 0)
            + (len2 - i >= 0 ? arr2[len2-i] : 0)
            + carry;

        arr3[len-i+1] = sum%10;
        carry = sum/10;
    }
    arr3[0] = carry;

    return arr3;
}

三元运算符的用法仍然可读,所以我觉得这是一个很好的解决方案。

为了简短说明,我们从末尾读取数组,使用i 从右到左读取,但基于数组的长度。数组大小不同时使用三元运算。

编辑:

您的算法无法正确管理不同大小数组的进位值。

185 + 16 给出101

仅仅是因为您设置了如下值:

arr3[i+1] =  arr1[i];

所以你忘记了上一次操作中可能发生的进位。

【讨论】:

  • @PrinceVijayPratap,不客气。原因很简单,你没有测试所有东西;)你没有进行任何不同尺寸的测试,最后随身携带。
  • @AxelH 是的,随机性是罪魁祸首。
【解决方案2】:

这段代码比它必须的要复杂得多,这增加了它包含难以检测的错误的机会。

您不必执行该算法 3 次(根据第一个数组是否更小、更大或等于第二个数组)。您可以为两个大小为Math.max(arr1.length,arr2.length) 的大小相等的数组实现一次。 这将消除您 2/3 的代码。

int len = Math.max(arr1.length,arr2.length);
int[] arr11 = new int[len];
int[] arr22 = new int[len];
int arr3[] = new int[len+1];
for(int i=len-1;i>=-1;i--) {
    if (i>=len-arr1.length)
        arr11[i]=arr1[i-(len-arr1.length)];
    if (i>=len-arr2.length)
        arr22[i]=arr2[i-(len-arr2.length)];
    // now you can use arr11[i] and arr22[i] instead of arr1[i] and arr2[i]
    ...
}

此外,我建议您立即添加进位而不是 sum = arr1[i] + arr2[i]; - sum = arr11[i] + arr22[i] + carry;。现在您只需检查一次是否sum &gt; 9

    if(i==-1) {
        arr3[i+1] = carry;
    } else {
        sum = arr11[i] + arr22[i] + carry;
        if(sum>9) {
            arr3[i+1] = sum % 10;
            carry = 1;
        } else {
            arr3[i+1] = sum;
            carry = 0;
        }
    }

结合这两个 sn-ps,你会得到:

int carry = 0;
int sum = 0;
int len = Math.max(arr1.length,arr2.length);
int[] arr11 = new int[len];
int[] arr22 = new int[len];
int arr3[] = new int[len+1];
for(int i=len-1;i>=-1;i--) {
    if(i==-1) {
        arr3[i+1] = carry;
    } else {
        if (i>=len-arr1.length)
            arr11[i]=arr1[i-(len-arr1.length)];
        if (i>=len-arr2.length)
            arr22[i]=arr2[i-(len-arr2.length)];
        sum = arr11[i] + arr22[i] + carry;
        if(sum>9) {
            arr3[i+1] = sum % 10;
            carry = 1;
        } else {
            arr3[i+1] = sum;
            carry = 0;
        }
    }
}
return arr3;

编辑:

我有一个小错误。我在较小数组的最低有效位(即高索引)而不是最高有效位(低索引)中添加 0,如果数组的长度不同,这会使结果错误。我修复了它,但现在将元素从原始数组复制到 arr11arr22 的部分可读性较差。

【讨论】:

  • @Eran 试过 int arr1[] = {8, 5, 3, 9, 6}; int arr2[] = {1, 0, 5}; 没用
  • @PrinceVijayPratap 现已修复不同长度的数组。你的输入给出了输出[0, 8, 5, 5, 0, 1]
  • @MauricePerry 现已修复。
  • @Eran 是的,它现在可以工作,但我仍然无法弄清楚我冗长的代码到底有什么问题。它每次都能给我正确的输出ఠ_ఠ
  • @Eran,好吧,我正在写我的,最终也得到了这个算法。我只是使用len1len2 来提高可读性。只需将arr3[0] = carry; 放在循环之后,而不是这个if(i ==-1)
【解决方案3】:

如果不需要在第二个示例输出中使用前导 0,您还可以通过预先转换输入来使用不同的方法,例如功能如下:

static Integer toNumber(int[] arr) {
  return Integer.valueOf(Arrays.stream(arr)
                               .mapToObj(Integer::toString)
                               .collect(Collectors.joining()));
}

这样你就可以对你的数组求和,就好像它们是普通整数一样:

Integer sum = toNumber(arr1) + toNumber(arr2);

将其转换回数组可以如下完成:

int[] sumArray = sum.toString().chars()
                               .map(operand -> Character.digit(operand, 10))
                               .toArray();

但是您现在的输出中没有前导 0。该代码使用 Java 8,但同样可以在没有流的情况下写入(但未经测试):

static Integer toNumber(int[] arr) {
  StringBuilder integerStrBuilder = new StringBuilder();
  for (int i = 0; i < arr.length; i++) {
    integerStrBuilder.append(Integer.toString(arr[i]));
  }
  return Integer.valueOf(integerStrBuilder.toString());
}

对于数组:

char[] characters = sum.toString().toCharArray();
int[] sumArray = new int[characters.length];
for (int j = 0; j < characters.length; j++) {
  sumArray[j] = Characters.digit(characters[j], 10);
}

【讨论】:

    【解决方案4】:
    int[] firstArray = {1,8,8,8, 8};
            int[] secondArray = {1,8,9};
            String diffstring1 = "", diffstring2 = "";
            for (int i = 0; i < firstArray.length; i++) {
                diffstring1 = diffstring1 + String.valueOf(firstArray[i]);
            }
    
            for (int i = 0; i < secondArray.length; i++) {
                diffstring2 = diffstring2 + String.valueOf(secondArray[i]);
            }
    
            int diff = Integer.parseInt(diffstring1) + Integer.parseInt(diffstring2);
    
            String diifffinal = String.valueOf(diff);
            int[] third = new int[diifffinal.length()];
            for (int j = 0; j < diifffinal.length(); j++) {
                char abc = diifffinal.charAt(j);
                third[j] = Character.getNumericValue(abc);
                Log.d(TAG, "onCreate:---> " + third[j]);
            }
    

    【讨论】:

      【解决方案5】:

      效果不错

              int[] arr1 = {1, 2, 3, 4, 5, 6}, arr2 = {3, 5, 2, 9, 0};
              int[] output = new int[Math.max(arr1.length, arr2.length)];
              int num1 = 0, num2 = 0;
              for (int value : arr1) {
                  num1 = (num1 * 10) + value;
              }
      
              for (int i : arr2) {
                  num2 = (num2 * 10) + i;
              }
      
              int result = (num1 + num2), k = output.length - 1;
      
              while(result > 0){
                  output[k] = (result % 10);
                  result = result / 10;
                  k--;
              }
      
              if(k>0){
                  output[k] = 0;
                  k--;
              }
      
              for(int value: output){
                  System.out.print(value + " ");
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-08
        • 2018-09-21
        • 1970-01-01
        相关资源
        最近更新 更多