C++ Permutation with a output length limit and special arguments - c++

I am new to C++ and I am working on a program that will generate a list of all permutations of a string of characters, however I need the ability to limit the length of the output to lets say 5 characters (this will most likely become a variable number set by the user). I have been searching for about a week for something like this and the closest I have gotten is the following code.
Source.cpp:
#include <iostream>;
using namespace std;
void swap(char *fir, char *sec)
{
char temp = *fir;
*fir = *sec;
*sec = temp;
}
/* arr is the string, curr is the current index to start permutation from and size is sizeof the arr */
void permutation(char * arr, int curr, int size)
{
if(curr == size-1)
{
for(int a=0; a<size; a++)
cout << arr[a] << "";
cout << endl;
}
else
{
for(int i=curr; i<size; i++)
{
swap(&arr[curr], &arr[i]);
permutation(arr, curr+1, size);
swap(&arr[curr], &arr[i]);
}
}
}
int main()
{
string next;
char str[] = "abcdefghijklmnopqrstuvwxyz1234567890-";
permutation(str, 0, sizeof(str)-1);
cin.get();
cin.get();
}
This code works however it does not limit the length of the output. It sets the output length to the length of the given string. It also appears it might not account for multiple of the same letter/number in the output (this I am not 100% sure of).
Additionally, I will need to set special rules such as the hypen cannot be the first or last character in the output.
I have attempted to modify the above code by replacing sizeof(str)-1 with 5 however it will only "loop" through the first 5 characters in the string, so anything beyond "e" is not processed.
If anyone can assist on this it would be much appreciated.
EDIT:
Thank you to everyone for their excellent help I am now going to post my final product in case anyone else was trying to do the same thing.
Final Source:
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;
void swap(char *fir, char *sec)
{
char temp = *fir;
*fir = *sec;
*sec = temp;
}
void permutation(char * arr, int size, char* result, int depth, int limit)
{
ofstream myfile ("permutation.txt", fstream::app);
if(depth == limit)
{
for(int a=0; a<limit; a++){
myfile << result[a] << "";
cout << result[a] << "";
}
myfile << "\n";
cout << endl;
}
else
{
for(int i=0; i<size; i++)
{
result[depth] = arr[i];
permutation(arr, size, result, depth + 1, limit);
}
}
myfile.close();
}
int main()
{
ofstream myfile ("permutation.txt");
myfile << "";
myfile.close();
string answer;
char *rArray;
string startProcess = "N";
std::cout << "Welcome to permutation v1" << endl;
std::cout << "-------------------------" << endl;
std::cout << "Please enter how long the string should be: ";
std::getline (std::cin,answer);
int result = atoi(answer.c_str());
rArray = new char[result];
std::cout << "\n\nThank You!\n" << endl;
std::cout << "Please wait, generating possible character array for length of " << result << "." << endl;
std::cout << "Would you like to proceed? Y = yes & N = no: ";
std::getline (std::cin,startProcess);
char str[] = "abcdefghijklmnopqrstuvwxyz1234567890";
if(startProcess == "Y")
{
permutation(str, sizeof(str)-1, rArray, 0, result);
}
else
{
std::cout << "\n\nOperation Terminated. No permutations being generated..." << endl;
}
cin.get();
return EXIT_SUCCESS;
}

You need to limit the depth of the recursion
To give permutations of characters in the string, using each only once:
void permutation(char * arr, int currsize, intchar* sizeresult, int depth, int limit)
{
if(depth == limit)
{
for(int a=0; a<limit; a++)
cout << arr[a]result[a] << "";
cout << endl;
}
else
{
for(int i=curr;i=0; i<size; i++)
{
swap(&arr[curr],result[depth] &arr[i]);= arr[i];
permutation(arr, curr+1size, sizeresult, depth + 1, limit);
swap(&arr[curr], &arr[i]);
}
}
}
Call like this
permutation(str, 0, sizeof(str)-1, result, 0, 5);
To give permutations of characters in the string, using each character an unlimited number of times:
void permutation(char * arr, int size, char* result, int depth, int limit)
{
if(depth == limit)
{
for(int a=0; a<limit; a++)
cout << result[a] << "";
cout << endl;
}
else
{
for(int i=0; i<size; i++)
{
result[depth] = arr[i];
permutation(arr, size, result, depth + 1, limit);
}
}
}
Call like this
char result[5];
permutation(str, sizeof(str)-1, result, 0, sizeof(result));

This is not a tough job actually. If you can use recursion and a loop within that function you can solve it. I suggest use next_permutation function from the standard library.
The fact is time. Within 3 second you can process permutation for only 8 character. And the condition will be depended to requirement. Suppose in your example you can prune back if you need to omit hyphen in starting or ending.
Pseudo code of my implementation:
char array[] = "abcdee";
char eachPerm[6];
bool usedmatrix[6][6];
Recur(int depth, int n)
{
// you can return from here if this is not the right path, suppose '-'
// in first or last place.
if(depth == n)
{
print;
}
else
{
int i;
for(i= 0 to array.length)
{
if(array[i] is not used before)
eachPerm[depth] = array[i];
recur(depth+1, n);
}
}
}
Call this function initially recur(0, 5)

Related

Why is my program not working when I enter a charge number that matches the number in my array

Why is my program not working when I enter a charge number that matches the number in my array. Please Refer to the function
#include <iostream>
#include <cmath>
using namespace std;
string returnWord(int arr[], int SZ)
{
int nums = 0;
string answer;
cout << "Please enter a charge number: ";
cin >> nums;
for (int i = 0; i < SZ; i++) {
if (nums == arr[i]) {
answer = "This is Valid";
}
else {
answer = "This is Invalid"; // When I enter the valid number this is what prints out
}
}
return (answer);
}
int main()
{
const int SZ = 18;
int nums[SZ] = { 5658845, 4520125, 7895122, 8777541, 8451277, 1302850,
8080152, 4562555, 5552012, 5050522, 7825877, 1250255,
1005231, 6545231, 3852085, 7576651, 7881200, 4581002 };
string something = returnWord(nums, SZ);
cout << something << " ";
}
My program when ran will not properly print out "This is valid", even when I enter the correct number from my array. I don't understand why this is happening.
It will only print This is Valid if the last number in the array is valid because you continue the loop through the whole array and assign answer in each step.
You should return from the function early if the value you check is valid or return that it's invalid after the loop.
Example:
std::string returnWord(int arr[], size_t SZ) {
cout << "Please enter a charge number: ";
if (int nums; cin >> nums) {
for (size_t i = 0; i < SZ; i++) {
if (nums == arr[i]) {
return "This is Valid"; // return directly when it's found valid
}
}
}
return "This is Invalid"; // the whole array is checked, it was invalid
}
This for loop with the inner if statement
for (int i = 0; i < SZ; i++) {
if (nums == arr[i]) {
answer = "This is Valid";
}
else {
answer = "This is Invalid"; // When I enter the valid number this is what prints out
}
}
is logically incorrect. It can be interrupted at once when the current element of the array is not equal to the searched number.
Rewrite the loop for example the following way
std::string returnWord( const int arr[], size_t SZ )
{
int nums = 0;
std::cout << "Please enter a charge number: ";
std::cin >> nums;
size_t i = 0;
while ( i != SZ && nums != arr[i] ) ++i;
return i == SZ ? "This is Invalid" : "This is Valid";
}

get length of an array in C++

int grades[100];
int j = 0;
int len = sizeof(grades)/sizeof(grades[0]);
while (j < len)
{
cout << grades[j] << endl;
j++;
}
I have entered only 5 grades and I want to print only that entered grades then ho can I print that?
I have tried to use length of array but since I have created array of size 100, it is printing all unwanted characters at the end.
I have also used '\0' to get end of array but it is not working.
#include <vector>
std::vector<int> grades;
// add 3 grades
grades.push_back(4);
grades.push_back(1);
grades.push_back(9);
// https://www.cplusplus.com/reference/vector/vector/size/
auto size = grades.size();
Just keep track of the size when you read the numbers:
#include <iostream>
int main()
{
int const max_len = 100;
int arr[max_len];
std::cout << "Enter numbers: ";
int len = 0;
while (len < max_len && std::cin >> arr[len]) {
++len;
}
// you've read `len` numbers.
std::cout << "You've entered " << len << " numbers\n";
for (int i = 0; i != len; ++i) {
std::cout << arr[i] << '\n';
}
}
Your code returns the total number of elements the array can store.
Try this instead:-
#include <iostream>
int main()
{
int sample[10];
int length = 0;
for (int integer : sample)
{
if (integer != NULL)
{
length++;
// If you want to print the element as well -
std::cout << integer << std::endl;
}
}
}
Essentially what it does goes through all of the elements of the array and adds 1 to length if that element is not NULL (NULL means a null pointer, or if you're a beginner, just know it means basically nothing).
You can easily change int to any other type.
Hope it helps :)

How to end a user input array

So this is for a lab assignment and I already have it working, but one thing is bothering me. The assignment involves creating a 1-dimensional array and then manipulating it. I am supposed to allow a max of 100 inputs but the user does not have to use all 100. Right now, I am using a while statement to either break or allow another input to be entered. To break the statement, you have to enter a negative number (this is what I don't like and want to change). What other options are there to end the user input, once they are done entering their numbers? Is it possible to end the loop once you hit enter with nothing typed?
I have searched stackoverflow for the last 3 days and found some compelling stuff but could never get it to work.
Note, I get the void function is redundant here but that's besides the point (unless it actually affects my ability to achieve what I want).
Also, thanks in advance.
here is my code so far (my while statement is in the main)... be kind I'm a newbie to coding.
#include <iostream>
using namespace std;
void reverseElements(int array[], int size)
{
int tmp;
int j;
int i = size;
j = i - 1;
i = 0;
while (i < j)
{
tmp = array[i];
array[i] = array[j];
array[j] = tmp;
i++;
j--;
}
cout << "I will now reverse the elements of the array." << endl;
cout << endl;
for (i = 0; i < size; i++)
{
cout << array[i] << " " << endl;
}
}
int main()
{
const int NUM_ELEMENTS = 100;
int iArr[NUM_ELEMENTS];
int i;
int myInput;
cout << "Enter your numbers, then enter a negative number to finish" << endl;
cout << endl;
for (i = 0; i < NUM_ELEMENTS; i++) //loop to obtain input
{
cin >> myInput;
if (myInput < 0) //checks for negative number to end loop
{
break;
}
else //continues to allow input
{
iArr[i] = myInput;
}
}
cout << endl;
reverseElements(iArr, i);
return 0;
}
Probably the easiest solution: let your user choose how many numbers to write before actually writing them.
int readNumbersCount()
{
int const numbersMin = 1;
int const numbersMax = 100;
int numbersCount = -1;
while (numbersCount < numbersMin || numbersCount > numbersMax)
{
std::cout <<
"How many numbers are you going to enter? Choose from " <<
numbersMin << " to " << numbersMax << ":\n";
std::cin >> numbersCount;
}
return numbersCount;
}
int main()
{
int const numbersCount = readNumbersCount();
for (int i = 0; i < numbersCount; ++i)
{
// read the numbers etc.
}
return 0;
}
I wrote readNumbersCount() as a separate function to extract numbersMin and other "one-use" identifiers from main() and to make main()'s numbersCount const.
I have edited the main function a little bit.
Here the user is asked how many elements he wants to enter .
and doing the memory allocation dynamically so as to save space
int main()
{ int n=101;
while(n>100){
cout<<"How many numbers do you want to enter";
cin>>n;
}
int *ptr=new(nothrow)int[n];
for (int i=0;i<n;i++){
cout << "Enter your number" << endl;
cin>>ptr[i];
}
cout << endl;
reverseElements(ptr, n);
return 0;
}

Controlling input in c++ and display

Question :
Your program is to use the brute-force approach in order to find the Answer to Life, the Universe, and Everything. More precisely... rewrite small numbers from input to output. Stop processing input after reading in the number 42. All numbers at input are integers of one or two digits.
Example
Input:
1
2
88
42
99
Output:
1
2
88
So that is the question, however i am still a beginner and unable to have an input tab like that. In my program, how should i modify it such that it still accepts numbers after 42, however, it does not print them? currently I am only able to terminate the input at 42.
#include <iostream>
using namespace std;
int main()
{
int A[100], num, i=0,k,count;
for(count = 0; count != 1;){
cin >> k;
if (k!=42){
A[i] = k;
i++;
}
else
count =1;
}
cout << endl;
for (count = 0; count <i; count ++){
cout << A[count] << endl;
}
}
You don't have to use array at all. You can print the value just after reading it. Exit when you read 42. This may help you.
#include <iostream>
using namespace std;
int main() {
// your code goes here
int n ;
for(; ;) {
cin >> n ;
if(n == 42) {
return 0 ;
}
cout << n << endl ;
}
return 0;
}
Pretty sure the easiest way to do so is to simply ask the user how many numbers they need to enter.
#include <iostream>
using namespace std;
int main()
{
int A[100], k, count;
cout << "How many numbers do you want to enter ? ";
cin >> count; //this is to count how many numbers the user wants to enter
for(int i(0); i < count; ++i) //put all the numbers user enters in your array
{
cin >> k;
A[i] = k;
}
cout << endl;
for (int i(0); i < count; ++i)
{
if (A[i] == 42) //if the element at index i is == 42 then stop displaying the elements
break;
else
cout << A[i] << " "; //else display the element
}
cout << endl;
return 0;
}
Else you would need to put everything in a string and parse it and i'm not quite sure how that goes as I am a beginner as well.
EDIT:
Actually here you go, I think that is correct and does exactly what you want.
Do keep in mind that if user enters p.e "1 88 442" it will output "1 88 4" because it found "42" in "442". But it should be okay because you precised input numbers should only be two digits max.
#include <iostream>
using namespace std;
int main()
{
string k;
getline(cin, k);
cout << endl;
for (unsigned int i(0); i < k.length(); ++i)
{
if (!((k[i] == '4') && (k[i+1] == '2'))) //if NOT 4 followed by 2 then display
cout << k[i];
else
break; //else gtfo
}
cout << endl;
return 0;
}
Use a bool value to control the execution of your code.
#include <iostream>
#define N_INPUT 100
#define THE_ANSWER 42
using namespace std;
int main()
{
int array[N_INPUT], i, input, count=0;
bool universeAnswered = false;
for (i = 0; i < N_INPUT; i++) {
cin >> input;
if (!universeAnswered)
{
if (input == THE_ANSWER) {
universeAnswered = true;
} else {
array[count] = input;
count++;
}
}
}
for (i = 0; i < count; i++) {
cout << array[i] << endl;
}
}
(My code was not tested)
You just have to have some state to see if you have seen 42 already, and only output if you haven't
#include <iostream>
int main()
{
bool output = true;
for (int n; std::cin >> n;)
{
output &= (n != 42);
if (output)
{
std::cout << n << std::endl;
}
}
return 0;
}

Having trouble with converting a decimal number to a binary

I'm making a program that converts a string that the user enters such as "APPLE" into a binary number through the corresponding ASCII numbers that represent each character of the string "APPLE." For example A = 65 in ascii etc.. I've created a function that converts the string into a binary but it doesn't seem to be working. It displays "The equivalent binary number is: 0031F240for A" in an infinite loop and gives me "0031F240for" instead of being in the binary version of 65. I know this function works for converting a decimal number into binary because I've tried it, but I think my implementation of the bin[] array is messing things up. Any help would be appreciated.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <fstream>
using namespace std;
class RandomString
{
private:
string input;
string bin[100];
public:
RandomString() : bin(), input("")
{
}
void getData()
{
cout << "Enter the word to be encoded into a binary file.";
cin >> input;
}
void numToBin()
{
int i = 0;
int len = input.length();
int num = int(input[i]);
for(int i = 0; i < len; i++)
{
while(num != 0)
{
if (num % 2 == 0)
bin[i].insert(0, "0");
else
bin[i].insert(0, "1");
num = num / 2;
cout << "The equivalent binary number is: " << bin << "for " << input[i] << endl;
}
}
}
void display()
{
}
};
I haven't test if the result is correct but this code convert a string to binary. Probably you have to modify it to fit with ASCII codes.
void DecimalToBinary(char a,std::vector<char>& v)
{
if(a==0)
v.push_back(0);
if(a==1)
v.push_back(1);
else
{
v.push_back(a%2);
DecimalToBinary(a/2,v);
}
}
int main()
{
std::vector<char> v;
std::string line;
getline(std::cin,line);
std::istringstream input(line);
char c;
while(input >> c)
{
DecimalToBinary(c,v);
}
std::copy(v.begin(),v.end(),std::ostream_iterator<int>(std::cout,""));
}
First Your while loop never stops because you don't change the value of i inside the while loop, so int(input[i]) has always the same value, you have to use break somewhere or i++, but I don't know if the result is correct,I think recursion is better than while in this situation, but anyway try the following:
void numToBin()
{
int i = 0;
int len = input.length();
int num = int(input[i]);
for(int i = 0; i < len; i++)
{
while(int(input[i]) != 0)
{
if (num % 2 == 0)
{
bin[i].insert(0, "0");
break;
}
else
{
bin[i].insert(0, "1");
num = num / 2;
}
cout << "The equivalent binary number is: " << bin << "for " << input[i] << endl;
}
}
}
Second, doing std::cout << bin you print a memory address, not the contents of the bin.
while(int(input[i]) != 0)
{
if (num % 2 == 0)
bin[i].insert(0, "0");
else
{
bin[i].insert(0, "1");
}
num = num / 2;// this line should be in both case.
cout << "The equivalent binary number is: " << bin << "for " << input[i] << endl;
}
I've changed num = num / 2 for both cases. Please check it.
You may want to change the 'bin' in
cout << "The equivalent binary number is: " << bin
to 'bin[i]'.
Because 'bin' is a string array, also the pointer/address to the string array, so 'cout << bin' will always output the address.