0

I want to say that most of the Code is well and functioning, BUT when there are bigger data, it just malfunctions. I got 30 point out of 100 for it so far.

Here are test inputs and outputs, the source code, and the exercise itself (roughly translated to English).

The row's first numbers are the rows of after the first line, and the second one is the number of datas that are in those rows. After that those are the datas that I need to work with. I store them in bemenet 2 dimensional array.

My exercise was to find out which rows had at least 2 non 0 numbers in it. And then report it in a Matrix which size is: the second number from the first row^2.

So because of this I searched which rows have at least 2 non 0 numbers in them, then I put them in a Vector, and what I tried to do was to have like a relation thing, when like for example 1,2, and 4 are selected, the output will be all 0s except the 1st row 2nd 1st row 4th, 2nd row 1st, 2nd row 4th, and 4th row 1st and 2nd. In the in1.txt it works just like this, and is perfect, however, for the in2. Every value except for the main diagonal will be 1. I don't know what I did wrong, and I've been trying for the last 2 hours to solve this.

Can someone try to help, or explain me what my error is? Any help would be appreciated! Here's my source code so far:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct adatok{
  int szam = 0;
  bool alkalmi = false;
};

bool IsZero(int a){
    if(a == 0) return true;
    else return false;
}

int indexOf(vector<auto> v, auto item){
  for(int i=0; i <v.size();++i)
     if(item == v[i]) return i;
  return -1;
}
bool contains(vector<auto> v, auto item){
    return indexOf(v,item) != -1;
}

int main()
{
    int n = 0, m = 0;
    cin >> n >> m;vector<int> vektor;
    adatok bemenet[n][m];
    for (int i = 0; i < n; i++){
        int seged = 0;
        for (int j = 0; j < m; j++){
            cin >> bemenet[i][j].szam;
            if (!IsZero(bemenet[i][j].szam)){
                seged++;
            }
        }
        if (seged >= 2){
            for(int j = 0; j < m; j++){
                if(!IsZero(bemenet[i][j].szam)){
                    vektor.push_back(j);
                }
            }
        }
    }

    sort( vektor.begin(), vektor.end() );
    vektor.erase( unique( vektor.begin(), vektor.end() ), vektor.end() );

    for (int i = 0; i < m; i++){
        for (int j = 0; j < m; j++){
            if (i == j) cout << "0";
            else if(contains(vektor, i) && contains(vektor, j)){
                cout << "1";
            }
            else cout << "0";
        }
        cout << "\n";
    }

    return 0;
}

  • 1
    In the last loop you are using `m` as boundary in both outer and inner loop which is very likely incorrect. I haven't studied it too much though. – Resurrection Nov 17 '20 at 18:10
  • 2
    What does "not working" mean? Takes too long? Crashes? Uses up too much memory? My initial guess here is you have something that's quadratic in terms of run-time so the more data you add, the slower it gets, exponentially. – tadman Nov 17 '20 at 18:10
  • 2
    This `IsZero` function is a huge anti-pattern. Why a function to do something so elementary? – tadman Nov 17 '20 at 18:11
  • 1
    If you have a sorted vector, you can do a lot better than O(n) for `contains` and `indexOf`. The fact that those two functions take `v` by value means that every time you call `contains`, you're making two copies of `vektor`. There could very easily be major time/space issues with this code. – Nathan Pierson Nov 17 '20 at 18:11
  • Variable-sized arrays are stack-allocated. Use vector of vectors for a large allocation – stark Nov 17 '20 at 18:12
  • 1
    @stark This is C++. `malloc` is not the answer. If anything, `new[]` or `std::vector`. – tadman Nov 17 '20 at 18:12
  • 1
    Whoops - corrected. – stark Nov 17 '20 at 18:13
  • 2
    There's a lot of code here which suggests you're not really familiar with what the Standard Library can do for you out of the box, like [`std::find`](https://en.cppreference.com/w/cpp/algorithm/find) instead of this `indexOf` plus `contains` duct-tape solution. Check the Standard Library first for simple things like this as there's usually *something* there to build on. – tadman Nov 17 '20 at 18:15
  • 1
    In addition to the point raised by tadman above about `IsZero`, anytime you have a `if (condition) return true; else return false;` save yourself a bit of work and `return condition;` – user4581301 Nov 17 '20 at 18:17
  • @Resurrection They need to be compared m with m. Think of it like a knowing table. I only need to use 1 side of it divided by a main diagonal, and then making it's reflexion on the other side. They will only consist of numbers, and like its hard to explain but let's say that in 1 base input there's 2 3 0 4. This means that 1 is in relation with 2 and 4 and vice versa, so in my 4x4 square matrix is all 0 except for the 1st row 2nd and 4th, 2nd row 1st and 4th, and 4th row 1st and second. – Lakatos Márk Nov 17 '20 at 18:55
  • @tadman not working means that everything is 1 except for the main diagonal, also i know that function is silly, but my teacher said do everything we can in functions. – Lakatos Márk Nov 17 '20 at 18:56
  • "Do everything you can in functions" usually means "Don't write everything in `main()` and keep [SOLID](https://en.wikipedia.org/wiki/SOLID) in mind" not "literally write everything as a function, including trivial operations like `x == 0`". – tadman Nov 17 '20 at 19:26

2 Answers2

5

It's the Variable Length Array adatok bemenet[n][m];. A large enough m and n, could be as low as a few hundred each, will exhaust the program's automatic storage and send the program off into the wild and wacky world of Undefined Behaviour.

Note that Variable Length Arrays are not a part of Standard C++ (See Why aren't variable-length arrays part of the C++ standard? for a discussion on why not) and are only added by extension on a few compilers. Use them with caution if at all.

Use something like the vector-based matrix structure proposed in this answer instead.

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • 5
    It's also worthwhile to mention that Variable Length Arrays are not part of C++ at all, they're a compiler extension. – Human-Compiler Nov 17 '20 at 18:24
  • 1
    Most OS ABI's would raise a Stack Overflow abort (e.g. with a simple canary check of a special value at the stacks top+1) for exhaustive stack allocations though. But it is UB in the end, yes. – πάντα ῥεῖ Nov 17 '20 at 18:36
  • 1
    They need to be compared m with m. Think of it like a knowing table. I only need to use 1 side of it divided by a main diagonal, and then making it's reflexion on the other side. They will only consist of numbers, and like its hard to explain but let's say that in 1 base input there's 2 3 0 4. This means that 1 is in relation with 2 and 4 and vice versa, so in my 4x4 square matrix is all 0 except for the 1st row 2nd and 4th, 2nd row 1st and 4th, and 4th row 1st and second. – Lakatos Márk Nov 17 '20 at 18:55
  • @PatrikKarakai groovy and thanks. Will remove note. – user4581301 Nov 17 '20 at 19:04
0

After deciding to start over fresh, and to turn on my brain, I came up with the solution. For my problem this was how I managed to solve it completely, using Cartesian product.

#include <iostream>
#include <array>
#include <string.h>
#include <vector>

using namespace std;

bool IsZero(int a){
    if(a == 0) return true;
    else return false;
}

int main()
{
    int n = 0, m = 0;
    cin >> n >> m;
    int bemenet[n][m];
    int kimenet[m][m];
    memset(kimenet, 0, m * m * sizeof(int));

    for (int i = 0; i < n; i++){
        vector<int> seged;
        int s1 = 0;
        for (int j = 0; j < m; j++){
            cin >> bemenet[i][j];
            if (!IsZero(bemenet[i][j])){
                seged.push_back(j);
            }
        }
        for (int j = 0; j < seged.size(); j++){
            for (int k = 0; k < seged.size(); k++){
                if (seged[j] != seged[k]){
                    kimenet[seged[j]][seged[k]] = 1;
                    kimenet[seged[k]][seged[j]] = 1;
                }
            }
        }
    }

    for (int i = 0; i < m; i++){
        for (int j = 0; j < m; j++){
            cout << kimenet[i][j];
        }
        cout << "\n";
    }

    return 0;
}