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
Related
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
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;
}
The algorithm is supposed to find the minimum cost path in NxN matrix given as an input. The starting cell is always left bottom and the destination is right top.
Each cell of the matrix represents a cost to traverse through that cell.
You can only move up and right.
I have managed to find the cost, however, I still struggle to backtrack the path.
I tried to start from top right cell and use the greedy algorithm to find my "way back", but the output was either completely wrong or skipping random columns/rows. I also tried to keep track of decisions I was making by creating an additional matrix, but I always end up stuck in the loop.
So how do I find the path?
Here's the code that works well (counts the cost and that's it):
#include <iostream>
using namespace std;
int main()
{
int tab[101][101], N, cost[101][101], backtrack[101][101];
cout << "N (size of NxN matrix) :" << endl;
cin >> N;
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
{
cin >> tab[i][j];
cost[i][j] = 0;
backtrack[i][j] = 0;
}
}
cost[N-1][0] = tab[N-1][0];
int a = N-1;
for(int i = N-2; i >= 0; i--) // column 0 can be chosen only in 1 way
{
cost[i][0] = cost[i+1][0] + tab[i][0];
backtrack[i][0] = 4; // came from down
}
for(int j = 1; j < N; j++) // row N-1 can be chosen only in 1 way
{
cost[a][j] = cost[a][j-1] + tab[a][j];
backtrack[a][j] = 3; // came from right
}
for(int i = N-2; i >= 0; i--)
{
for(int j = 1; j < N; j++)
{
if(cost[i][j-1] <= cost[i+1][j])
{
cost[i][j] = tab[i][j] + cost[i][j-1];
backtrack[i][j] = 3;
}
else
{
cost[i][j] = tab[i][j]+cost[i+1][j];
backtrack[i][j] = 4;
}
}
}
cout << "Cost: " << cost[0][a] << endl;
return 0;
}
Now, here's the function with flawed additional matrix that's supposed to give me the path, but ends up in an infinite loop:
(matrix backtrack from previous code was given as track here)
void path(int track[101][101], int N)
{
int help[101][101];
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
help[i][j] = 0;
}
int w = 0, k = N-1;
help[w][k] = 1; // top right argument is included in the output
while(w < N || k >= 0)
{
if(track[w][k] == 3)
{
help[w][k-1] = 1; // 3 means I came from the previous column k-1
k--;
}
else if(track[w][k] == 4)
{
help[w+1][k] = 1; //4 means I came from the previous row w+1
w++;
}
}
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
{
if(help[i][j] != 0)
cout << i << " " << j << endl;
}
}
}
Example input:
5
2 3 4 2 5
5 2 1 2 2
2 4 2 2 3
1 2 2 4 3
3 2 1 2 3
Expected output:
Cost: 20
4 0
4 1
4 2
3 2
2 2
1 2
1 3
0 3
0 4
Actual output
Cost: 20
And no path at all since it ends up in an infinite loop.
You have written the while loop in path() incorrectly:
while(w < N || k >= 0)
...
You intend this loop to continue until w = N-1 and k=0, which it does, but the loop doesn't terminate there, it just runs in place. (You could see this yourself by adding cout << w << " " << k << endl; to the loop.) The conditional I think you want is:
while(w < N-1 || k > 0)
by now I have this code
int main() {
int cols;
cout << "cols";
cin >> cols;
int rows;
cout << "rows";
cin >> rows;
char** charArray = new char*[rows];
for (int i = 0; i < rows; ++i) {
charArray[i] = new char[cols];
}
// Fill the array
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
charArray[i][j] = char('1' + i + j );
}
}
// Output the array
for (int i = 0; i < rows; ++i) {
for (int j = i; j < cols ; ++j) {
cout << charArray[i][j];
}
cout << endl;
}
// Deallocate memory by deleting
for (int i = 0; i < rows; ++i) {
delete[] charArray[i];
}
and the output is like
1 2 3
2 3 4
How can I make it to be
1 2 3
4 5 6
I tried a lot, im a newbie in programming so can you please explain me what's the matter with this problem! Thanks a lot!!
Just change this:
charArray[i][j] = char('1' + i + j );
by:
charArray[i][j] = char('1' + i*cols + j);
BTW:
You have a typo in the output array loop:
for (int j = i; j < cols ; ++j) {
Should be:
for (int j = 0; j < cols ; ++j) {
Array filling loop should be
int count = 0;
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
charArray[i][j] = char('1' +count );
count++;
}
}
try with above code
You are building a matrix, here right. So it's 2-dimensional.
What the output means is that your matrix looks like:
1 2 3
2 3 4
Which is only natural, since, while filling it, you wrote for each element at coordinate i,j to be value 1+i+j. That means if i and j both equal 1 (second line, second column, since index start at 0), you put value the 1+1+1=3.
If you want to get the matrix:
1 2 3
4 5 6
You'll have to fill it with
charArray[i][j] = char('1' + i*ncols + j );
This way when you fill the first line, i = 0, so it's the same.
But then on the second line, i=1, so you get 1 + 3 + 0 = 4. And then 1+3+1=5, etc.
Edit: people are fast here. By the time I write my answer, already 2 others posted theirs :D
I am trying to fill an array of 52 with the numbers 0 - 12. Once it hits 12, it needs to go back to 0 - 12 again. You might have already guessed it's a deck of cards. My code is below and doesn't work. It prints 0 - 12 one time, but then prints the address of the array I believe for the remainder of the iterations left.
#include<iostream>
#include<string>
using namespace std;
int main()
{
int myArray[52];
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < 13; i++)
{
myArray[i] = i;
}
}
for (int k = 0; k < 52; k++)
{
cout << myArray[k] << endl;
}
//system("pause");
return 0;
}
Can someone please help me with this brain fart?
int myints[52];
for (int idx = 0; idx < 52; idx++)
{
myints[idx] = idx % 13;
}
Modulus of 13 will range from 0 to 12.
You're indexing the same first 12 elements of the array in the inner loop for every iteration of the outer loop.
Try changing it to something like this
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < 13; i++)
{
myArray[i + 13 * j] = i;
}
}