Traversing a multi array with pointers - c++

for ( j = 0; j < d1; j++ ){
m += j;
for ( i = 0; i < d1*d2; i +=d2){
cout << *(m+i);
}
cout << endl;
}
d1,d2 are array dimensions
and
int* m = new int [d1*d2];
I want to traverse over my array and simply group and print the columns.Can't figure what's wrong with this code.Seems to be working fine untill the 3rd iteration in the following example:
Let's say my input values are 1 2 3 4 5 6 7 8 9
I get:
1 4 7
2 5 8
4 7 (something random)

In
m += j;
you are first incrementing m by 0, then by one, then by 2. If we originally took a copy
int *start = m;
then in the first iteration of the outer loop, we'd have
m == start
in the second,
m == start + 1
in the third
m == start + 3
You'd want m == start + 2 there. Except that you want to keep m in order to delete it at the end, so you shouldn't change m at all but use something like
for ( j = 0; j < d2; j++ ){
for ( i = j; i < d1*d2; i +=d2){
cout << *(m+i);
}
cout << endl;
}

m = &a[0];
for ( j = 0; j < d1; j++ )
{
for ( i = 0; i < d2; i++)
cout << *m++;
cout << endl;
}

Related

How to create array by user input?

I have a C++ problem:
Input an sequence of digit [ 0 - 9 ] and terminated by three 9 consecutivly, print on standard output the number of subsequences consisting of three consecutive equal digits on standard output.
Example: Given the sequence { 1 2 2 2 2 0 0 3 3 3 7 9 9 9 }, the subsequence are identified:
{ 2 2 2}, { 2 2 2 }, { 3 3 3 } .
Therefore, the program should print on standard output the number 3, equal to sequences present.
I try to use an array. My code ended up like this:
int main(){
int i;
int N = 0, A[100];
while( (A[i] && A[i+1] && A[i+2]) != 9 ){
N++;
for( i = 0; i <= N; i++ ){
cout << "A[" << i + 1 << "]:";
cin >> A[i];
}
for(int i = 0; i <= N; i++ ){
cout << "A[" << i + 1 << "]:" << A[i];
}
}
}
My problem is, I have no idea how to terminate the sequence by three 9's consecutively. So I try to use an array. I hope someone can help me to elaborate the idea.
You can do that by breaking the loop when three consecutive 9 is found.
#include <iostream>
const int ARRAY_SIZE = 100;
int main(){
int i;
int N = ARRAY_SIZE, A[ARRAY_SIZE];
for( i = 0; i < ARRAY_SIZE; i++ ){
std::cout << "A[" << i + 1 << "]:";
std::cin >> A[i];
// stop when three consecutive 9 is found
if (i >= 2 && A[i - 2] == 9 && A[i - 1] == 9 && A[i] == 9){
N = i + 1;
break;
}
}
for(int i = 0; i < N; i++ ){
std::cout << "A[" << i + 1 << "]:" << A[i] << '\n';
}
return 0;
}
Instead of an array with the number of elements equal to the magic number 100 what you need is an array of exactly three elements.
Here is a demonstrative program.
#include <iostream>
int main()
{
const size_t N = 3;
int a[N];
size_t count = 0;
for ( size_t i = 0, j = 0; std::cin >> a[j++]; )
{
j %= N;
if ( i != N - 1 )
{
++i;
}
else
{
size_t k = 1;
while ( k < N && a[k] == a[k-1] ) k++;
if ( k == N )
{
if ( a[0] == 9 ) break;
else ++count;
}
}
}
std::cout << "count = " << count << '\n';
return 0;
}
If to enter the sequence of numbers
1 2 2 2 2 0 0 3 3 3 7 9 9 9
then the program output will be
count = 3
instead of the inner while loop you could use for example the algorithm std::all_of.

what is wrong with the logic that i am using?

theres a logic error , for the code i m trying to do ,
*
**
***
**
*
so this is the pattern , what my code is running is this
*
**
***
**
**
**
there seems to be logic error for the printing of stars , i just wanted to know what logic should i use.
heres the code :-
#include<iostream>
using namespace std;
int main()
{
/*
*
**
***
**
*
*/
int i,rows;
cout<<"Enter number of rows :"<<endl;
cin>>rows;
for(i = 1; i <= ((rows/2)+1) ; i++)
{
for(int j = (rows - i); j >= 1; j--)
{
cout<<" ";
}
for(int k = 1; k <= i; k++)
{
cout<<"*";
}
cout<<endl;
}
for(i = ((rows/2)+1) ; i <= rows; i++)
{
for(int j = 1; j <= i; j++)
{
cout<<" ";
}
for(int k = (rows/2); k >= 1; k--)
{
cout<<"*";
}
cout<<endl;
}
return 0;
}
You can change your second loop as follows:
for ( i = ( rows / 2 ); i >= 1; i-- ) {
for ( int j = ( rows - i ); j >= 1; j-- ) {
cout << " ";
}
for ( int k = 1; k <= i; k++ ) {
cout << "*";
}
cout << endl;
}
It reuses the logic from the first loop, but just changes it to go from rows/2 down to 1 (inclusive) instead.
The first loop header also runs too many times for even values. For example, with 4, it does 4 / 2 + 1 which is 3. What you want is below.
for ( i = 1; i <= (int)( rows / 2. + .5 ); i++ )
This effectively rounds. So for 4 you now have 4 / 2. + .5 which is 2.5, then converted to int is 2. With 5, you get 5 / 2. + .5 which is 2.5 + .5 which is 3.0, then to an int is 3
You don't need to initialize i in the second for loop. Just let continue with the next row value after the first loop finishes.
The number of * you print is controlled by the k loop. In the first row loop you print out i of them, while in the second you always print out the same number - rows / 2. You'll want to print out a gradually reducing number of them - rows + 1 - i. Or just use for (int k = i; k <= rows; ++k).

Can't find path in Minimum Cost Path using Dynamic Programming

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)

Swapping 2d array minimum row value with reverse diagonal

I am trying to swap minimum row value with reverse diagonal. I managed to print out every row minimum value, but my swap fails. Maybe you could give me some hints.
for (int i = 0; i < n; i++)
{
int min = mas[i][0];
for (int j = 1; j < m; j++)
{
if (mas[i][j] < min)
{
min = mas[i][j];
}
for(int k=n-1;k>0;k--){
for(int h = m-1; h>0;h--){
min = mas[i][j];
mas[i][j]=mas[k][h];
mas[k][h]=min;
}
cout << "New Matrix\n";
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
cout << mas[i][j] << " ";
}
}
}
}
system("pause");
return EXIT_SUCCESS;
}
This is my for for a minimum value and later I am adding another for to swap values.
My result:
I go printed out 3 matrices and none of them are correctly swapping value. I guess it's because of for in for cycle?
My file with with 2d array:
1 2 5 // row min 1, reverse diagonal 5
2 8 9 // row min 2, reverse diagonal 8
5 9 10 // row min 5, revese diagonal 5
What output I expect:
5 2 1 // 5 diagonal swap with min = 1
8 2 9 // 8 diagonal swap with min = 2
5 9 10 // 5 diagonal no swap because 5 is row minimum
If I understand correctly then the "reverse diagonal" can be present only in a square matrix. So there is no sense to enter two values n and m to deal with a square matrix.
If to consider the example of a 3 x 3 matrix shown in your question and to use loops instead of for example standard functions std::max_element and std::swap then the code that converts the matrix can look the following way as it is shown in the demonstrative program
#include <iostream>
#include <iomanip>
int main()
{
const size_t N = 3;
int a[N][N] =
{
{ 1, 2, 5 },
{ 2, 8, 9 },
{ 5, 9, 10 }
};
for (size_t i = 0; i < N; i++)
{
for (size_t j = 0; j < N; j++)
{
std::cout << std::setw(2) << a[i][j] << ' ';
}
std::cout << '\n';
}
std::cout << std::endl;
for (size_t i = 0; i < N; i++)
{
size_t min = 0;
for (size_t j = 1; j < N; j++)
{
if (a[i][j] < a[i][min]) min = j;
}
if ( min != N - i - 1 )
{
int tmp = a[i][min];
a[i][min] = a[i][N - i - 1];
a[i][N - i - 1] = tmp;
}
}
for (size_t i = 0; i < N; i++)
{
for (size_t j = 0; j < N; j++)
{
std::cout << std::setw(2) << a[i][j] << ' ';
}
std::cout << '\n';
}
std::cout << std::endl;
}
The program output is
1 2 5
2 8 9
5 9 10
5 2 1
8 2 9
5 9 10

For loop with multiple variable

Is it possible for a for loop with 2 variables to stop incrementing only one of the variable when a condition is met ? For example
for(int i = 0, j = 0; i < 5 && j < 10; i++, j++)
{
cout << i << " " << j << endl;
}
and the output would look something like
0 0
1 1
2 2
3 3
4 4
4 5
4 6
4 7
4 8
4 9
This is my actual code. I wanted the condition for both variables
cout << sp.dets.size() << " " << gt.groundtruth.size() << endl;
for (int i = 0, j = 0; i < sp.dets.size() && j < gt.groundtruth.size(); j < gt.groundtruth.size() ? j++ : j, i < sp.dets.size() ? i++ : i)
{
cout << i << " " << j << endl;
}
sp.dets.size = 0
gt.groundtruth.size() = 8
It would be nice if the solution works for any number i.e. i > j or i < j or i = 0 or j = 0
You can use ternary statement to increment variable i value. Like below:
for(int i = 0, j = 0; i < 5 && j < 10; j++, i<4? i++: i)
{
cout << i << " " << j << endl;
}
This will output the expected result.
Something like this may work,
int k = 0;
int val = 4;
for(int i = 0, j = 0; i < 10 && j < 10; i++, j++){
if (i>=val){
k=val;
cout << k << " "<< j << endl;
}
else
cout << i << " " << j << endl;
}
Prints this,
0 0
1 1
2 2
3 3
4 4
4 5
4 6
4 7
4 8
4 9
Don't try to be overly clever by trying to fit all the logic in one line. It't more important that your code can be read by others (and yourself in two weeks' time) than saving a single line. If the incrementing logic of the two variables is more complex than just increasing by one for each loop, put them in seperate lines, like this:
while (i<5 && j<10) {
...
// complicated expression calculating new i
// complicated expression calculating new j
}
In your case, you might also flip the logic around:
for (int i=0; i<max(sp.dets.size(), gt.groundtruth.size(); i++) {
cout << min(i, sp.dets.size()-1)
<< ","
<< min(i, gt.groundtruth.size()-1)
<< endl;
}
You can use ternary operator on both variables. Just be sure to change your condition to break only when both reach their destined value
for (int i = 0, j = 0;
i != 5 || j != 10;)
{
i += i < 5 ? 1 : 0;
j += j < 10 ? 1 : 0;
}
You'll note I moved the increment into the loop body, this improves readability, in my opinion.