I'm struggling with solving this problem in C++.
I have a string: {A,A,B,C} and I want to print all possible permutations for this.
This would be 12:
AABC, AACB, ABAC, ABCA, etc...
I've written the following piece of code in which I have:
- a string which contains the letters A,A,B,C.
- a result string in which I will print each permutation when base condition of recursivity is fullfilled
- an array of integers which represent counters values for each digit: counters[3] = {2,1,1} which means there can be 2 A's, 1 B and 1C in a permutation.
- a function which should solve the problem in a recursive manner like this:
Start from initial string. From left to right of string check if counter for each character is greater than 0. If it is put the character in result[lvl] where lvl is the depth of the recursion. Then decrement the counter for that character's position. Do that for all the elements to the right of the current element and then backtrack all the way up and start with next element(second A).
The base case would be when all counters are equal to 0 print the solution then return.
Here is the code:
#include <iostream>
using namespace std;
char theString[4] = {'A','A','B','C'};
char resultString[4]={};
int counters[3] = {2,1,1};
void printPermutation()
{
for(int i=0; i<4; i++)
{
cout << resultString[i];
}
cout << endl;
}
void solvePermutations(int *counters, int lvl)
{
if(lvl == 4)
{
printPermutation();
return;
}
for(int i=0; i<4; i++)
{
if(counters[i] == 0)
{continue;}
else
{
resultString[lvl] = theString[i];
counters[i]--;
solvePermutations(counters, lvl+1);
counters[i]++;
}
}
}
int main()
{
int *ptr;
ptr = counters;
solvePermutations(ptr, 0);
return 0;
}
When I run the code I get this output instead of what I'm expecting(12 distinct permutations):
ACAB
ACBA
BAAA
BAAC
BACA
etc
More than 12 and with no logic(to me :D)
Please help me correct this and tell me what is wrong in my algorithm and help me understand it. Thank you.
You have one small logical error in your algorithm. You are using a counter[3] and a theString[4]. The idea here is that each index of counter should correspond to one letter, and hold the amount of that letter used.
With your loop you are using i<4. When i is 3 in that loop, you are trying to access counter[3] which is out of bounds. This in undefined behavior and you could be reading any int value.
To correct this, you simply need to decrease the loop to go to max 2 (i < 3) and change theString to an array of 3 elements, {'A', 'B', 'C'}.
char theString[3] = {'A','B','C'};
//...
for(int i=0; i<3; i++)
Related
#include<iostream>
using namespace std;
int main(){
int n,d1,d2,d3;
cout<<"Enter a 3-digit positive integer"<<endl;
cin>>n;
d1=n/100;
d2=n%100/10;
d3=n%10;
int a[3]{d1,d2,d3};
for (int i = 0; i < 3; ++i) {
if(a[i]!=0){
a[i]=10-a[i];
}
cout<<"The new number is :"<<a[i]<<endl;
}
}
This code takes a 3-digit integer as input and returns a new number in which all non-zero digits in the original are replaced by the distance between the digit and 10, for example, if one of the digits is 2 so the new digit will be 10-2=8. But the problem is with the output.
I want the program to print (The new number is :(here the new digits in the same line)), instead of repeating the message and printing each digit in a separate line. How can I do that??
Thanks in advance.
This for loop,
for (int i = 0; i < 3; ++i) {
if(a[i]!=0){
a[i]=10-a[i];
}
cout<<"The new number is :"<<a[i]<<endl;
}
Is the issue for your problem. This means that your printing The new number is : on every iteration. What we need to do is, print it once and print all the integers after it. Its very simple, just change the position of the std::cout to be before the for loop and we can put in a little optimization; we dont need to store the 10 - a[i], we can directly print it.
cout << "The new number is : ";
for (int i = 0; i < 3; ++i) {
if(a[i] != 0) {
std::cout << (10 - a[i]);
}
}
Bonus: Try not to use using namespace std; as its a bad practice. Basically what it does is, it takes the whole std namespace and dumps it into the global namespace. If its for competitive programming and time is limited, then it would be okay but for general programming, avoid it.
u can print the information out from the for loop or u can do for loop like this
for (int i = 0; i < 3; ++i) {
if(a[i]!=0){
a[i]=10-a[i];
}
if(i == 0)
cout<<"The new number is :";
cout <<a[i];
}
cout << endl
I am trying to count number of swaps to sort the given array in ascending order. Inside the for loop I have a if condition to check the condition weather to swap or not , But inside if condition I have added a cout statement to check which elements are being compared, When I have that cout statement number of swaps printed are different, and when I remove that statement number of swaps printed are different, for sample:
if I have cout statement
Sample Input
1
4
4 1 2 3
and output came as
3
if I remove or comment that cout statement
Sample Input
1
4
4 1 2 3
and output came as
4
I can't figure out the reason for this.
#include <iostream>
using namespace std;
int main() {
int swap=0,t,n,arr[20],temp;
cin>>t;
while(t!=0) {
cin>>n;
for(int i = 0 ; i < n ; i++) {
cin>>arr[i];
}
for(int i = 0 ; i < n ; i++) {
if(arr[i]>arr[i+1]) {
swap++;
cout<<arr[i]<<">"<<arr[i+1]<<endl; //this cout statement
temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
cout<<swap<<endl;
--t;
}
return 0;
}
Your result is non-deterministic since you are accessing a position of the array that should not be accessed, i.e. when i = n - 1, a[i+1] is trying to access a[n] that is "dirty" memory.
Furthermore I think that your algorithm does not do what you want it to do. I suggest you to read here before going further. From the right code, it's enough to add the counter (as you did) to obtain the correct result.
So, I tried to make an array using input first, then sorting it out from smallest to biggest, then display the array to monitor.
So I come up with this code :
#include <iostream>
using namespace std;
void pancakeSort(int sortArray[], int sortSize);
int main()
{
// Input The Array Element Value
int pancake[10];
for(int i=0; i<10; i++)
{
cout << "Person " << i+1 << " eat pancakes = ";
cin >> pancake[i];
}
// call pancake sorting function
pancakeSort(pancake, 10);
}
void pancakeSort(int sortArray[], int sortSize)
{
int length = 10;
int temp;
int stop = 10;
// this is where the array get sorting out from smallest to biggest number
for(int counter = length-1; counter>=0; counter--)
{
for(int j=0; j<stop; j++)
{
if(sortArray[j]>sortArray[j+1])
{
temp = sortArray[j+1];
sortArray[j+1] = sortArray[j];
sortArray[j]=temp;
}
}
stop--;
}
// after that, the array get display here
for(int x=0; x<sortSize; x++)
{
cout << sortArray[x] << " ";
}
}
but the output is weird :
enter image description here
the function is successfully sorting the array from smallest to biggest,
but there is 2 weird things :
1. The biggest value element (which is 96 from what I input and it's the 10th element after got sorted out), disappear from the display.
2. For some reason, there is value 10 , which I didn't input on the array.
So, what happened?
In the loop
for(int j=0; j<stop; j++)
{
if(sortArray[j]>sortArray[j+1])
{
temp = sortArray[j+1];
sortArray[j+1] = sortArray[j];
sortArray[j]=temp;
}
}
stop is the length of the array, and you are iterating through values of j = 0 to stop - 1. When j reaches stop - 1, the next element that is j+1 becomes stop (10 in this case). But since your array has a length of 10, sortArray[10] is not part of the array, but is referring to some other object in memory which is usually a garbage value. The garbage value is 10 in this case. When you swap sortArray[10] and sortArray[9], the garbage value becomes part of the array and the value at index 9 leaves the array. This keeps on happening till the outer loop ends.
The end result is that unless the garbage value < largest element in the array, the garbage value is pushed in the array and the greatest value of the array is put at sortArray[10] which is not part of the array. If the garbage value is greater than all the values of the array, it'll be found at sortArray[10] which is again not part of the array and your code will return the desired result.
Essentially, what you are doing is giving the function an array of 10 (or stop) elements, but the function is actually working with an array of 11 (or stop + 1) elements, with the last element being a garbage value. The simple fix is to change the conditional of the loop to j < stop - 1.
Note that if you had written this code in a managed (or a comparatively higher level) language like Java or C#, it would have raised an IndexOutOfBoundsException.
At index 9, j+1 is out of bounds. So to fix this, you only need to check till index 8
for(int counter = length-1; counter>=0; counter--)
{
for(int j=0; j<stop-1; j++)
{
if(sortArray[j]>sortArray[j+1])
{
temp = sortArray[j+1];
sortArray[j+1] = sortArray[j];
sortArray[j]=temp;
}
}
stop--;
}
Look carefully at the inner loop condition j<stop-1
My problem is a bit hard to explain, so I will do my best. I'm writing a program that will take a target number and a list of other numbers. I want it to add all possible combinations of numbers from the list until a combination of numbers from the list sums to be the same as the target number. For example, if the target number is 6 and the list provided has the numbers <2, 3, 4, 5>, then the program will print the solution being 2+4=6.
I currently have the program set up with 4 nested loops where the outermost loop checks combinations with the first number as constant. The second loop holds the second number constant, and likewise for the other two. If the target number was 20 for the above list, the program would check in the following manner:
2
2+3
2+3+4
2+3+4+5
2+3+5
2+4
2+4+5
2+5
3
3+4
3+4+5
3+5
4
4+5
5
Then it would return a message saying no solutions were found. This works okay for small lists, but would not work very well if the list contained many small numbers and the target number was a high one. Since the program only has four loops, it can only add 4 numbers at most.
I can't help but thinking that there must be a better way to do this, because for longer lists, the only solution would be to make more nested loops, which isn't practical. Is there a way to go through all combinations of a list of numbers without nested loops?
I hope that this was easy to understand. If you'd like to see my code, let me know. Thank you for your help!
You might use a recursive approach like this:
#include <iostream>
#include <vector>
using namespace std;
vector<bool> active_pos;
vector<int> input;
int recurse (int current_sum, int target_sum, int length) {
if (length < 0) {
return -1;
}
for (int i = 0; i < input.size(); i++) {
if (active_pos[i]) {
continue;
}
active_pos[i] = true;
int tmp_sum = current_sum + input[i];
if (tmp_sum == target_sum) {
return tmp_sum;
}
int next_sum = recurse(tmp_sum, target_sum, length-1);
if (next_sum == target_sum) {
return next_sum;
}
active_pos[i] = false;
}
return -1;
}
int main(int argc, const char **argv) {
input.push_back(2);
input.push_back(3);
input.push_back(4);
input.push_back(5);
input.push_back(6);
int length = input.size();
active_pos.resize(length);
int res = recurse(0, 10, length);
cout << "Result is: " << res << endl;
cout << "Used numbers are: " << endl;
for (int j = 0; j < length; j++) {
if (active_pos[j]) {
cout << input[j] << " ";
}
}
cout << endl;
}
The function recurse() calls itself and decrements the length parameters by one for each time. A vector keeps track of the values which are already taken.
If an instance of recurse() finds a matching sum, it returns that value. If not, it returns -1. If the final result is -1, no matches were found.
I would approach this from the other direction....add all of the numbers from the list together, and if it doesn't equal the target value, your done....if the addition of the list is larger than the target, then start to remove items from the start of you list until you match the target value. If you don't match, (skips by the target value) and the addition value become smaller than your target value, then handle that scenario appropriately.
This should only require 1 loop.
You could represent each combination as N one-bit values, set if that element should be in the combination. Then iterating over all combinations is equivalent to counting from 1 to 2N, with an inner loop to add up the values corresponding to the set bits.
If the set size is 64 or less, then you do this very easily with a uint64_t loop counter. If it's larger, then you probably won't live long enough to see the result anyway.
#include<iostream>
#include<conio.h>
#include<math.h>
#include<vector>
#include<iterator>
#include<string>
using namespace std;
int main() {
int k=0;
string s;
cout<<"string ";
getline(cin,s); //taking in a string from the user
float n=s.size(); //storing size of string
int f=floor((sqrt(n))); //floor of square root of input string
int c=ceil((sqrt(n))); //ceiling
int m=f*c; //storing product of f and c
vector< vector<string> > vec(n<=m?f:++f, vector<string>(c)); //makes a 2d vector
//depending on user's
//string length
for(int i=0;n<=m?i<f:i<++f;i++) //looping acc to user's input and assigning
{
for(int j=0;j<c;j++) //string to a matrix
{
if(k<s.size())
{
vec[i][j]=s[k];
k++;
}
}
}
for(int j=0;j<c;j++) //printing the vector
{
{
for(int i=0;n<=m?i<f:i<++f;i++)
cout<<vec[i][j];
}cout<<" ";
}
getch();
}
It's not working for n>m as for a string of length 8 characters it makes a vector of 2*3 thus failing to enclose the whole string in the matrix and which is why I am using ternary so as to make a vector of bigger size when it encounters cases like these.
.So what am I doing wrong?
I'll just write the whole question.
One classic method for composing secret messages is called a square code. The spaces are removed from the english text and the characters are written into a square (or rectangle). The width and height of the rectangle have the constraint,
floor(sqrt(word)) <= width, height <= ceil(sqrt(word))
The coded message is obtained by reading down the columns going left to right. For example, the message above is coded as:
imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau
Sample Input:
chillout
Sample Output:
clu hlt io
This won't fix your entire problem, but I still feel it is important. You seem to misunderstand how the ternary works. Let's observe one of its uses here:
for (int i = 0; n <= m ? i < f : i < ++f; i++) {}
// ^^^^^^^^^^^^^^^^^^^^^^^^ <--- not the intended outcome
This will not work because the returned side of the ternary does not "stick" itself in-place. In other words, neither i < f nor i < ++f will be put directly into the for-loop. Instead, it'll give you a value.
To see what it's really doing, you'll first need to understand that the ternary is just another way to do an if-else. The ternary above, put into if-else form, looks like this:
if (n <= m)
i < f; // left side of the ":"
else
i < ++f; // right side of the ":"
Let's break it down further:
i < f
This is doing a less-than comparison of i and f. So, depending on the individual values, you'll receive either a 0 (false) or a 1 (true).
So, in your for-loop, this will occur:
for (int i = 0; 1; i++) {}
// ^ <--- if comparison returns true
for (int i = 0; 0; i++) {}
// ^ <--- if comparison returns false
So, for your example, you'll need to find the value of f before the loop. You can use a ternary for that part, but only if you understand it. Otherwise, use another method to find f (the intended numerical value). Once you find it, then you can put i < f into the for-loop.