(C++) Removing the rows with duplicates in a matrix bug - c++

Remove the rows where a value is encountered twice from the matrix. Where's the bug in my code that I've already written, so that I do it without using any function or anything that would make it easier?
My code:
#include <iostream>
using namespace std;
int main()
{
int v[99][99], m, n, i, j, k, vlinie[99], a=0;
cout<<"m="; cin>>m;
cout<<"n="; cin>>n;
for(i=1; i<=m; i++)
for(j=1; j<=n; j++)
cin>>v[i][j];
//finding out each row that has doubles and remembering its index in an array called vlinie
for(i=1; i<=m; i++)
for(j=1; j<=n-1; j++)
for(k=j+1; k<=n; k++)
if(v[i][j]==v[i][k])
{
a++; //a is the number of numbers in vlinie
vlinie[a]=i;
}
//removing duplicates from vlinie, in case there are any
for(i=1; i<=a-1; i++)
for(j=i+1; j<=a; j++)
if(vlinie[i]==vlinie[j])
for(k=i; k<=m; k++)
{
vlinie[k]=vlinie[k+1];
a--;
}
//this is where we move the rows around, and supposedly the line where i got it wrong, so what do i change in this line?
for(i=1; i<=a; i++)
for(j=1; j<=n; j++)
for(k=vlinie[i]; k<=m; k++)
v[vlinie[i]+k][j]=v[vlinie[i]+k+1][j];
for(i=1; i<=m; i++)
{
cout<<endl;
for(j=1; j<=n; j++)
cout<<v[i][j]<<" ";
}
return 0;
}
Example:
1 2 2 3
4 5 6 7
7 7 8 9
7 6 5 4
What it should output:
4 5 6 7
7 6 5 4
0 0 0 0
0 0 0 0 (without the zeros theoretically but the way i wrote it leaves it like this, for now)
What it outputs instead:
1 2 2 3
7 7 8 9
5 4 3 2 (it didn't delete the lines that it should delete and instead deleted some line it should keep)
How do I fix this?
PS: yes, i know i shouldn't have started my indexing at 1 instead of 0, no need to remind me about it again

Your problem was at these lines :
for(i=1; i<=a; i++)
for(j=1; j<=n; j++)
for(k=vlinie[i]; k<=m; k++)
v[vlinie[i]+k][j]=v[vlinie[i]+k+1][j];
There is a first issue with the indices: we should copy v[k+1][] to v[k][].
The second issue is that once a first move has been performed, the table vlinie is no longer valid.
This last point is not so easy to correct.
Moreover, for each suppressed row, you are implementing a shift of several rows, which leads to a poor efficiency.
It is simpler and more efficient to memorize which rows are suppressed (suppress[]) and from this table, to determine which row of the input matrix will end at the ith row of the final matrix (table posi[]).
Hereafter is an example of implementation.
#include <iostream>
int main()
{
int v[99][99], m, n, i, j, k, posi[99];
bool suppress[99];
std::cout << "m = "; std::cin >> m;
std::cout << "n = "; std::cin >> n;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
std::cin >> v[i][j];
//finding out each row that has doubles
for (i = 0; i < m; i++) {
suppress[i] = false;
for (j = 0; (j < n-1) && !suppress[i]; j++)
for (k = j+1; (k < n) && !suppress[i]; k++)
suppress[i] = (v[i][j] == v[i][k]);
}
// determination of the moves to be performed
int n_keep = 0;
for (i = 0; i < m; i++) {
if (!suppress[i])
posi[n_keep++] = i;
}
//this is where we move the rows around
for (i = 0; i < n_keep; i++)
for (j = 0; j < n; j++)
v[i][j] = v[posi[i]][j];
// Set to 0 remaining rows
for (i = n_keep; i < m; i++)
for (j = 0; j < n; j++)
v[i][j] = 0;
for(i = 0; i < m; i++)
{
std::cout << "\n";
for(j = 0; j < n; j++)
std::cout << v[i][j] << " ";
}
return 0;
}

Related

C++ while loop v[i++] vs i++ in while body

I have a question about iterating in a while loop. So let's say we have a vector with size 10 and elements are from 0-9. We have a for loop that just iterates once and within the for loop we have the while loop. I am getting two different results when I print the loop and I'm unsure why.
I understand the idea behind the first loop where we increment j in the body of the while and we don't enter the loop on the last iteration since j is 5 so we only print 0-4.
The second loop is where I'm having issues with understanding. My logic is first we increment the pointer j to 1 so that's why we cout 1 instead of 0. But once j is 4 v[j++] = 5 and in the condition in the loop breaks when v[j++] = 5 so why do we cout 5 still?
Any help is appreciated.
vector<int> v(10);
for(int i = 0; i < v.size(); i++){
v[i] = i;
}
int j = 0;
for(int i = 0; i < 1; i++){ // first loop
while(v[j] != 5){
cout << v[j]; //prints 0 1 2 3 4
j++;
}
}
for(int i = 0; i < 1; i++){ //second loop
while(v[j++] != 5){
cout << v[j]; //prints 1 2 3 4 5
}
}
j++ will increment the value of j but return the original value of j before being incremented.
int i =0;
int j = 0;
i = 1;
j = i++;
(i is 2, j is 1)
Source
As it is said above, j++ will increment the j
so when j is 3, v[j++] is 4 so condition in while is not broken. But because of j++, when cout is executed j is 4 and v[4] is 5 so 5 gets printed
The postfix increment conceptually copies the operand in memory, increments the original operand, and finally yields the value of the copy.
The below snippet is fairly straightforward. The j has been incremented after printing the content of the vector.
vector<int> v(10);
for(int i = 0; i < v.size(); i++){
v[i] = i;
}
int j = 0;
for(int i = 0; i < 1; i++){ // first loop
while(v[j] != 5){
cout << v[j]; //prints 0 1 2 3 4
j++;
}
}
Now, let's take the look at the 2nd loop.
vector<int> v(10);
for(int i = 0; i < v.size(); i++){
v[i] = i;
}
int j = 0;
for(int i = 0; i < 1; i++){ // second loop
// values of j are 0 1 2 3 4
while(v[j++] != 5){
// values of j are 1 2 3 4 5 because it has been incremented
cout << v[j]; //prints 1 2 3 4 5
}
}
You forgot to reinitialize j after a the first loop. If you want to print from 1 to 5 in the second loop, then you should reinitialize j as 0 before the second loop runs. Try:
vector<int> v(10);
for (int i = 0; i < v.size(); i++) {
v[i] = i;
}
int j = 0;
for (int i = 0; i < 1; i++) { // first loop
while (v[j] != 5) {
cout << v[j]; //prints 0 1 2 3 4
j++;
}
}
j = 0;
for (int i = 0; i < 1; i++) { //second loop
while (v[j++] != 5) {
cout << v[j]; //prints 1 2 3 4 5
}
}
using a single for loop will help understand the code better since both conditions are same for the loop.
vector<int> v(10);
for (int i = 0; i < v.size(); i++) {
v[i] = i;
}
int j = 0;
for (int i = 0; i < 1; i++) { // first loop
while (v[j] != 5) {
cout << v[j]; //prints 0 1 2 3 4
j++;
}
// joined the end of the first loop and the start of the second loop
j = 0;
while (v[j++] != 5) {
cout << v[j]; //prints 1 2 3 4 5
}
}
Hope it will help in answering your question

Finding min and max elements of every column and row in a matrix C++

I was trying to do the following:
Have a matrix, print the entire thing out, print at end of every row the biggest element of said row and print at the bottom of every column the smallest element of said column.
I'm pretty much a beginner at C++.
So here's what I've done so far:
#include <iostream>
#include <iomanip>
#define M 50
#define N 50
using namespace std;
int main()
{
int m,n;
int a[M][N];
int b[M],c[N];
do {
cout<<"m=";
cin>>m;
cout<<endl<<"n=";
cin>>n;
cout<<endl;
}
while(m!=n);
for(int i=0;i<m; i++) {
for(int j=0; j<n; j++){
cout<<"a["<<i<<"]["<<j<<"]=";
cin>>a[i][j];
}
}
int max_row;
max_row=0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (a[i][j] > max_row) {
max_row = a[i][j];
b[i] = max_row;
}
}
}
for (int i=0; i<m; i++)
{ for(int j=0; j<n; j++){
cout<<setw(3)<<a[i][j]<<"\t";
}
cout<<"|"<<b[i];
cout<<endl;
}
for(int i=0; i<m; i++){
cout<<setw(3)<<"-";}
cout<<endl;
for(int j=0; j<n; j++)
{cout<<c[j]<<"\t";
}
system("pause");
}
Most of the time the max_row are the correct ones such as this case:
3 2 1 |3
4 6 5 |6
7 8 9 |9
Other times they get messed up and it goes like this:
1 2 3 |3
4 33 6 |33
7 8 9 |-858993460
I really have no idea what causes it and since there are no error messages I got really confused. Also I have no idea how to make the min column ones. Any help would be appreciated.
The problem with these loops
max_row=0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (a[i][j] > max_row) {
max_row = a[i][j];
b[i] = max_row;
}
}
}
is that the value of max_row should be initialized with each iteration of the outer loop. Otherwise all rows after the first row deal with the maximum value of the previous row and in general can not have en element that is greater than the current value of max_row. So the corresponding element of the array b will not be initialized.
Also the user can enter for the matrix negative values in this case your program will output zeroes instead of maximum values.
To find maximum elements in rows and minimum elements in columns it is enough to have one pair of nested loops/
Here is a demonstrative program/
#include <iostream>
#include <iomanip>
int main()
{
const size_t N = 3;
int a[N][N] =
{
{ 1, 2, 3 },
{ 4, 33, 6 },
{ 7, 8, 9 }
};
int b[N], c[N];
for ( size_t i = 0; i < N; i++ )
{
b[i] = a[i][0];
c[i] = a[0][i];
for ( size_t j = 1; j < N; j++ )
{
if ( b[i] < a[i][j] ) b[i] = a[i][j];
if ( a[j][i] < c[i] ) c[i] = a[j][i];
}
}
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ )
{
std::cout << std::setw( 3 ) << a[i][j] << '\t';
}
std::cout << '|' << b[i] << '\n';
}
for ( size_t i = 0; i < N; i++ )
{
std::cout << std::setw( 3 ) << '-' << '\t';
}
std::cout << '\n';
for ( size_t i = 0; i < N; i++ )
{
std::cout << std::setw( 3 ) << c[i] << '\t';
}
std::cout << '\n';
return 0;
}
Its output is
1 2 3 |3
4 33 6 |33
7 8 9 |9
- - -
1 2 3

I want to delete a row from a matrix

I'm beginner in c++, and I want to make a program that delete a row from a matrix.. Like, If I say 3 3 2
1 2 3 it need to show 1 2 3
4 5 6 7 8 9
7 8 9
The program works like this: 3 = rows, 3 = columns, 2 = the deleted row. "3 3 2" is not a row...
I wrote this :
#include <iostream>
using namespace std;
int main() {
int N, M, v[100][100];
cin>>N>>M;
int i,j,p;
cin>>p;
for (i = 1; i <= N; ++i)
for (j = 1; j <= M; ++j)
cin>>v[i][j];
for (i = 1; i <= N; ++i) {
for (j = 1; j <= M; ++j)
cout<<v[i][j]<<" ";
cout<<"\n";
}
for (i = p; i < N; ++i)
v[i][j]=v[i+1][j];
--N;
for (i = 1; i <= N; ++i){
for (j = 1; j <= N; ++j)
cout<<v[i][j]<<' ';
cout<<"\n";
}
return 0;
}
But it doesn't work.... Can someone help me?
modified code (it will work fine ):
#include <iostream>
using namespace std;
int main()
{
int N, M, v[100][100];
cin>>N>>M;
int i,j,p;
cin>>p;
for (i = 1; i <= N; ++i)
for (j = 1; j <= M; ++j)
cin>>v[i][j];
for (i = 1; i <= N; ++i)
{
for (j = 1; j <= M; ++j)
cout<<v[i][j]<<" ";
cout<<"\n";
}
for (i = p; i < N; ++i)
for(j=1; j<=M; ++j)
v[i][j]=v[i+1][j];
--N;
for (i = 1; i <= N; ++i)
{
for (j = 1; j <= M; ++j)
cout<<v[i][j]<<' ';
cout<<"\n";
}
return 0;
}
This doesn't work, what do you think j is doing in this code?
for (i = p; i < N; ++i)
v[i][j]=v[i+1][j];
--N;
You need to loop over rows and columns. Copy each column in every row greater that the row you want to delete. In other words you need nested loops here
for (i = p; i < N; ++i)
for (j = 1; j <= M; ++j)
v[i][j] = v[i+1][j];
--N;
You should use vector
#include <vector>
#include <iostream>
using namespace std;
int main()
{
//matrix
vector< vector<int> > V;
//To Add
for(int i=0; i<100; i++)
{
vector<int> R;
for(int j=0; j<100; j++)
{
int x;
cin>>x;
R.push_back(x);
}
V.push_back(R);
}
//To delete a row
int row_to_delete = 2;
V.erase(V.begin() + row_to_delete);
//To access
for(int i=0; i<V.size(); i++)
{
for(int j=0; j<V[i].size(); j++)
{
cout<<V[i][j];
}
}
}
vector<T> is class that use a template to create a dynamic array.
vector<int> is a var array int. V.push_back(T) you can add a element to array with type T, and with V.erase(V.begin() + int ) you can delete a element to array in this case a row. With V.size() you can take a elements count inside the array.

looping matrix ordo 4X4

i have problem with code,where i can't looping data in c++.
so here my code:
int j,i;
int matriks[5][5];
for(i=0; i<5; i++)
{
for(j=0; j<5; j++)
matriks[i][j]=j;
}
for(i=1; i<5; i++)
{
for(j=1; j<5; j++)
cout<<matriks[i][j]<<" ";
cout<<endl;
getch();
}
the code above only shows
1 2 3 4
i want output like this:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
where is wrong code,how to create looping matrix ordo 4x4?
Try this code; I did not compile or test, but it looks like what you are trying to achieve.
int matrix[5][5];
for (int i = 0, k = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
matrix[i][j] = k++;
}
}
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}

Block Matrix Transpose

I wanted to implement transposition of a matrix by dividing the input matrix into blocks and then transposing them. I referred to the corresponding post A Cache Efficient Matrix Transpose Program? and wrote my code like this:
#include<iostream>
#include<stdlib.h>
#define m 4
#include<sys/time.h>
#include<time.h>
#include<malloc.h>
using namespace std;
int **a, **b, **c;
int count = 0;
clock_t t1, t2;
int blocksize = 2;
int main(){
a = (int **)malloc(m*sizeof(int *));
for(int i = 0;i<m;i++){
a[i] = (int *)malloc(m*sizeof(int));
}
b = (int **)malloc(m*sizeof(int *));
for(int i = 0;i<m;i++){
b[i] = (int *)malloc(m*sizeof(int));
}
for(int i=0; i<m; i++){
for(int j =0; j<m; j++){
a[i][j]=(2*i)+(3*j);
}
}
for(int i=0; i<m; i++){
for(int j =0; j<m; j++){
cout << a[i][j] << "\t";
}
cout << "\n";
}
cout << "\n";
t1 = clock();
// MAIN BLOCK TRANSPOSE CODE
for (int i = 0; i < m; i += blocksize) {
for (int j = 0; j < m; j += blocksize) {
for (int k = i; k < i + blocksize; ++k) {
for (int l = j; l < j + blocksize; ++l) {
b[k + l*m] = a[l + k*m];
}
}
}
}
t2 = clock();
for(int i=0; i<m; i++){
for(int j =0; j<m; j++){
cout << b[i][j] << "\t";
}
cout << "\n";
}
free(a);
free(b);
cout << "\n";
cout << (double)(t2-t1)/CLOCKS_PER_SEC << "\n";
return 0;
}
However, the code is not working as expected. I implemented the code that is said to be working in the corresponding post. Please help if possible.
Input Array:
0 3 6 9
2 5 8 11
4 7 10 13
6 9 12 15
Expected Output Array:
0 2 4 6
3 5 7 9
6 8 10 12
9 11 13 15
Obtained Result:
0 3 6 9
Segmentation fault
I think your matrix is supposed to be encoded in a single array, not in an array of arrays (See the Edit 2 of the linked question).
You might want to try that instead:
int *a, *b, *c;
a = (int *)malloc(m*m*sizeof(int));
b = (int *)malloc(m*m*sizeof(int));
for(int i=0; i<m; i++){
for(int j =0; j<m; j++){
a[i*m+j]=(2*i)+(3*j);
}
}
for(int i=0; i<m; i++){
for(int j =0; j<m; j++){
cout << a[i*m+j] << "\t";
}
cout << "\n";
}
cout << "\n";