I wanted to ask you for help with this project based on functions, where I have to fill an array with random numbers of 1 and 2, then I have to type the row and column where the value to pass to 0 is located and both the values that are equal to the left and right must be eliminated I put an example.
2 1 2 1 2 1
2 1 2 2 2 1
Then suppose that when typing the row and column of 2 in bold I must delete both the two on the left and the 2 on the right but without touching the first 2 of row 2 of the matrix, so to speak, it would be an elimination only by blocks, Despite the fact that the first 2 of the second row is a repeated value, I cannot pass it to 0 since I can only delete by blocks.
Then I must move that block to the beginning of the row already past 0 and the others to the right of that block, so it would look like this:
2 1 2 1 2 1
0 0 0 2 1 1
So the offset would look like this.
#include <iostream>
using namespace std;
//prototipos de las funciones y sus variables para trabajar en ellas
//se necesitan las matrices, y dos variables de tipo int para las filas y columnas
void mostrarMatriz(int[][9],int,int);
int numeroaleatorio();
void llenarMatriz(int[][9],int,int);
void crearMatrizcopia(int[][9],int[][9],int,int);
void imprimirMatrizcopia(int[][9],int,int);
void rangocalculado(int[][9],int);
void eliminarbloque(int[][9],int);
int main(){
int Matriz[9][9];//matriz original
int Matrizcopia[9][9];//copia de la matriz original
llenarMatriz(Matriz,9,9);
mostrarMatriz(Matriz,9,9);
crearMatrizcopia(Matrizcopia,Matriz,9,9);
imprimirMatrizcopia(Matrizcopia,9,9);
rangocalculado(Matrizcopia,9,9);
return 0;
}
int numeroaleatorio(){
int aleatorio;
aleatorio = 1 + rand() % 2;//
return aleatorio;
}
void llenarMatriz(int Matriz[9][9],int filas,int columnas){
int aleatorio;
for(int i=0 ; i<filas; i++){
for(int j=0;j<columnas; j++){
aleatorio = numeroaleatorio();
Matriz[i][j] = aleatorio;
}
}
}
void mostrarMatriz(int Matriz[9][9],int filas,int columnas){
cout<<"Matriz Original"<<endl;
cout<<endl;
for(int i=0 ; i<filas; i++){
for(int j=0;j<columnas; j++){
cout<<Matriz[i][j]<<" ";
}
cout<<endl;
}
}
void crearMatrizcopia(int Matrizcopia[9][9],int Matriz[9][9],int filas, int columnas){
for(int i=0 ; i<filas; i++){
for(int j=0;j<columnas; j++){
Matrizcopia[i][j] = Matriz[i][j];//pasar datos de la matriz original a la copia
}
}
}
void imprimirMatrizcopia(int Matrizcopia[9][9],int filas, int columnas){
cout<<endl;
cout<<"Matriz Copia"<<endl;
cout<<endl;
for(int i=0 ; i<filas; i++){
for(int j=0;j<columnas; j++){
cout<<Matrizcopia[i][j]<<" ";
}
cout<<endl;
}
}
void rangocalculado(int Matrizcopia[9][9],int fc ){
do{
cout << "Insertar la fila-columna a eliminar :";
cin >> fc;
} while (fc <= 0 );
eliminarbloque(Matrizcopia,9,9);
}
void eliminarbloque(int Matrizcopia[9][9],int fc){
Matrizcopia[fc / 10][fc % 10] = 0;
}
First of all, your arrays are fixed in size, you don't need to be passing all the functions the dimensions of the array.
A better solution is to declare two constant values and use them directly wherever we need them. This solution allows you to easily change the size of the array:
On the other hand, check the function calls because your code doesn't even compile. Declarations have some parameters and implementations have different ones.
Note, for example, that the function
rangocalculado
should not receive the parameterfc
since that should be a local variable of the function.Now dealing with your problem, you are going to work by rows, so, to avoid too much redundancy, we can take the pointer to the row:
And then, already, dealing with the problem, the first thing you can do is make a copy of the value to delete
You can use this number to calculate the range of columns to remove:
And finally it's time to set the values to 0 and move them to the origin of the row
My first advice in this regard is that you put your batteries. Nobody from this portal is going to sit next to you in the exam and, honestly, that change is so trivial that in other situations I wouldn't even have answered you.
If you want the algorithm to only work when there are 2 or more matches, just compare
inicio
andfin
If you're wondering where you should put that, I'm not going to be that explicit, but here's a hint: if
fin==inicio
then you shouldn't move or replace any valuesFirst of all, you have to clarify your concept of " remove from an array "; it is not possible to remove data from an array as its data size is invariant. You mean that storing a zero (
0
) in the array is equivalent to having no data; but that's not delete , that's a convention.Your whole algorithm can be summed up in two steps to be applied on sequences of data (in your case matrix rows):
For the first step, you can use
std::search_n
the header function<algorithm>
:The above code shows the following output :
As for the second step, you can use the function
std::sort
from the same header, but passing a lambda that uses the fact that the value is zero as a criteria to order:The above code shows the following output :
With this we have the ingredients for what you need:
In each row the blocks of numbers are searched
2
and replaced by zeros, we start searching from big blocks to small ones because (obviously) the small blocks are contained in the big ones.I have obtained the following result :