Home > Back-end >  C - response is int%
C - response is int%

Time:05-29

I decide 2D Dinamic Coding on C , i'm decide task about count of ways to bottom-right field in table, and my program return %. Why? Program:

#include <iostream>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    int arr[n][m];

    for (int i = 0; i < n; i  ) 
        arr[i][0] = 1;

    for (int i = 0; i < m; i  )
        arr[0][i] = 1;

    for (int i = 1; i < n; i  ) {
        for (int j = 1; j < m; j  )
            arr[i][j] = arr[i-1][j]   arr[i][j-1];
    }

    cout << arr[n-1][m-1];
}

I would like answer Request: 1 10 Response: 1

CodePudding user response:

Your program has undefined behavior for any other sizes than n = 1 and m = 1 because you leave the non-standard VLA (variable length array) arr's positions outside arr[0][0] uninitialized and later read from those positions. If you want to continue using these non-standard VLA:s, you need to initialize them after constructing them. Example:

#include <cstring> // std::memset

    // ...
    int arr[n][m];
    std::memset(arr, 0, sizeof arr); // zero out the memory
    // ...

Another approach that would both make it initialized and be compliant with standard C would be to use std::vectors instead:

#include <vector>

    // ...
    std::vector<std::vector<int>> arr(n, std::vector<int>(m));
    // ...

A slightly more cumbersome approach is to store the data in a 1D vector inside a class and provide methods of accessing the data as if it was stored in a 2D matrix. A class letting you store arbitrary number of dimensions could look something like below:

#include <utility>
#include <vector>

template <class T, size_t Dim> // number of dimensions as a template parameter
class matrix {
public:
    template <class... Args>
    matrix(size_t s, Args&&... sizes)  // sizes of all dimensions
        : m_data(s * (... * sizes)),   // allocate the total amount of data
          m_sizes{s, static_cast<size_t>(sizes)...}, // store sizes
          m_muls{static_cast<size_t>(sizes)..., 1}   // and multipliers
    {
        static_assert(sizeof...(Args)   1 == Dim);
        for (size_t i = Dim - 1; i--;)
            m_muls[i] *= m_muls[i   1]; // calculate dimensional multipliers
    }

    template <size_t D> size_t size() const { return m_sizes[D]; }
    size_t size(size_t D) const { return m_sizes[D]; }

    // access the data using (y,z) instead of [y][x]
    template <class... Args>
    T& operator()(Args&&... indices) {
        static_assert(sizeof...(Args) == Dim);
        return op_impl(std::make_index_sequence<Dim>{}, indices...);
    }

private:
    template <std::size_t... I, class... Args>
    T& op_impl(std::index_sequence<I...>, Args&&... indices) {
        return m_data[(...   (indices * m_muls[I]))];
    }

    std::vector<T> m_data;
    size_t m_sizes[Dim];
    size_t m_muls[Dim];
};

With such a wrapper, you'd only need to change the implementation slightly:

#include <iostream>

int main() {
    int n, m;
    if(!(std::cin >> n >> m && n > 0 && m > 0)) return 1;

    matrix<int, 2> arr(n, m);

    for (int i = 0; i < arr.size<0>(); i  )
        arr(i, 0) = 1;

    for (int i = 0; i < arr.size<1>(); i  )
        arr(0, i) = 1;

    for (int i = 1; i < n; i  ) {
        for (int j = 1; j < m; j  ) 
            arr(i, j) = arr(i - 1, j)   arr(i, j - 1);
    }

    std::cout << arr(n - 1, m - 1) << '\n';
}
  •  Tags:  
  • c
  • Related