首页 文章

一个程序,在第三个数组中汇总2个数组和显示输出 . 它显示运行时错误 . 为什么?

提问于
浏览 1965
-1

我编辑了代码 . 但现在它显示运行时错误 . 有人能说出原因吗?这是一个将第2个数组和第三个数组中的显示输出相加的程序 . 我还想知道这段代码是否可以优化?

void sumOfTwoArrays(int arr[], int size1, int brr[], int size2, int crr[])
{
    int k;
    if(size1>size2){
        k = size1;
    }
    else
        k = size2;

    int c = k;
    int r = 0;
    int i = size1-1;
    int j = size2-1;
    for(;i>=0&&j>=0;i--,j--){
        int n = arr[i] + brr[j] + r;
        if(n<=9){
            crr[c] = n;
        }
        else
        {
          int r = n/10;
          n = n%10;
          crr[c] = n;
        }
        c--;
    }

    while(arr[i]>=0){
        crr[c] = arr[i] + r;
        r = 0;
        c--;
    }
    while(brr[j]>=0){
        crr[c] = brr[j] + r;
        r = 0;
        c--;
    }
    if(r!=0){
        crr[c] = r;
    }
}

3 回答

  • 3

    关于范围问题:请参阅Stephananswer .

    我也想知道这段代码是否可以优化

    通过使用 std::vector . 好吧,如果您也可以使用外部向量,以下只是一个很好的选项 - 将原始数组复制到向量中也不会有效...但如果可以,那么您可能会喜欢这个变体:

    template <typename T> // optional: you're more flexible if you make a template of...
    void sumOfTwoArrays(std::vector<T> const& va, std::vector<T> const& vb, std::vector<T>& vr)
    {
        vr.resize(std::max(va.size(), vb.size() + 1));
        int carry = 0; // renamed r to something more meaningful
    
        // these pairs will help to avoid code duplication later
        std::pair pa(va, va.rbegin());
        std::pair pb(vb, vb.rbegin());
        auto ir = vr.rbegin();
        while(pa.second != pa.first.rend() && pb.second != pb.first.rend())
        {
            // just skip the if/else:
            // assume you have arbitrary number, the else case will be entered anyway
            // in 50 % of the cases - in the other 50 %, the else branch calculates
            // the correct result, too; and on most modern machines, the branch is
            // rather expensive, so you result in easier code and have quite a good
            // chance to even perform better...
            carry += *pa.second + *pb.second;
            *ir = carry % 10;
            carry /= 10;
            ++ir, ++pa.second, ++pb.second;
        }
    
        // avoiding of two identical while loops: iterate over the two pairs...
        for(auto p : { pa, pb })
        {
            // just loop over, if we are already at the end, won't enter...
            while(p.second != p.first.rend())
            {
                // STILL need to continue calculating the carry!
                // imagine we have set it and ciphers following are all 9!
                carry += *p.second;
                *ir = carry % 10;
                carry /= 10;
                ++ir, ++p.second;
            }
        }
        // assign either 0 or 1...
        *ir = carry;
    }
    

    变体:您可以在最后删除第一个元素,而不是分配0:

    if(carry == 0)
    {
        vr.erase(vr.begin());
    }
    else
    {
        *ir = carry;
    }
    

    请注意,这会将所有元素向前移动一个位置 . 另一方面,如果您反复添加已经包含前导零的向量,则可以在不需要的情况下一次又一次地添加另一个向量,如果不再删除它 .

    你不会't experience any of these issues if you inverted the order of digits in the vector, having least significant one at position 0 (you'与 begin()end() 交换 rbegin()rend() ,但会使用前者打印数据来显示......) . 最后的擦除将是 O(1) 操作然后:

    if(carry == 0)
    {
        vr.erase(std::previous(vr.end())
    }
    // ...
    

    如果你保持矢量标准化(即0到9之间的所有数字),上面所有这些只会按预期工作 . 您可以考虑将向量打包到一个单独的类中,以便数据远离用户隐藏,并且只能以受控方式进行修改(假设您有一个精细向量,但用户确实 v[7] = -1012 ...) .

  • 1

    运行时错误表明它是一个内存问题,即您正在写入一些未分配给您的代码使用的内存 . 因此,正如其他贡献者所提到的,您应该为数组分配适当的内存 .

    以下是您的代码的修改版本,工作正常 . 你可以see it working here

    void sumOfTwoArrays(int arr1[], int size1, int arr2[], int size2, int sumArr[])
    {
        int maxLen;
        int* tArry;
        int l;
        if(size1>size2) { maxLen = size1; tArry = arr1; l = size1 - size2; }
        else { maxLen = size2; tArry = arr2; l = size2 - size1; }
    
        int carry = 0;
    
        while(size1 && size2){
            carry += arr1[--size1] + arr2[--size2];
            sumArr[maxLen--] = carry%10;
            carry /= 10;
        }
    
        while(l){
            carry += tArry[--l];
            sumArr[maxLen--] = carry%10;
            carry /= 10;
        }
        sumArr[maxLen] = carry;
    }
    

    调用代码看起来像这样:

    ... 
    int a[] = {9,9,9,9,9};
    int b[] = {1};
    int l1 = sizeof(a) / sizeof(int), l2 = sizeof(b)/sizeof(int);
    int l3 = ((l1 > l2) ? l1 : l2) + 1;
    int *c = new int[l3];
    sumOfTwoArrays(a, l1, b, l2, c);
    ...
    delete [] c;
    ...
    
  • 0

    您在块作用域中声明变量,即在 { ... } 内,并且这些变量仅在此块中可见:

    if(size1>size2){ 
      int crr[size1+1];
      int c = size1;
    }
    else{
      int crr[size2+1];
      int c = size2;
    }
    ...
    crr[c] = ...  // neither crr nor c are valid here any more
    

    BTW:C不支持像 int crr[size1+1] 这样的可变长度数组(当 size 不是编译时常量时) .

    要克服这一点,写下......

    int *crr;
    int c;
    if(size1>size2){ 
      crr = new int[size1+1];
      c = size1;
    }
    else{
      crr = new int[size2+1];
      c = size2;
    }
    
    ...
    
    delete[] crr;
    

相关问题