Issue of matrices

Asked

Viewed 45 times

-1

Well, the question may be that for what

  • Write an algorithm that reads an array A(5,2) and write it.
  • Check, below, which elements of To are repeated and how many times each is repeated.
  • Write each element repeated with a message saying how many times each element appears in To.

So since I couldn’t see which numbers were repeating in the matrix, I turned this matrix into a vector[10], and I could even count which numbers repeat, I just need to put it now how many times they repeat themselves. Follows the code.

#include<iostream>
#include <stdio.h>
#include <string>

using namespace std;
    
int main(){    
    int A[5][2];
    int vetor[10];
    int cont;
    int cont2;
    int cont3=0;

    cout << ("Digite numeros para a matriz:") << endl;
    for(cont=0;cont<5;cont++){
        for(cont2=0;cont2<2;cont2++) {
            cin >> A[cont][cont2];
        }
    }    

    for(cont=0;cont<5;cont++) {
        for(cont2=0;cont2<2;cont2++) {
            vetor[cont3]=A[cont][cont2];
            cont3++;
        }
    }

    for (cont = 0; cont < 10; cont++) {
        for (cont2 = cont+1; cont2 < 10; cont2++) {
            if (vetor[cont] == vetor[cont2]) {
                cout << ("Valor repetido:") << vetor[cont]<< endl;
            }  
        }
    }
}

1 answer

0

So how I was not able to see which numbers repeated in the matrix, I transformed this matrix into a vector[10], and even managed to count which numbers repeat, I just need to put now how many times they repeat.

Maybe you shouldn’t consider "transform". C++ doesn’t have vectors like in FORTRAN. Just vectors. And vector vectors and so on. As the values stay there lined up in memory one after another, line by line, its 5x2 "matrix" is actually a vector of 10 int from the start address.

Your program is very, very confusing :(

See this excerpt

   cout << ("Digite numeros para a matriz:") << endl;
    for(cont=0;cont<5;cont++){
        for(cont2=0;cont2<2;cont2++) {
            cin >> A[cont][cont2];
        }
    }    

Use more expressive names... cont and cont2 is evil. And never declare those loop control variables out of the loop. It’s a disaster. These values stay alive throughout the program and become impossible to control...

And help the user and yourself by telling what he is typing at every moment. Leaving the screen black and reading the values ONE by ONE is very boring and a hell to control.

Unless the statement clearly states that the matrix should be read from the user NEVER do so. It’s just a headache. Never write an interactive program if you don’t have to.

It is much easier and safer to read from a file. You can repeat the tests easily. You can type the matrix directly into the IDE. Save multiple test files...

And especially in tests you don’t have to keep coming up with 10 values all the time with the program eventually closing in on you.

Back on the show

You don’t pray to have written a program in C++ but a program in C. And you don’t even have the minimum that the statement asks, which is to show the function read.

Once you’ve done that, understand that there are many ways to do this, more to the C-side or more to the C-side++.

A long and inefficient way would be to sort the matrix into another and mark the values that are repeated, and then join a table.

A more C++ way would be to use some of the STL algorithms and some container.

A possible solution would be to do something like Selection Sort, which separates the smaller one with each loop in the matrix, and instead of reversing with the first one and sort you just see if the element is duplicated and how many times it appears in the table and keeps in a result matrix. At the end just show what’s there.

It can have nothing if the matrix is of all distinct elements, can have a single element and have a matrix of 10 constant elements....

Of course in C++ the expected would be to have a class for which you pass the file name on the disk and the number of rows and columns and it reads the matrix and calculates everything...

An example in C++

A class kit, one struct in this example, it serves. Declared so in kit.h

#pragma once
#include <iomanip>
#include <iostream>
#include <fstream>
#include <new>
using namespace std;

struct kit
{
    string  arquivo; // a origem
    int     C;  // colunas
    int     L;  // linhas
    int     N;  // tamanho, so pra nao mult. toda hora.

    int*    matriz; // a matriz
    struct  Par
    {
        int     posicao;
        int     quantos;

    }*          status; // o mapa de repetidos
    int         n_repetidos; // o total

    int     calcula_repetidos();
    int     le(string arquivo); // le a matriz

    kit(int, int, const char*); // o normal: LxC e arquivo
    kit() : kit(5, 2, "entrada.txt") {};
    ~kit();

    friend ostream& operator<<( ostream& sai, const kit& uma);

private:
    kit::Par     busca_menor();
    kit::Par     busca_menor(int);
};

The idea is simple: when declaring a kit If the guy does not specify anything the program will try to read an array 2 x 5 of the file "input.txt" in the current directory. It is your original problem. But the problem does not depend on the size of the matrix or the file where it is so the convenient is to be able to pass as parameters, or not?

a program that uses this struct

int         main(void)
{
    kit teste;
    cout << "(Testando com 5x2)\n" << teste << endl;

    kit uma55(5, 5, "55.txt");
    cout << "(Agora 5x5)\n" << uma55 << endl;

    return 0;
}

teste was declared without parameters so will use the size 5x2 and the file "input.txt". The cout shows text and operator << has been redefined for this struct kitso that will write what we program, whenever we read Cout << thing and coisa for a kit. This is typical of C++ and very convenient.

And I’m showing you an example, after all ;)

The second struct will use a 5x5 array and the other file. There are examples below. You don’t need to type anything if you want to test and change. Just copy and paste from here :)

functions in the struct

They are only 2 methods and in fact everything walks alone, as you saw in main(), because the builder of kit, the function that creates each occurrence of kit flame le() to read the file and calcula_repetidos to, well, calculate the repeated.

status within the struct is a pair vector where the repeated occurrences in the matrix are, first the position and then the number of repetitions. Only the values that have repetition will be there.

calcula_repetidos()

That is the code

int         kit::calcula_repetidos()
{
    Par res = busca_menor();
    if (res.quantos > 1)
    {   // guarda esse
        *status = res;
        n_repetidos = 1;
    }
    // tenta encontrar algum outro elemento
    // a matriz pode ser constante
    res = busca_menor(*(matriz+ res.posicao));
    while (res.quantos > 0)
    {   
        if (res.quantos > 1)
        {   // guarda esse
            status[n_repetidos] = res;
            n_repetidos += 1;
        }
        int limite = *(matriz + res.posicao);
        res = busca_menor( *(matriz+ res.posicao) );
    };
    return n_repetidos;
};

And the idea is to first identify the least of all in busca_menor() and then while you have some new value go testing in busca_menor(limite) if it repeats itself, using as limit the lowest value ever seen. As I said, it is the algorithm of Selection Sort(), the simplest of all. Check the code and ask if you don’t understand something

5 x 2 test file

1 2
3 4
5 6 
7 8 
9 9 

5 x 5 test file

12 12 2 2 3
3 4 4 5 5 
6 6 7 7 8
8 9 9 21 12 
12 2 3 4 5

the result when rotating main() as above

Lendo matriz 5x2 a partir de entrada.txt
(Testando com 5x2)

Matriz 5x2 lida de "entrada.txt"

         1         2
         3         4
         5         6
         7         8
         9         9

1 elementos repetidos:

9 (2X)

Lendo matriz 5x5 a partir de 55.txt
(Agora 5x5)

Matriz 5x5 lida de "55.txt"

        12        12         2         2         3
         3         4         4         5         5
         6         6         7         7         8
         8         9         9        21        12
        12         2         3         4         5

9 elementos repetidos:

2 (3X)
3 (3X)
4 (3X)
5 (3X)
6 (2X)
7 (2X)
8 (2X)
9 (2X)
12 (4X)

Without great pretensions, it’s just an example and I’ve tested almost nothing.

Here is the code, in a single file that can compile directly

#include "kit.h"
using namespace std;

int         main(void)
{
    kit teste;
    cout << "(Testando com 5x2)\n" << teste << endl;

    kit uma55(5, 5, "55.txt");
    cout << "(Agora 5x5)\n" << uma55 << endl;

    return 0;
}


kit::       kit(int l, int c, const char* nome) :
    C(c), L(l), matriz(nullptr), status(nullptr),
    n_repetidos(0), arquivo(nome), N(l*c)
{
    int res = le(nome);
    if (res < 0)
    {
        cerr << "Erro " << res << " lendo os dados de " << nome << endl;
        return;
    }
    n_repetidos = calcula_repetidos();
};


kit::       ~kit()
{
    delete[] matriz;
    delete[] status;
}


kit::Par    kit::busca_menor()
{
    int menor = 0;
    Par res;
    res.quantos = 1;
    for (int i = 1; i < N; i++)
    {
        if (*(matriz + i) < *(matriz + menor))
        {
            menor = i;
            res.quantos = 1;
        }
        else
        {
            if (*(matriz + i) == *(matriz + menor)) res.quantos++;
        }
    };  // for()
    res.posicao = menor;
    return res;
};


kit::Par    kit::busca_menor(int limite)
{
    Par    res;
    res.quantos = 0;
    int achou = 0;
    int menor = 0;
    for (auto i = 0; i < N; i++)
    {
        if (*(matriz + i) <= limite) continue;
        // ao menos esse maior que  limite
        menor = i;
        achou = 1;
        break;
    };  // for()

    if (achou == 0) return res;
    res.quantos = 1;
    for (auto i = 0; i < N; i++)
    {
        if (*(matriz + i) <= limite) continue;
        if (i == menor) continue;
        if (*(matriz + i) < *(matriz + menor))
        {
            menor = i;
            res.quantos = 1;
        }
        else
        {
            if (*(matriz + i) == *(matriz + menor)) res.quantos++;
        }
    };  // for()
    res.posicao = menor;
    return res;
};


int         kit::calcula_repetidos()
{
    Par res = busca_menor();
    if (res.quantos > 1)
    {   // guarda esse
        *status = res;
        n_repetidos = 1;
    }
    // tenta encontrar algum outro elemento
    // a matriz pode ser constante
    res = busca_menor(*(matriz+ res.posicao));
    while (res.quantos > 0)
    {   
        if (res.quantos > 1)
        {   // guarda esse
            status[n_repetidos] = res;
            n_repetidos += 1;
        }
        int limite = *(matriz + res.posicao);
        res = busca_menor( *(matriz+ res.posicao) );
    };
    return n_repetidos;
};


int         kit::le(string arquivo)
{
    ifstream entra { arquivo };
    istream_iterator<int> in {entra};
    istream_iterator<int> FIM   {};

    if (!entra.good())
    {
        cerr << "Erro tentando abrir " <<
            arquivo << endl;
        return -1;
    }
    // abriu o arquivo, entao aloca os vetores para ler
    size_t tamanho = sizeof(int) * L * C; // o simples
    // pode estar lendo de novo
    if (matriz != nullptr) delete[] matriz;
    if (status != nullptr) delete[] status;
    matriz = new int[tamanho];
    status = new Par[tamanho];

    cerr << "Lendo matriz " << L << "x" << C << 
        " a partir de " << arquivo << "\n";

    for (int i = 0; i < L; i += 1)
        for (int j = 0; j < C; j += 1)
        {
            if (in == FIM)
            {
                cout << "Fim de arquivo inesperado!\n";
                delete[] matriz;
                delete[] status;
                matriz = nullptr;
                return -1;
            };  // if()
            *(matriz + (i * C) + j) = *in++;
        }
    entra.close();
    return L*C; // retorna o total de itens lidos para a matriz
}


ostream& operator<<(ostream& sai, const kit& uma)
{
    cout << "\nMatriz " << uma.L << "x" << uma.C <<
        " lida de \"" << uma.arquivo << "\"\n\n";

    for (int i = 0; i < uma.L; i += 1)
    {
        for (int j = 0; j < uma.C; j += 1)
        {
            cout << setw(10) << *(uma.matriz + (i * uma.C) + j);
        }
        cout << "\n";
    }
    if (uma.n_repetidos < 1)
    {
        cout << "\nSem elementos repetidos\n";
        return sai;
    }
    cout << "\n" << uma.n_repetidos << " elementos repetidos:\n\n";
    for (int i = 0; i < uma.n_repetidos; i += 1)
    {
        cout <<
            uma.matriz[uma.status[i].posicao] << " (" <<
            uma.status[i].quantos << "X)\n";
    }
    return sai;
}

I’m not going to explain the whole show because it’s really boring and I don’t know if you need it, but feel free to ask me anything.

  • Thanks friend, I’ll get your tips and improve here.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.