Need help understanding some parts of "15 Puzzle Game" in C++ [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I was reading the code of "15 Puzzle Game" implemented in C++ (Link).
Code
#include <time.h>
#include <stdlib.h>
#include <vector>
#include <string>
#include <iostream>
class p15 {
public :
void play() {
bool p = true;
std::string a;
while( p ) {
createBrd();
while( !isDone() ) { drawBrd();getMove(); }
drawBrd();
std::cout << "\n\nCongratulations!\nPlay again (Y/N)?";
std::cin >> a; if( a != "Y" && a != "y" ) break;
}
}
private:
void createBrd() {
int i = 1; std::vector<int> v;
for( ; i < 16; i++ ) { brd[i - 1] = i; }
brd[15] = 0; x = y = 3;
for( i = 0; i < 1000; i++ ) {
getCandidates( v );
move( v[rand() % v.size()] );
v.clear();
}
}
void move( int d ) {
int t = x + y * 4;
switch( d ) {
case 1: y--; break;
case 2: x++; break;
case 4: y++; break;
case 8: x--;
}
brd[t] = brd[x + y * 4];
brd[x + y * 4] = 0;
}
void getCandidates( std::vector<int>& v ) {
if( x < 3 ) v.push_back( 2 ); if( x > 0 ) v.push_back( 8 );
if( y < 3 ) v.push_back( 4 ); if( y > 0 ) v.push_back( 1 );
}
void drawBrd() {
int r; std::cout << "\n\n";
for( int y = 0; y < 4; y++ ) {
std::cout << "+----+----+----+----+\n";
for( int x = 0; x < 4; x++ ) {
r = brd[x + y * 4];
std::cout << "| ";
if( r < 10 ) std::cout << " ";
if( !r ) std::cout << " ";
else std::cout << r << " ";
}
std::cout << "|\n";
}
std::cout << "+----+----+----+----+\n";
}
void getMove() {
std::vector<int> v; getCandidates( v );
std::vector<int> p; getTiles( p, v ); unsigned int i;
while( true ) {
std::cout << "\nPossible moves: ";
for( i = 0; i < p.size(); i++ ) std::cout << p[i] << " ";
int z; std::cin >> z;
for( i = 0; i < p.size(); i++ )
if( z == p[i] ) { move( v[i] ); return; }
}
}
void getTiles( std::vector<int>& p, std::vector<int>& v ) {
for( unsigned int t = 0; t < v.size(); t++ ) {
int xx = x, yy = y;
switch( v[t] ) {
case 1: yy--; break;
case 2: xx++; break;
case 4: yy++; break;
case 8: xx--;
}
p.push_back( brd[xx + yy * 4] );
}
}
bool isDone() {
for( int i = 0; i < 15; i++ ) {
if( brd[i] != i + 1 ) return false;
}
return true;
}
int brd[16], x, y;
};
int main( int argc, char* argv[] ) {
srand( ( unsigned )time( 0 ) );
p15 p; p.play(); return 0;
}
/*
Possible Output:
+----+----+----+----+
| 11 | 5 | 12 | 3 |
+----+----+----+----+
| 10 | 7 | 6 | 4 |
+----+----+----+----+
| 13 | | 2 | 1 |
+----+----+----+----+
| 15 | 14 | 8 | 9 |
+----+----+----+----+
Possible moves: 2 13 14 7
*/
While I understood most of the code, some parts seemed unclear to me:
A. Why does the for loop iterate a 1000 times? Why is the number 1000 chosen?
for( i = 0; i < 1000; i++ )
B. In the above loop, why is v.clear(); called once in every iteration?
C. What is the significance of the numbers 1, 2, 4 and 8 in the code (used in the switch blocks)?
D. How does the getCandidates() function work?

A. The board is being shuffled, so 1000 means 'a lot, but not that much that you really have to start waiting for the board being shuffled'
B. getCandidates() returns the candidates by filling them in the vector, v.clear() resets the vector for new candidates.
C. Here 1,2,4,8 just means up,down,left,right (not in particular order). This is filled in by getCandidate(). There seem to be no reason for these specific values, they could be used as bits in an byte, but that doesn't seem to be the case here.
D. getCandidate() fills up,down,left,right in a vector based on whether the empty spot is near which border.

Related

Random matrix multiplication [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 months ago.
Improve this question
I need to create at least 2 matrix 4x4, multiplicate them and display the result, but I'm getting this thing as as result img
I'm creating matrix a[i][j] and matrix b[k][l], and trying to pass the result to a new matrix called c[i][j]
Besides that, I need to make 2 kinds of matrix multiplication, one like this, and another one like this
Can you please please please help? Code below
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
int matriz1() {
int a[4][4], i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
a[i][j] = rand() % 100 + 1;
}
}
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
std::cout << a[i][j] << '\t';
std::cout << '\n';
}
std::cout << '\n';
std::cout << "x" << std::endl;
std::cout << '\n';
std::cout << "Matriz 2:" << std::endl;
int b[4][4], k, l;
for (k = 0; k < 4; ++k)
{
for (l = 0; l < 4; ++l)
{
b[k][l] = rand() % 100 + 1;
}
}
for (k = 0; k < 4; ++k)
{
for (l = 0; l < 4; ++l)
std::cout << b[k][l] << '\t';
std::cout << '\n';
}
std::cout << '\n';
int c[4][4], m, n, x;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
for (k = 0; k < 4; k++) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
cout << " RESULTADO!!!!!!!!!!!!!!!!!!!!!!" << endl;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
cout << c[i][j] << "\t";
}
cout << "\n";
}
return 0;
}
int main()
{
srand(time(0));
std::cout << "Matriz 1:" << std::endl;
std::cout << matriz1() << std::endl;
}
SOLVED IN THE COMMENTS! Stop disliking my post its my first post
You do this:
c[i][j] += a[i][k] * b[k][j];
but you never initialized c array, it contains random values, likely something like
0xCDCDCDCD (-842150451). Initialize it like this:
int c[4][4] = {}
You have repeated code, so consider to break it up in functions, e.g. you can initialize matrices as functions and output one as another. THat would make code more readable and easier to find errors.
A common "Beginner's Problem" is writing too much code. One consequence is that there are too many places where bugs and other flaws can hide.
This is in 'C', but the only 'C++' aspect of your code is using cout for output. printf() can also be used with C++.
#include <stdio.h>
#include <stdlib.h>
void fill4x4( int a[][4] ) {
for( int r = 0; r < 4; r++ )
for( int c = 0; c < 4; c++ )
a[r][c] = rand() % 100 + 1;
}
void show4x4( int a[][4] ) {
for( int r = 0; r < 4; r++ )
for( int c = 0; c < 4; c++ )
printf( "%5d%c", a[r][c], " \n"[c] );
puts( "" );
}
int showPair( int a, int b, int pos ) {
printf( "%2dx%-2d%c", a, b, " \n"[pos] );
return a * b;
}
void mult4x4( int a[][4], int b[][4], int d[][4], bool x ) {
for( int r = 0; r < 4; r++ )
for( int c = 0; c < 4; c++ )
// assign (=), not accumulate (+=)
// notice the 'exchange' of row/col access of 'b[][]'
if( x )
d[r][c] = showPair( a[r][c], b[r][c], c );
else
d[r][c] = showPair( a[r][c], b[c][r], c );
puts( "" ); show4x4( d );
}
int main()
{
srand(time(0));
int a[4][4]; fill4x4( a ); show4x4( a );
int b[4][4]; fill4x4( b ); show4x4( b );
int d[4][4];
mult4x4( a, b, d, true );
mult4x4( a, b, d, false );
return 0;
}
Copy, paste, compile and run this to see the (random) output.
EDIT: Pointed out by a question from the OP, here's a further compaction of one function that may-or-may-not be self-evident:
void mult4x4( int a[][4], int b[][4], int d[][4], bool x ) {
for( int r = 0; r < 4; r++ )
for( int c = 0; c < 4; c++ )
d[r][c] = showPair( a[r][c], x?b[r][c]:b[c][r], c );
puts( "" ); show4x4( d );
}
Further EDIT: A common problem for those with time to fill is mucking around, shrinking code that already works. Here's the result of some of that..
#include <stdio.h>
#include <stdlib.h>
char *fmt1 = "%5d%.2s";
char *fmt2 = "%2dx%-2d%.2s";
char *tail1 = " ::";
char *tail2 = " \n";
void show2x4x4( int a[][4], int b[][4] ) {
for( int r = 0, c; r < 4; r++ ) {
for( c = 0; c < 4; c++ ) printf( fmt1, a[r][c], &tail1[c+c] );
for( c = 0; c < 4; c++ ) printf( fmt1, b[r][c], &tail2[c+c] );
}
puts( "" );
}
int main() {
srand(time(0));
int r, c, v, a[4][4], b[4][4], d[4][4], e[4][4], *px, *py;
// fill 2 4x4 arrays of random ints as if both were 1x16
for( px = &a[0][0], py = &b[0][0], v = 0; v < 4 * 4; v++ ) {
int num = rand();
*px++ = num % 100; // two digits only
*py++ = num / 100 % 100;
}
show2x4x4( a, b ); // display
// show and perform the calc of the product matrices
for( r = 0; r < 4; r++ ) {
for( c = 0; c < 4; c++ ) {
printf( fmt2, a[r][c], b[r][c], &tail1[c+c] );
d[r][c] = a[r][c] * b[r][c];
}
for( c = 0; c < 4; c++ ) { // note b[] swaps col & row
printf( fmt2, a[r][c], b[c][r], &tail2[c+c] );
e[r][c] = a[r][c] * b[c][r];
}
}
puts( "" );
show2x4x4( d, e ); // show both products
return 0;
}
Output
29 66 71 20 : 35 88 22 22
35 80 36 85 : 53 1 28 54
12 14 12 71 : 95 98 92 19
62 61 89 17 : 94 63 32 43
29x35 66x88 71x22 20x22 :29x35 66x53 71x95 20x94
35x53 80x1 36x28 85x54 :35x88 80x1 36x98 85x63
12x95 14x98 12x92 71x19 :12x22 14x28 12x92 71x32
62x94 61x63 89x32 17x43 :62x22 61x54 89x19 17x43
1015 5808 1562 440 : 1015 3498 6745 1880
1855 80 1008 4590 : 3080 80 3528 5355
1140 1372 1104 1349 : 264 392 1104 2272
5828 3843 2848 731 : 1364 3294 1691 731

How to solve the problem that program works in the same way in case of negative numbers? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
As a result, the program must display the 3 largest elements of the sequence. Elements must be displayed from small to large and not using array...
Examples
Input:
3 1 2 3
Work result:
1 2 3
Input:
5 2 -4 16 0 15
Work result:
2 15 16
Input:
3 0 -1 -2
Work result:
-2 -1 0
Here is my code:
#include <iostream>
int main() {
int n;
std::cin >> n;
int number;
std::cin >> number;
int max1, max2, max3;
max1 = max2 = max3 = number;
for (int i = 1; i < n; i++) {
std::cin >> number;
if (number > max3) {
if (number > max2) {
if (number > max1) {
max3 = max2;
max2 = max1;
max1 = number;
} else {
max2 = number;
}
} else {
max3 = number;
}
}
}
std::cout << max3 << " " << max2 << " " << max1;
}
I'd use standard algorithms to keep it as simple as possible.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
int main() {
std::vector<std::vector<int>> tests{
{5, 2, -4, 16, 0, 15},
{3, 0, -1, -2}
};
for(auto& test : tests) {
// sort the vector to get the three largest last
std::sort(test.begin(), test.end());
// create an iterator 3 steps back from the end
// (or less if the vector doesn't have 3 elements)
auto first = std::prev(test.cend(), std::min(test.size(), static_cast<size_t>(3)));
// copy to std::cout
std::copy(first, test.cend(), std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
}
}
Output:
5 15 16
-1 0 3
A slightly more complicated way involves partially sorting the vector. This makes it more effective since you only need 3 elements sorted.
std::partial_sort puts the smallest elements first so we need to sort it in decending order (using std::greater<>).
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
int main() {
std::vector<std::vector<int>> tests{
{5, 2, -4, 16, 0, 15},
{3, 0, -1, -2}
};
for(auto& test : tests) {
// calculate how many elements to show, 0-3
auto elems = std::min(test.size(), static_cast<size_t>(3));
// sort "elems" elements in decending order
std::partial_sort(
test.begin(),
std::next(test.begin(), elems),
test.end(),
std::greater<>()
);
// copy the result to std::out, in reverse order since they are sorted "backwards"
std::copy(
std::prev(test.crend(), elems),
test.crend(),
std::ostream_iterator<int>(std::cout, " ")
);
std::cout << '\n';
}
}
My five cents.:)
#include <iostream>
#include <utility>
int main()
{
size_t n = 0;
int max1, max2, max3;
std::cin >> n;
size_t i = 0;
for ( int number; n-- && std::cin >> number; i = i < 3 ? i + 1 : i )
{
if ( i == 0 )
{
max3 = number;
}
else
{
if ( max3 < number )
{
std::swap( max3, number );
}
if ( i == 1 )
{
max2 = number;
}
else
{
if ( max2 < number )
{
std::swap( max2, number );
}
if ( i == 2 || max1 < number )
{
max1 = number;
}
}
}
}
if ( i > 0 )
{
std::cout << max3;
}
if ( i > 1 )
{
std::cout << ", " << max2;
}
if ( i > 2 )
{
std::cout << ", " << max1;
}
std::cout << '\n';
return 0;
}
If to enter
6
5 2 -4 16 0 15
then the output is
16, 15, 5
If to enter
6
-5 -2 4 -16 0 -15
then the output is
4, 0, -2
Or if to enter
4
3 0 -1 -2
then the program output is
3, 0, -1
Pay attention to that in general the user can enter less than 3 numbers.:)
The solution above allows duplicated maximum values.
If it is required that maximum values shall not be repeated then the program can look the following way.
#include <iostream>
#include <utility>
int main()
{
size_t n = 0;
int max1, max2, max3;
std::cin >> n;
size_t i = 0;
for ( int number; n-- && std::cin >> number; )
{
if ( i == 0 )
{
max3 = number;
i = 1;
}
else
{
if ( max3 < number )
{
std::swap( max3, number );
}
if ( number < max3 )
{
if ( i == 1 )
{
max2 = number;
i = 2;
}
else
{
if ( max2 < number )
{
std::swap( max2, number );
}
if ( number < max2 )
{
if ( i == 2 || max1 < number )
{
max1 = number;
i = 3;
}
}
}
}
}
}
if ( i > 0 )
{
std::cout << max3;
}
if ( i > 1 )
{
std::cout << ", " << max2;
}
if ( i > 2 )
{
std::cout << ", " << max1;
}
std::cout << '\n';
return 0;
}
For example if to enter
5
-1 -1 -1 -1 -1
where all numbers are equal each other then the output will contaoin onky one maximum number
-1
If to use standard containers then the standard container std::set is the most appropriate container.
For example
#include <iostream>
#include <set>
#include <iterator>
#include <algorithm>
int main()
{
size_t n = 0;
std::set<int> set;
std::cin >> n;
std::copy_n( std::istream_iterator<int>( std::cin ), n,
std::inserter( set, std::end( set ) ) );
size_t i = 3;
for ( auto it = std::rbegin( set ); i-- != 0 && it != std::rend( set ); ++it )
{
std::cout << *it << ' ';
}
std::cout << '\n';
return 0;
}
If to enter
6
5 2 -4 16 0 15
then the output is
16 15 5
int main () {
int n;
std::cin >> n;
int number;
std::cin >> number;
int max1, max2, max3;
max1 = max2 = max3 =number;
for(int i = 1; i < n; i++) {
std::cin >> number;
if (number > max3) {
if (number > max2) {
if (number > max1) {
max3 = max2;
max2 = max1;
max1 = number;
} else {
max3 = max2;
max2 = number;
}
} else {
max3 = number;
}
}
}
std::cout << max3 << " " << max2 << " " << max1;
}
If the number is greater than max2 but smaller than max1 then max2 is the new max3 and max2 is number, that was the mistake.
Do not write everything in main. Slice code to smaller pieces to make it easy to read.
Here is an example (a bit to fancy):
class AccumulateTopThree
{
public:
void update(int x)
{
if (!isUnique(x)) return;
keepInOrder(c, x);
keepInOrder(b, c);
keepInOrder(a, b);
}
void print(std::ostream& out)
{
// TODO: handle case when count of input nubers is less then 3
out << c << ' ' << b << ' ' << a << '\n';
}
private:
bool isUnique(int x) const
{
return a != x && b != x && c != x;
}
static void keepInOrder(int &a, int &b)
{
if (a < b) std::swap(a, b);
}
private:
int a = std::numeric_limits<int>::min();
int b = a;
int c = a;
};
https://wandbox.org/permlink/OFkQUaGI9PygAV6D

printing stack in the incorrect order in c++

I have a function that pushes down all non zero integers to the top of my array and then reprints it in a 3x3 matrix.
the problem i am having is when i push all the non zero integers into my stack it reverses the order.
** the indexing of my array is backwards. ie, in a 3x3 matrix the coordinates (0,0) would be the bottom left **
here is the relevant code:
void State::pushDown() {
std::stack<int> tempStack;
for ( int c = 0; c < BOARDSIZE; c++ )
{
for ( int r = 0; r < BOARDSIZE ; r++ )
{
if ( grid[r][c] != 0 ) tempStack.push( grid[r][c] );
}
for ( int r = BOARDSIZE; r != 0; --r )
{
if ( !tempStack.empty() )
{
grid[r-1][c] = tempStack.top();
tempStack.pop();
}
else
{
grid[r-1][c] = 0;
}
}
}
}
State() {
for (int i = 0; i < BOARDSIZE; i++)
for (int j = 0; j < BOARDSIZE; j++)
grid[i][j] = rand() % 7;
}
void State::printBoard() {
cout << endl;
for (int i = 0; i < BOARDSIZE; i++) {
for (int j = 0; j < BOARDSIZE; j++) {
cout << " " << grid[BOARDSIZE - i - 1][j] << " ";
}
cout << endl;
}
}
int main() {
srand(time(0));
State state;
state.printBoard();
state.pushDown();
state.printBoard();
return 0;
}
here is my current output:
before push down function
045
504
226
after push down function:
006
224
545
as you can see it successfully pushes the non zero elements to the bottom of the matrix however in the process it reverses the order of the other numbers and i believe this is because of the stack.
my expected output would be the following:
before push down function
045
504
226
after push down function:
005
544
226
My question is- how can i fix my function so that the order of the elements remain the same without reversing.
Here is a demonstrative program that shows how the loops can be defined.
#include <iostream>
#include <stack>
const int BOARDSIZE = 3;
void reformat( int ( &a )[BOARDSIZE][BOARDSIZE] )
{
std::stack<int> tempStack;
for ( int c = 0; c < BOARDSIZE; c++ )
{
for ( int r = 0; r < BOARDSIZE ; r++ )
{
if ( a[r][c] != 0 ) tempStack.push( a[r][c] );
}
for ( int r = BOARDSIZE; r != 0; --r )
{
if ( !tempStack.empty() )
{
a[r-1][c] = tempStack.top();
tempStack.pop();
}
else
{
a[r-1][c] = 0;
}
}
}
}
int main()
{
int a[BOARDSIZE][BOARDSIZE] =
{
{ 0, 4, 5 },
{ 5, 0, 4 },
{ 2, 2, 6 }
};
for ( const auto &row : a )
{
for ( const auto &item : row ) std::cout << item << ' ';
std::cout << '\n';
}
std::cout << '\n';
reformat( a );
for ( const auto &row : a )
{
for ( const auto &item : row ) std::cout << item << ' ';
std::cout << '\n';
}
std::cout << '\n';
return 0;
}
Its output is
0 4 5
5 0 4
2 2 6
0 0 5
5 4 4
2 2 6
If you are outputting the array starting from its last row then use the following loops
#include <iostream>
#include <stack>
const int BOARDSIZE = 3;
void reformat( int ( &a )[BOARDSIZE][BOARDSIZE] )
{
std::stack<int> tempStack;
for ( int c = 0; c < BOARDSIZE; c++ )
{
for ( int r = 0; r < BOARDSIZE ; r++ )
{
if ( a[BOARDSIZE-r-1][c] != 0 ) tempStack.push( a[BOARDSIZE-r-1][c] );
}
for ( int r = 0; r != BOARDSIZE; ++r )
{
if ( !tempStack.empty() )
{
a[r][c] = tempStack.top();
tempStack.pop();
}
else
{
a[r][c] = 0;
}
}
}
}
int main()
{
int a[BOARDSIZE][BOARDSIZE] =
{
{ 2, 2, 6 },
{ 5, 0, 4 },
{ 0, 4, 5 }
};
for ( size_t i = 0; i < BOARDSIZE; i++ )
{
for ( const auto &item : a[BOARDSIZE - i - 1] ) std::cout << item << ' ';
std::cout << '\n';
}
std::cout << '\n';
reformat( a );
for ( size_t i = 0; i < BOARDSIZE; i++ )
{
for ( const auto &item : a[BOARDSIZE - i - 1] ) std::cout << item << ' ';
std::cout << '\n';
}
std::cout << '\n';
return 0;
}
The program output is the same as shown above
0 4 5
5 0 4
2 2 6
0 0 5
5 4 4
2 2 6
But now the array is outputted starting from its last line.

Prime Factors in C++(Error in program)

When I input 6 I only get 2.
When I input 91 I only get only 7.
However:
When I input 18 I get 2 3 3.
When I input 2121 (which is 3*7*101) I get 3 7.
I can't seem to find what is wrong. Does anybody have any suggestions?
#include<iostream>
using namespace std;
bool is_prime( int fac )
{
int i;
bool found;
found=true;
for( i = 2; i < fac; i++ )
{
if ( fac % i == 0 && found)
{
found=false;
break;
}
}
return found;
}
void prime_factors(int x)
{
int i;
for ( i = 2; i < x; i++ )
{
if ( is_prime(i) )
{
while ( x % i == 0 )
{
cout << i << " ";
x = x / i;
}
}
}
}
int main(){
int x;
cin>>x;
prime_factors(x);
}
Aside of the code indentation woes (I fixed those for you), there are two major things wrong here:
You're modifying x within your prime_factors() function, and your loop tests against x to know when to exit early. You should make a copy of x so that you don't do this.
You're not restoring x between loops.
You can also cut the number of tests you're doing in half in your is_prime() function.
Corrected Code Listing
#include<iostream>
using namespace std;
bool is_prime( int fac )
{
int i;
bool found = true;
for( i = 2; i < fac; i++)
{
if ( fac % i == 0 )
{
found=false;
break;
}
}
return found;
}
void prime_factors( int x )
{
int i;
int test;
for ( i = 2; i <= x; i++ )
{
test = x;
if ( is_prime(i) )
{
while ( test % i == 0 )
{
cout << i << " ";
test /= i;
}
}
}
}
int main(){
int x;
cin >> x;
prime_factors(x);
}
Sample Output
./a.out
100000
2 2 2 2 2 5 5 5 5 5
./a.out
6
2 3
./a.out
1001
7 11 13

C++ Remove the last new line

I'm using cout and endlto print some guides, the output (my intention) is like:
From Spot 1
Spot 2
Spot 5
Spot 8
Spot 6
To Spot 3
Here, the Spot No. is random and generated from some iterations. Because of iterations, i can only print the result like:
From Spot 1
Spot 2
Spot 5
Spot 8
Spot 6
Spot 3
Is there any method to remove my last new line Spot 3?
EDIT:
I want to find the shortest path (using Floyd-Warshall Algorithm) between two vertices. Here's my code, and it describes the following gragh:
#include <iostream>
using namespace std;
const int INF = 100000;
int n = 10, path[11][11], dist[11][11], map[11][11];
void init() {
int i, j;
for ( i = 1; i <= n; i++ )
for ( j = 1; j <= n; j++ )
map[i][j] = ( i == j ) ? 0:INF;
map[1][2] = 2, map[1][4] = 20, map[2][5] = 1;
map[3][2] = 3, map[4][3] = 8, map[4][6] = 6;
map[4][7] = 4, map[5][3] = 7, map[5][8] = 3;
map[6][3] = 1, map[7][8] = 1, map[8][6] = 2;
map[8][10] = 2, map[9][7] = 2, map[10][9] = 1;
}
void floyd() {
int i, j, k;
for ( i = 1; i <= n; i++ )
for ( j = 1; j <= n; j++ )
dist[i][j] = map[i][j], path[i][j] = 0;
for ( k = 1; k <= n; k++ )
for ( i = 1; i <= n; i++ )
for ( j = 1; j <= n; j++ )
if ( dist[i][k] + dist[k][j] < dist[i][j] )
dist[i][j] = dist[i][k] + dist[k][j], path[i][j] = k;
}
void output( int i, int j ) {
if ( i == j ) return;
if ( path[i][j] == 0 ) cout << "Spot" << j << endl;
else {
output( i, path[i][j] ); // iterations
output( path[i][j], j );
}
}
int main() {
int u, v;
init();
floyd();
u = 1, v = 3;
if ( dist[u][v] == INF ) cout << "No path" << endl;
else {
cout << "From Spot" << u << endl;
output( u, v );
cout << endl;
}
return 0;
}
The problem now is to find the conditon of the last iteration so that i can cout a different expression. But i think it is more easier to solve the problem by simply removing the last expression and rewriting, so i didnt attach my code.
EDIT 2:
I've achieved my purpose with the help of Fabian Tamp though it seems a little stupid of me writing the code above. Here goes the modified code:
#include <iostream>
#include <queue>
using namespace std;
const int INF = 100000;
int n = 10, path[11][11], dist[11][11], map[11][11];
void init() {
int i, j;
for ( i = 1; i <= n; i++ )
for ( j = 1; j <= n; j++ )
map[i][j] = ( i == j ) ? 0:INF;
map[1][2] = 2, map[1][4] = 20, map[2][5] = 1;
map[3][3] = 3, map[4][3] = 8, map[4][6] = 6;
map[4][7] = 4, map[5][3] = 7, map[5][8] = 3;
map[6][3] = 1, map[7][8] = 1, map[8][6] = 2;
map[8][10] = 2, map[9][7] = 2, map[10][9] = 1;
}
void floyd() {
int i, j, k;
for ( i = 1; i <= n; i++ )
for ( j = 1; j <= n; j++ )
dist[i][j] = map[i][j], path[i][j] = 0;
for ( k = 1; k <= n; k++ )
for ( i = 1; i <= n; i++ )
for ( j = 1; j <= n; j++ )
if ( dist[i][k] + dist[k][j] < dist[i][j] )
dist[i][j] = dist[i][k] + dist[k][j], path[i][j] = k;
}
void output( int i, int j, queue<int> &output_queue ) {
if ( i == j ) return;
if ( path[i][j] == 0 ) output_queue.push(j);
else {
output( i, path[i][j], output_queue); // iterations
output( path[i][j], j, output_queue);
}
}
void print_path(queue<int> output_queue) {
if (output_queue.empty()) return;
int item = output_queue.front();
while (!output_queue.empty()) {
item = output_queue.front();
output_queue.pop();
if (output_queue.empty()) {
cout << "To ";
}
cout << "Spot " << item << endl;
}
}
int main() {
int u, v;
init();
floyd();
u = 1, v = 3;
if ( dist[u][v] == INF ) cout << "No path" << endl;
else {
cout << "From Spot " << u << endl;
queue<int> output_queue;
output(u, v, output_queue);
print_path(output_queue);
}
return 0;
}
The output is the guide at the very beginning. Thank you all!
Change your output function thusly:
void output( int i, int j, Queue<int> &output_queue ) {
if ( i == j ) return;
if ( path[i][j] == 0 ) output_queue.push(j);
else {
output( i, path[i][j], output_queue); // iterations
output( path[i][j], j, output_queue);
}
}
Then change your main():
//....
else {
Queue<int> output_queue;
output_queue.push(u);
output(u, v, output_queue);
print_path(output_queue);
}
//...
Then add print_path:
void print_path(Queue<int> output_queue) {
if (output_queue.empty()) return;
auto item = output_queue.front();
cout << "From Spot " << item << endl;
while (!output_queue.empty()) {
item = output_queue.front();
output_queue.pop();
if (output_queue.empty()) {
cout << "To ";"
}
cout << "Spot " << item << endl;
}
}
A couple of things here:
I haven't compiled or tested this. Try and figure out any errors yourself and letting me know in the comments.
It would be really helpful for you to look at the STL. http://www.cplusplus.com/reference is a great resource for this.
If you're not familiar with passing by reference, that's the strategy I used to make sure that we're adding information to the same output_queue. Note that I've passed by copy for print_path() because it destroys the data in the parameter. It's one of the most powerful techniques in C++.
if you have how many lines you had printed you can use this macro
#define gotoxy(a,b) {COORD coord; coord.X=(b); coord.Y=(a) ; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);}
and go to that line and print " " for all characters you had printed.
It will make it easier if you do not print a newline after each line. Then you can go back and "erase" the text on the current line by outputting a number of "\b" (backspace) characters equal to the number of characters on the line, followed by the same number of spaces (to wipe out what was there). Then you can return to the beginning of the line by writing "\r" and write the whole line again.