This code prints all the permutation of N-1 items. But I could not understand one thing:
when n=N, it is returning where it is called and make flag[n-1] = false. Thus, i = N-1 and breaks the loop. But how is the rest of the permutation printing or returning when n=N-2 to 0?
void perm(int n) {
if (n == N) {
for (int i = 0; i < N ; i++) {
cout<<a[i]<<" ";
}
cout<<endl;
return;
}
for (int i = 0; i < N; i++) {
if (flag[i]) continue;
a[n] = i;
flag[i] = true;
cout<<i<<endl;
perm(n + 1);
cout<<i<<endl;
flag[i] = false;
}
}
You need to consider that function calls ended up nested.
Each indentation below shows a nested call:
main()
entering perm(0)
entering perm(1)
i = 0
entering perm(2)
let's say N is 2, this will print and return
now perm(1) continues
i becomes 1
entering perm(2)
...
Since return only returns from the current function call, not all function calls, the permutations continue printing.
In order to gain familiarity with this, try this:
void perm(int n) {
std::cout << "Entering perm " << n << std::endl;
if (n == N) {
for (int i = 0; i < N ; i++) {
cout<<a[i]<<" ";
}
cout<<endl;
std::cout << "Exiting perm " << n << std::endl;
return;
}
for (int i = 0; i < N; i++) {
if (flag[i]) continue;
a[n] = i;
flag[i] = true;
cout<<i<<endl;
std::cout << "about to call perm" << std::endl;
perm(n + 1);
std::cout << "finished call to perm" << std::endl;
cout<<i<<endl;
flag[i] = false;
}
std::cout << "Exiting perm " << n << " (2)"<< std::endl;
}
Related
I'm a C++ newb. I need to insert numbers to an array and then display first the odd numbers and then the even numbers in a single array. I've managed to create two separate arrays with the odd and even numbers but now I don't know how to sort them and put them back in a single array. I need your help to understand how to do this with basic C++ knowledge, so no advanced functions. Here's my code:
#include <iostream>
using namespace std;
int main()
{
int N{ 0 }, vector[100], even[100], odd[100], unify[100], i{ 0 }, j{ 0 }, k{ 0 };
cout << "Add the dimension: " << endl;
cin >> N;
cout << "Add the elements: " << endl;
for (int i = 0; i < N; i++) {
cout << "v[" << i << "]=" << endl;
cin >> vector[i];
}
for (i = 0; i < N; i++) {
if (vector[i] % 2 == 0) {
even[j] = vector[i];
j++;
}
else if (vector[i] % 2 != 0) {
odd[k] = vector[i];
k++;
}
}
cout << "even elements are :" << endl;
for (i = 0; i < j; i++) {
cout << " " << even[i] << " ";
cout << endl;
}
cout << "Odd elements are :" << endl;
for (i = 0; i < k; i++) {
cout << " " << odd[i] << " ";
cout << endl;
}
return 0;
}
If you don't need to store the values then you can simply run through the elements and print the odd and the even values to different stringstreams, then print the streams at the end:
#include <sstream>
#include <stddef.h>
#include <iostream>
int main () {
std::stringstream oddStr;
std::stringstream evenStr;
static constexpr size_t vecSize{100};
int vec[vecSize] = {10, 5, 7, /*other elements...*/ };
for(size_t vecIndex = 0; vecIndex < vecSize; ++vecIndex) {
if(vec[vecIndex] % 2 == 0) {
evenStr << vec[vecIndex] << " ";
} else {
oddStr << vec[vecIndex] << " ";
}
}
std::cout << "Even elements are:" << evenStr.rdbuf() << std::endl;
std::cout << "Odd elements are:" << oddStr.rdbuf() << std::endl;
}
Storing and sorting the elements are always expensive.
Basically, it would be better to sort them first.
#include <iostream>
using namespace std;
int main()
{
int numbers[5];
int mergedArrays[5];
int evenNumbers[5];
int oddNumbers[5];
for(int i=0;i<5;i++){
cin>>numbers[i];
}
int temp=numbers[0];
//bubble sort
for(int i = 0; i<5; i++)
{
for(int j = i+1; j<5; j++)
{
if(numbers[j] < numbers[i])
{
temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
}
}
}
int nEvens=0;
int nOdds=0;
for(int i = 0; i<5; i++)
{
if(numbers[i]%2==0)
{
evenNumbers[nEvens]=numbers[i];
nEvens++;
}
else if(numbers[i]%2!=0)
{
oddNumbers[nOdds]=numbers[i];
nOdds++;
}
}
int lastIndex=0;
//copy evens
for(int i = 0; i<nEvens; i++)
{
mergedArrays[i]=evenNumbers[i];
lastIndex=i;
}
//copy odds
for(int i =lastIndex; i<nOdds; i++)
{
mergedArrays[i]=oddNumbers[i];
}
return 0;
}
If you have to just output the numbers in any order, or the order given in the input then just loop over the array twice and output first the even and then the odd numbers.
If you have to output the numbers in order than there is no way around sorting them. And then you can include the even/odd test in the comparison:
std::ranges::sort(vector, [](const int &lhs, const int &rhs) {
return ((lhs % 2) < (rhs % 2)) || (lhs < rhs); });
or using a projection:
std::ranges::sort(vector, {}, [](const int &x) {
return std::pair<bool, int>{x % 2 == 0, x}; });
If you can't use std::ranges::sort then implementing your own sort is left to the reader.
I managed to find the following solution. Thanks you all for your help.
#include <iostream>
using namespace std;
int main()
{
int N{0}, vector[100], even[100], odd[100], merge[100], i{0}, j{0}, k{0}, l{0};
cout << "Add the dimension: " << endl;
cin >> N;
cout << "Add the elements: " << endl;
for (int i = 0; i < N; i++)
{
cout << "v[" << i << "]=" << endl;
cin >> vector[i];
}
for (i = 0; i < N; i++)
{
if (vector[i] % 2 == 0)
{
even[j] = vector[i];
j++;
}
else if (vector[i] % 2 != 0)
{
odd[k] = vector[i];
k++;
}
}
cout << "even elements are :" << endl;
for (i = 0; i < j; i++)
{
cout << " " << even[i] << " ";
cout << endl;
}
cout << "Odd elements are :" << endl;
for (i = 0; i < k; i++)
{
cout << " " << odd[i] << " ";
cout << endl;
}
for (i = 0; i < k; i++)
{
merge[i] = odd[i];
}
for (int; i < j + k; i++)
{
merge[i] = even[i - k];
}
for (int i = 0; i < N; i++)
{
cout << merge[i] << endl;
}
return 0;
}
You can use Bubble Sort Algorithm to sort whole input. After sorting them using if and put odd or even numbers in start of result array and and others after them. like below:
//Bubble Sort
void bubbleSort(int arr[], int n)
{
int i, j;
for (i = 0; i < n - 1; i++)
// Last i elements are already
// in place
for (j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1])
swap(arr[j], arr[j + 1]);
}
// Insert In array
int result[100];
if(odd[0]<even[0])
{
for (int i = 0; i < k; i++)
{result[i] = odd[i];}
for (int i = 0; i < j; i++)
{result[i+k] = even[i];}
}else
{
for (int i = 0; i < j; i++)
{result[i] = even[i];}
for (int i = 0; i < k; i++)
{result[i+k] = odd[i];}
}
I have a problem with this piece of code, I'm trying to print the EVEN and ODD numbers, but there is a problem when it comes to show them, the vectors don't save the numbers as I'm expecting.
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int vect[n], even[n], odd[n]; // CREATING VECTORS LIMIT AFTER "n"
for(int i = 1; i <= n; ++i) { // ENTERING The ELEMENS IN VECTOR
cin >> vect[i];
}
for(int i = 1; i <= n; ++i) {
if(vect[i] % 2 != 0) {
odd[i] = vect[i]; // I think that here's the problem, the vectors don't save the right numbers.
} /// VERIFYING IF THE NUMBER IS ODD OR EVEN.
else if (vect[i] % 2 == 0) {
even[i] == vect[i];
}
}
for(int i = 1; i <= n; ++i) {
cout << even[i] << " " << endl; /// PRINTING THE ODD AND EVEN numbers.
cout << odd[i] << " " << endl;
}
return 0;x
}
I have fixed the problem, thanks all for help.
Now it works perfectly.
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int vect[n], even[n], odd[n], z = 0, x = 0; // CREATING VECTORS LIMIT AFTER "n"
for(int i = 1; i <= n; ++i) { // ENTERING The ELEMENS IN VECTOR
cin >> vect[i];
}
for(int i = 1; i <= n; ++i) {
if(vect[i] % 2 != 0) {
odd[1+z] = vect[i];
z++;
// I think that here's the problem, the vectors don't save the right numbers.
} /// VERIFYING IF THE NUMBER IS ODD OR EVEN.
else if (vect[i] % 2 == 0) {
even[1+x] = vect[i];
x++;
}
}
for(int i = 1; i <= x; i++) {
cout << even[i] << " ";
}
cout << endl;
for(int i = 1; i <= z; i++) {
cout << odd[i] << " ";
}
return 0;
}
Considering the hints of the comments, your program shall be changed into this:
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n, number;
cin >> n;
vector<int> vect, even, odd; // CREATING DYNAMIC VECTORS
for(int i = 0; i < n; ++i) { // ENTERING THE ELEMENTS IN VECTOR
cin >> number;
vect.push_back(number);
}
for(int i = 0; i < n; ++i) {
if(vect[i] % 2 != 0) { /// VERIFYING IF THE NUMBER IS ODD OR EVEN.
odd.push_back(vect[i]);
}
else {
even.push_back(vect[i]);
}
}
for (int i = 0; i < n; ++i)
cout << vect[i] << " ";
cout << endl;
/// PRINTING THE ODD AND EVEN NUMBERS.
for (auto& val : odd)
cout << val << " ";
cout << endl;
for (auto& val : even)
cout << val << " ";
cout << endl;
return 0;
}
It uses the vector container of STL for your arrays, start the indexing at 0 and prints out the resulting arrays separately, as the number of odd and of even entries might be different.
Hope it helps?
With standard, you might use std::partition (or stable version) to solve your problem:
void print_even_odd(std::vector<int> v)
{
auto limit = std::stable_partition(v.begin(), v.end(), [](int n){ return n % 2 == 0; });
std::cout << "Evens:";
// Pre-C++20 span:
// for (auto it = v.begin(); it != limit; ++it) { int n = *it;
for (int n : std::span(v.begin(), limit)) {
std::cout << " " << n;
}
std::cout << std::endl;
std::cout << "Odds:";
for (int n : std::span(limit, v.end())) {
std::cout << " " << n;
}
std::cout << std::endl;
}
Demo
I am currently working on Knight tour Chessboard game in c++ using Stack to store my move. I encounter a weird loop that does not end the program. Can anybody help me with the code?
#include <iostream>
#include <stack>
#include <map>
#include <cstdlib>
using namespace std;
struct whereIam
{
int row, col;
};
struct L_shape_pattern
{
int Lrow[8]={1,1,2,2,-1,-1,-2,-2};
int Lcol[8]={2,-2,1,-1,2,-2,1,-1};
};
bool check_if_valid(int row, int col)
{
if ((row >= 0 && col >= 0) && (row < 8 && col < 8))
{
// cout << "here in valid " <<endl;
return true ;
}
else
return false;
}
bool check_empty(bool board[8][8], whereIam position)
{
// if (board[position.row][position.col] == false)
// return false;
// else
// return true;
if (board[position.row][position.col] == true)
{
// cout << "here in check empty" <<endl;
return true;
}
else
return false;
}
bool isReady(whereIam &position,bool board[8][8])
{
// cout << "here" << endl;
int ready = 0;
for (int i = 0 ; i < 8 ; i ++)
{
for (int j = 0 ; j < 8 ; j++)
{
if(board[i][j] == false)
{
ready += 1;
}
}
}
cout << "ready: " <<ready << endl;
if (ready == 64)
{
cout << "done" << endl;
return true;
}
else
return false;
}
void findspot(whereIam &position,bool board[8][8], stack<whereIam> &sequence)
{
L_shape_pattern Lshape;
// stack<whereIam> initial;
stack<int> counter;
for (int j = 0 ; j< 9 ;j++)
{
//nothing is assign here
if (check_if_valid(position.row+Lshape.Lrow[j],position.col+Lshape.Lcol[j]) /*&& check_empty(board,position)*/)
{
// cout << "here in valid in spot " <<endl;
whereIam hello;
hello.row = position.row+Lshape.Lrow[j];
hello.col = position.col+Lshape.Lcol[j];
// cout << hello.row << " " << hello.col << endl;
if (check_empty(board,hello))
{
// cout << "here in empty" <<endl;
// int possible_row = position.row+Lshape.Lrow[j];
// int possible_col = position.col+Lshape.Lcol[j];
// position.row = possible_row;
// position.col = possible_col;
position.row = hello.row;
position.col = hello.col;
sequence.push(position);
// initial.push(position);
// cout << position.row << " " << position.col << endl;
counter.push(j);
board[position.row][position.col] = false;
j = -1;
if (isReady(position,board) == true)
{
cout << "in if ready" << endl;
exit(0);
}
}
}
if (j == 8 )
{
// cout << "here in j = 8" <<endl;
board[position.row][position.col] = true;
// cout << " pop board " << position.row <<" " << position.col << endl;
sequence.pop();
position = sequence.top();
// increment to the position where it need to be backtracking and it increment by one
j = counter.top();
counter.pop();
if (isReady(position,board) == true)
{
cout << "in if ready" << endl;
exit(0);
}
}
}
}
//bool movetheKnight(whereIam &position,bool board[8][8], stack<whereIam> &sequence)
//{
//}
void open_all_spot( bool board[8][8])
{
for (int i = 0 ; i< 8 ; i++)
for (int j= 0 ; j <8 ; j++)
{
board[i][j] = true;
}
}
int main()
{
bool board[8][8];
open_all_spot(board);
whereIam position;
stack<whereIam> sequence;
cout << "Enter the initial position" << endl;
cout << "row : " ;
cin >> position.row;
cout << "column:";
cin >> position.col;
sequence.push(position);
//assign the initial position to be occupied already
board[position.row][position.col] = false;
findspot(position,board,sequence);
cout << "here end all" << endl;
return 0;
}
Some part I just created to debug and see how each function work so ignore those part.
The loop always goes on and never seems to end at all. I tried to track data in the stack but it does seems reasonable to me.
Any help would be appreciated.
When looking at this part of your code:
for ( int j = 0; j < 9; j++ ) {
if ( check_if_valid(position.row+Lshape.Lrow[j],position.col+Lshape.Lcol[j]) /*&& check_empty(board,position)*/) {
// code...
if ( checkEmpty( board, hello ) {
// code...
j = -1;
if ( isReady(position, board) == true ) { // == true not needed
// code...
}
}
}
if ( j == 8 ) {
// code...
j = counter.top()
// code...
if ( isReady(position, board) == true ) { // == true not needed
// code...
}
}
} // for loop
Think about what happens in the 1st nested if statement within the for loop when the condition is returned true. You are changing j to be -1.
Again in the 2nd if statement within the for loop if j==8 you again are changing j to be counter.top().
This behavior will cause infinite recursion of the for loop. Here is a simple example:
#include <iostream>
#include <iomanip>
int main() {
int counter = 0;
for ( int i = 0; i < 5; i++ ) {
if ( i == 4 ) {
i = 0;
}
++counter;
std::cout << "Count the recursion: "
<< std::setw( 2 ) << counter << " " << i << '\n';
// just to stop the recursion
if ( counter == 10 ) break;
}
std::cout << "\nPress any key and enter to quit.\n";
std::cin.get();
return 0;
}
The above program without the last if statement will simulate what is happening in your program. I only included that so as to stop the loop just to show the progression of the output.
I don't know if you intentionally want an infinite recursion of a for loop or not; but if you do you need to check your counter variable(s) in a debugger to make sure that they match the value needed to execute the statement involved in exiting the loop to stop the recursion. Just as I have shown in my small example above; without the condition of the counter being equal to 10. The loop would of continued on forever.
As a side note if you do intend to have an infinite loop; it is usually better to structure them in this manner this way it is more clear as to what you intended to do.
int counter = 0;
for ( ; ; ) {
++counter;
// do some work;
if ( counter == exit condition ) break;
}
or
int counter = 0;
for ( ; ; ) {
// do some work;
if work above is valid
increment counter
else
break;
}
or you can use a while loop instead
counter = some value
while ( true ) {
check counter for condition;
do some work
increment or set counter;
}
For this vectors and merging assignment, we are supposed to read in user inputted strings and sort them alphabetically. I got the first two parts, but when I am putting the sorted elements in the new vector, it says that my new vector is out of range. Does anyone know how to fix this?
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<string> que1;
vector<string> que2;
vector<string> que_merge;
string firstName;
string secondName;
int counterq1 = 0;
int counterq2 = 0;
cout << "Enter queues: " << endl;
bool check = true;
while(check) {
cin >> firstName;
if (firstName == "ENDQ"){
check = false;
}
else{
que1.push_back(firstName);
counterq1++;
check = true;
}
}
// que1.resize(counterq1);
bool check2 = true;
while (check2) {
cin >> secondName;
if (secondName == "ENDQ") {
check2 = false;
} else {
que2.push_back(secondName);
counterq2++;
}
}
// que2.resize(counterq2);
cout << "que1: " << counterq1 << endl;
for (int i = 0; i < que1.size(); i++) {
cout << que1.at(i) << endl;
}
cout << endl;
cout << "que2: " << counterq2 << endl;
for (int j = 0; j < que2.size(); j++) {
cout << que2.at(j) << endl;
}
cout << endl;
cout << "que_merge: " << counterq1 + counterq2 << endl;
int i = 0;
int k = 0;
int j = 0;
while (1){
if (i >= counterq1 || j >= counterq2){
break;
}
if(que1.at(i) < que2.at(j)){
que_merge.push_back(que1.at(i));
i++;
}
else{
que_merge.push_back(que2.at(j));
j++;
}
k++;
}
if (que1.empty()){
for (int m = j; m < counterq2; m++){
que_merge.push_back(que2.at(m));
}
} else {
for (int l = i; l < counterq1; ++l) {
que_merge.push_back(que1.at(l));
}
}
for (int l = 0; l < (counterq1+counterq2); l++) {
cout << que_merge.at(l) << endl;
}
return 0;
}
I think your problem is that these lines:
if (que1.empty()){
for (int m = j; m < counterq2; m++){
que_merge.push_back(que2.at(m));
}
} else {
for (int l = i; l < counterq1; ++l) {
que_merge.push_back(que1.at(l));
}
}
doesn't do what you expect.
As far as I can see, your idea is to merge the remaining element from either que1 or que2.
However, that is not what you get from this code as the elements in que1 and que2 is never erased. In other words - the check for an empty queue is rather meaningless and you can't be sure that all elements are added to que_merge
So when you do:
for (int l = 0; l < (counterq1+counterq2); l++) {
cout << que_merge.at(l) << endl;
}
you may read beyond the number of elements in que_merge
Tip:
Don't count the number of elements your self. Use size() (like que_merge.size()) instead. For instance:
for (int l = 0; l < que_merge.size(); l++) {
cout << que_merge.at(l) << endl;
}
or a range based loop like:
for (const auto& s : que_merge) {
cout << s << endl;
}
#include <algorithm>
Use std::merge and std::sort, not necessarily in that order.
If the assignment says you can't do it the C++ way, that you have to write it all out, you can do it the engineer's way: Find an example that works, and crib it.
There are two possible implementations of std::merge on this page: All about C++ merge
Game.h
#include "RandomNumberGenerator.h"
class Game
{
private:
int myNumbers[6];
int userRandomNumbers[6];
int lotteryRandomNumbers[6];
int prizeMoney;
public:
void generateRandomNumbersLottery();
void generateRandomNumbersUser();
void userInputNumbers();
void compareNumbers1();
void compareNumbers2();
void results();
};
Game.cpp
#include "Game.h"
void Game::compareNumbers1()
{
int k = 0;
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 6; ++j)
{
if (myNumbers[i] == lotteryRandomNumbers[j])
{
k++;
}
}
}
if (k > 0)
{
std::cout << "Congratulations you matched: " << k << " number(s)";
}
if (k == 0)
{
std::cout << "Unfortunatly you matched: " << k << " numbers";
}
}
void Game::compareNumbers2()
{
int k = 0;
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 6; ++j)
{
if (userRandomNumbers[i] == lotteryRandomNumbers[j])
{
k++;
}
}
}
if (k > 0)
{
std::cout << "Congratulations you matched: " << k << " number(s)";
}
if (k == 0)
{
std::cout << "Unfortunatly you matched: " << k << " numbers";
}
}
void Game::results()
{
if (k == 0)
{
prizeMoney = 0;
std::cout << "Unfortunatly you need to match atleast 2 numbers to win a prize.";
}
if (k == 1)
{
prizeMoney = 0;
std::cout << "Unfortunatly you need to match atleast 2 numbers to win a prize.";
}
if (k == 2)
{
prizeMoney = 3;
std::cout << "Congratulations, you have won: 3 pounds.";
}
if (k == 3)
{
prizeMoney = 30;
std::cout << "Congratulations, you have won: 30 pounds.";
}
if (k == 4)
{
prizeMoney = 3000;
std::cout << "Congratulations, you have won: 3,000 pounds.";
}
if (k == 5)
{
prizeMoney = 30000;
std::cout << "Congratulations, you have won: 30,000 pounds.";
}
if (k == 6)
{
prizeMoney = 3000000;
std::cout << "Congratulations, you have won: 3,000,000 pounds.";
}
}
Main.cpp
#include "Game.h"
std::cout << "Do you wish to enter your own numbers or generate them randomly?: ('own', 'random') ";
std::getline (std::cin, choice);
if (choice == "random")
{
play.generateRandomNumbersUser();
std::cout << std::endl << std::endl;
play.generateRandomNumbersLottery();
std::cout << std::endl << std::endl;
play.compareNumbers2();
}
if (choice == "own")
{
play.userInputNumbers();
std::cout << std::endl << std::endl;
play.generateRandomNumbersLottery();
std::cout << std::endl << std::endl;
play.compareNumbers1();
}
play.results();
system("pause");
return 0;
}
I'm aware this code has a lot of poor syntax etc in it at the moment but it currently just rough working code (i.e. no validation yet when choosing random or own numbers)
What I'm asking here is how do I get whatever value is in int k (from compareNumbers1() and compareNumbers2()) into results().
As far as my thinking goes it needs to be passed using a pointer somehow, or changing compareNumbers from void to int and return k. However after playing around with both these ways I still cannot get it to work.
One option is to use parameters. Pass the value as a parameter into results:
void results(int k);
Which leaves the question of how to get it out of compareNumbers1(). You could return it from that function:
int compareNumbers1();
If you need to put it into compareNumbers2(), let that method modify it, and then allow the caller to see the modifications you'd pass a reference to the variable:
void compareNumbers2(int& k);
And you'd clearly need to declare the variable somewhere. Since it is returned from compareNumbers1() you would declare it and assign it like this:
int k = compareNumbers1();
Put it all together at the call site and you have:
int k = compareNumbers1();
compareNumbers2(k);
results(k);
The obvious alternative to parameters is to make the variable be a private member variable of the class.