How to get every possible string of n characters in c++? - c++

I know it is possible to use n nested for loops to get the result. This however isn't very flexible. If I wanted to get every string of n+2 characters I would have to write an extra two for loops.
I'm pretty sure I should use a parameter called n_Letters and use some kind of recursion. Any ideas? This is how my code looks right now. It gives all the 3 character combinations.
#include <iostream>
#include <string>
using namespace std;
void StringMaker(){
for(int firstLetter = 97; firstLetter < 123; firstLetter++){
char a = firstLetter;
for(int secondLetter = 97; secondLetter < 123; secondLetter++){
char b = secondLetter;
for(int thirdLetter = 97; thirdLetter < 123; thirdLetter++){
char c = thirdLetter;
cout << a << b << c << endl;
}
}
}
}
int main() {
StringMaker(); // I could add a parameter n_Letters here
}

This is a simple tree traversal problem that can easily be solved using recursion. Using a counter (count) and accumulator (partial) recur on your function for each letter until count is zero then print partial.
#include <iostream>
#include <string>
void StringMaker(int count, std::string partial = "") {
if (count == 0) {
std::cout << partial << '\n';
}
else {
for (char letter = 'a'; letter <= 'z'; ++letter) {
StringMaker(count - 1, partial + letter);
}
}
}
int main() {
StringMaker(3);
return 0;
}
Edit: It seems their are some concerns with my answer regarding memory allocations. If it's a concern for you, consider this alternative solution. Increment the first character if it isn't 'z', otherwise set it to a and repeat with the the second character. Do this until the last character is set from z to a. This acts as a sort of base 26 counter with count digits.
#include <iostream>
#include <string>
void StringMaker(size_t count)
{
std::string data(count, 'a');
size_t i = 0;
do
{
std::cout << data << '\n';
for (i = 0; i < count; ++i)
{
auto & next_char = data[i];
if (next_char < 'z') {
++next_char;
break;
}
else {
next_char = 'a';
}
}
} while (i != count);
}
int main() {
StringMaker(3);
return 0;
}

Here is my just-for-fun solution:
void StringMaker(int n)
{
int base = ('z' - 'a' + 1);
std::string str(n, '\0');
for(int i = 0; i < int_pow(base, n); ++i)
{
for(int j = 0; j < n; ++j)
{
str[n - j - 1] = 'a' + i / int_pow(base, j) % base;
}
cout << str << '\n';
}
}
Suppose we have i written in numerical system with base 26 (from a to z), so increment i with n = 4 give us aaaa, aaab and so on

Related

Is there a way to write the same code without using void functions?

I'm a C++ beginner, and I was wondering how I can rewrite this code without using void functions, and use it all in main().
I know that this program needs to get the longest consecutive substring in a string,
but is there another way to do it without using functions?
substring in C++
#include <iostream>
using namespace std;
void longestConsecutivecharacter(string letters){
int finalResult = 1;
int letterCounter = 1;
char flcrcs;
for (int i = 1; i < letters.size(); i++) {
if (letters[i] == letters[i + 1]) {
++letterCounter;
}
else {
if(letterCounter>finalResult)
flcrcs=letters[i-1];
finalResult = max(finalResult, letterCounter);
letterCounter = 1;
}
}
finalResult = max(finalResult, letterCounter);
for(int i=0;i<finalResult;i++)
cout<<flcrcs;
};
int main(){
string letters;
cout << "Enter a string: ";
cin>>letters;
cout << "The first longest consecutive repeating character substring is: ";
longestConsecutivecharacter(letters);
return 0;
}
Why do you want to do it without functions? This method is better and more portable.
If you still want to, you can just take the code and put it in main, like this:
int main(){
string letters;
cout << "Enter a string: ";
cin>>letters;
int finalResult = 1;
int letterCounter = 1;
char flcrcs;
for (int i = 1; i < letters.size(); i++) {
if (letters[i] == letters[i + 1]) {
++letterCounter;
}
else {
if(letterCounter>finalResult) {
flcrcs=letters[i-1];
finalResult = max(finalResult, letterCounter);
letterCounter = 1;
}
}
finalResult = max(finalResult, letterCounter);
for(int i=0;i<finalResult;i++)
cout << "The first longest consecutive repeating character substring is: ";
cout<<flcrcs;
};

How do I count the occurences of each digit in a string using int* count (const string& s) in c++?

Note: I can't use maps or anything in the algorithm library
I only have the main function, but am completely lost on how I'm supposed to write the function
#include <string>
#include <iostream>
using namespace std;
int* count(const string& s);
int main() {
string userinput = "random word";
int *counts = count(userinput);
for (int i = 0; i < 11; i++) {
cout << "Letter " << i << " occured " << counts[i] << " times.";
}
system("pause");
return 0;
}
int* count(const string& s) {
for (int i = 0; i < 11; i++)
{
return s[i];
}
}
The int* count function is not correct and will not compile. How can I write a function that will work in returning the occurences?
How do I count the occurences of each digit in a string using int*
count (const string& s) in c++? Note: I can't use maps or anything in
the algorithm library
A few things to note:
Always bad idea, if we don't follow the simplest way of approaching a problem and it's sad that teachers are the promoters of such situations.
There is not need of a int*. which does not provide your solution at any manner. If it would have been array to count the chars of your string, then it might make sense(i.e, pointer to the array).
Try to avoid practicing with using namespace std;
You can do something like as follows, if you are not allowed to use std::map<char, int>(hint for your alternative solution).
I have commented on it, for better understanding.
#include <string>
#include <iostream>
#include <cstddef>
// consider 128 ASCII decimal and their coresponding character codes
int charASCIIArray[128] = {0};
void count_char(const std::string& s)
{
for(const auto& it: s)
{
if(('A' <= it && it <= 'Z') || // if char between (A,B,....,Z) or
('a' <= it && it <= 'z') ) // between (a,b,....,z)
charASCIIArray[static_cast<int>(it)]++; // we count each corresponding array then
}
}
int main()
{
std::string userinput = "random words WITH *- aLl";
count_char(userinput);
for(std::size_t index = 0; index < 128; ++index)
if(charASCIIArray[index] != 0)
std::cout << "Letter " << static_cast<char>(index) // convert back to char
<< " occured " << charASCIIArray[index] << " times.\n";
return 0;
}
See live action here: https://www.ideone.com/uFG2HJ
Letter H occured 1 times.
Letter I occured 1 times.
Letter L occured 1 times.
Letter T occured 1 times.
Letter W occured 1 times.
Letter a occured 2 times.
Letter d occured 2 times.
Letter l occured 1 times.
Letter m occured 1 times.
Letter n occured 1 times.
Letter o occured 2 times.
Letter r occured 2 times.
Letter s occured 1 times.
Letter w occured 1 times.
UPDATE
Inspired from #Fei Xiang's comment, here is two over engineered solutions:
Firstly, with returning pointer to a dynamic array(which will meet actual
question requirements): https://www.ideone.com/ouHqK4
#include <string>
#include <iostream>
#include <cstddef>
int* count_char(const std::string& s)
{
// consider 128 ASCII decimal and their coresponding character codes
int *charASCIIArray = new int[128]{0};
for(const auto& it: s)
{
if(('A' <= it && it <= 'Z') || // if char between (A,B,....,Z) or
('a' <= it && it <= 'z') ) // between (a,b,....,z)
charASCIIArray[static_cast<int>(it)]++; // we count each corresponding array then
}
return charASCIIArray;
}
int main()
{
std::string userinput = "random words WITH *- aLl";
int *charASCIIArray = count_char(userinput);
for(std::size_t index = 0; index < 128; ++index)
if(charASCIIArray[index] != 0)
std::cout << "Letter " << static_cast<char>(index) // convert back to char
<< " occured " << charASCIIArray[index] << " times.\n";
delete[] charASCIIArray;
return 0;
}
Secondly with smart pointer(std::unique_ptr) : https://www.ideone.com/dfc62J
#include <string>
#include <iostream>
#include <cstddef>
#include <memory>
#include <utility>
std::unique_ptr<int[]> count_char(const std::string& s)
{
// consider 128 ASCII decimal and their coresponding character codes
std::unique_ptr<int[]> charASCIIArray = std::unique_ptr<int[]>(new int[128]{0});
for (const auto& it : s)
{
if (('A' <= it && it <= 'Z') || // if char between (A,B,....,Z) or
('a' <= it && it <= 'z')) // between (a,b,....,z)
charASCIIArray[static_cast<int>(it)]++; // we count each corresponding array then
}
return std::move(charASCIIArray);
}
int main()
{
std::string userinput = "random words WITH *- aLl";
std::unique_ptr<int[]> charASCIIArray = count_char(userinput);
for (std::size_t index = 0; index < 128; ++index)
if (charASCIIArray[index] != 0)
std::cout << "Letter " << static_cast<char>(index) // convert back to char
<< " occured " << charASCIIArray[index] << " times.\n";
return 0;
}
Not so sure you wanted this answer but I hope it helps
you can seperate it into seperate function but I did it in a single go
#include <iostream>
#include <string>
using namespace std;
int main()
{
string userInput = "random word";
int fCharacter[256];
for (int i = 0; i <= 255; i++)
{
fCharacter[i] = 0;
}
for (int i = 0; i < userInput.length(); i++)
{
fCharacter[userInput[i]]++;
}
cout << "The character changes are as follows" << endl;
for (int i = 0; i <= 255; i++)
{
if (fCharacter[i] != 0)
{
cout << (char)i << endl;
}
}
system("pause");
return 0;
}

Getting out of a while loop earlier with cout using c++

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
string sentence = "some random sentence";
int i = 0; //runs through the bigger string
int j = 0; //runs through the smaller string
int k = 0; //variable to mark the position where the string starts being equal in order to delete it using substring
string remove = "random";
int a = sentence.size();
int b = remove.size();
while (i < a)
{
if (sentence[i] == remove[j])
{
if (b == j - 1)
{
cout << sentence.substr(0, k) << sentence.substr(i, (a - 1));
break;
}
else
{
i++;
j++;
}
}
else
{
i++;
j = 0;
k++;
}
}
return 1;
}
I want to remove the word random from the bigger string and print it out but when I run the code, it does not return anything. What's missing?
I already tried putting a break right below de "cout", but it does not work.
Thank you :)
As b == 6, j would have to be 7 in order for b == j-1 to become true. But remove[6] is the terminating \0 of the random string, so j can never grow beyond 6.
Here is the code I edited
if (b-1 == j)
{
cout << sentence.substr(0, k) << sentence.substr(i+2, (a - 1));
break;
}
This is assuming, you have spaces between the words.

Recursive function to generate string does not contain two adjacent identical substring c++

I have a task that is difficult for me to handle. The task is: Create recursive function that can be generate a string of length N (N <= 100), formed by the letters 'A', 'B' and 'C' and does not containing two identical adjacent substring. For example: enter for N = 6 and the program should generate such a string in which no one else to repeated substrings: ABACAB. Wrong strings are: AABACA - because 'A' is to 'A'; ABCBCA - as 'BC' is to 'BC' and ABCABC is also wrong because 'ABC' is to 'ABC'.
I made a version of the program but an iterative way, here is the code:
#include <iostream>
#include <ctime>
using namespace std;
const char letters[] = "ABC";
char generate_rand()
{
return letters[rand() % 3];
}
int check(char *s, int pos)
{
for (int i = 1; i <= (pos + 1)/2; i++)
{
int flag = 1;
for (int j = 0; j < i; j++)
if (s[pos-j] != s[pos-i-j])
{
flag = 0;
break;
}
if (flag)
return 1;
}
return 0;
}
int main()
{
char s[100];
int n;
cout << "enter n: ";
cin >> n;
srand(time(NULL));
for (int i = 0; i < n; i++)
{
do
{
s[i] = generate_rand();
} while (check(s, i));
cout << s[i] << " ";
}
cout << " ok" << endl;
system("pause");
return 0;
}
I think the entrance of the recursive function may need to be the number of characters in the string, which will seek to repeat with an adjacent string and each time increased by 1, but not more than half the length of the original string, but do not know how to do it.
So lets start with a simple recursive function which prints 10 letters but doesn't check anything:
void addLetter(char* buf, int max_length)
{
int len = strlen(buf);
buf[len] = generate_rand();
if (strlen(buf) < max_length)
addLetter(buf);
}
int main()
{
srand(time(NULL)); //I forgot srand!
int max_length = 10; //ask user to input max_length, like you had earlier
char buf[100];
memset(buf,0,sizeof(buf));
addLetter(buf, max_length);
printf("\n%s\n", buf);
return 0;
}
Now lets change the recursive function, get it to check just 1 letter:
void addLetter(char* buf, int max_length)
{
int len = strlen(buf);
buf[len] = generate_rand();
if (len > 0)
{
if (buf[len] == buf[len-1])
buf[len] = 0;
}
if (strlen(buf) < max_length)
addLetter(buf);
}
Next step, check 2 letters with previous ones etc. You should be able to take it from here.

Reverse n characters in the string (there is no spaces in string) without using built-in functions in c++

I have a string like str="ABCDEFGHIJK";
need o/p like this str="CBAFEDIHGJK"
am getting "CBA" correctly after that its not printing anything.
can anyone check the following code and let me know where is the problem?
int main()
{
string str="ABCDEFGHIJK";
char str1[10],rev[10];
int n=str.length(),count=0,c=3,k=0,j=0;
for(int i=0;i<n;i++)
{
str1[i]=str[i];
count++;
cout<<str1[i]<<" and "<<count<<"and "<<c<<endl;
if(count==c)
{
cout<<"Entered into if loop"<<count<<"and"<<c<<"and "<<k<<endl;
cout<<c<<" and "<<k<<endl;
while(j<c)
{
rev[j]=str1[c-k-1];
cout<<rev[j]<<" and "<<str1[c-k-1]<<endl;
j++;
k++;
}
count=0;
}
/*else
{
if(count < c && str[i]=='\0')
{
for(int k=0;k<count;k++)
{
rev[k]=str1[count-1];
count--;
count=0;
}
}
}*/
}
cout<<"The string is: "<<rev<<endl;
return 0;
}
Please help me on this.
No need to use a c++ string object for this use-case; just use a normal char *.
Also, always make sure you store enough room for the string null-terminator character ('\0'). This is required as c string functions assume your string is terminated in this way.
Following will reverse string in ansi C89
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void reverse(char *in, char *rev)
{
int i, n;
n = strlen(in);
for(i = n-1; i>=0; i--)
{
rev[n-i-1] = in[i];
}
/* add the null-terminator */
rev[n] = '\0';
}
int main()
{
char *str = "ABCDEFGHIJK";
char str1[12], temp;
char triplet[4];
char rev_triplet[4];
int index;
triplet[3] = '\0';
rev_triplet[3] = '\0';
str1[0] = '\0';
for(index = 0; index < strlen(str); index += 3)
{
memcpy(triplet, str + index, 3 * sizeof(char));
reverse(triplet, rev_triplet);
strcat(str1, rev_triplet);
}
printf("Initial string is: %s\n", str);
printf("Reverse string is: %s\n", str1);
return 0;
}
Outputs
$ ./test
Initial string is: ABCDEFGHIJK
Reverse string is: CBAFEDIHGKJ
If you intend to use C++ (and not C) for this:
#include <algorithm>
#include <iostream>
#include <string>
std::string reverse_triples(std::string s)
{
const unsigned int N = 3;
for (int i = 0, j = N - 1; i < s.length() - (s.length() % N); i += N, j += N)
{
std::swap(s[i], s[j]);
}
return s;
}
int main()
{
std::string s = "ABCDEFGHIJK";
std::string rs = reverse_triples(s);
std::cout << "Reversed Triples: " << rs << std::endl;
return 0;
}
Whatever value of N you need can be modified (and even supplied as a function parameter if you want). You only need to swap the outer characters (so all the elements below N / 2 will be swapped with the elements above N / 2). For N == 3, it is just a single swap. If you want to do it more generically:
#include <algorithm>
#include <iostream>
#include <string>
std::string reverse_substrings(std::string s, unsigned int substring_size)
{
for (int i = 0, j = substring_size - 1; i < s.length() - (s.length() % substring_size); i += substring_size, j += substring_size)
{
std::reverse(s.begin() + i, s.begin() + j + 1);
}
return s;
}
int main()
{
std::string s = "ABCDEFGHIJK";
std::string rs = reverse_triples(s, 4); // passing 3 gets you the same results as before
std::cout << "Reversed Triples: " << rs << std::endl;
return 0;
}
First, let us examine how std::reverse might be implemented. It uses iterators.
template <class BidirectionalIterator>
void reverse (BidirectionalIterator first, BidirectionalIterator last)
{
while ((first!=last)&&(first!=--last)) {
std::iter_swap (first,last);
++first;
}
}
We can extend the logic to use indices instead of iterators, where i and j represent iterators (positions) and s[i] and s[j] represent the data pointed to by the iterators.
void reverse(std::string& s)
{
int i = 0;
int j = s.size();
while ((i != j) && (i != (--j)))
{
std::swap(s[i], s[j]);
++i;
}
}
Now you want to reverse "chunks" rather than the entire string.
void reverse(int n, std::string& s)
{
int beg = 0;
int end = beg + n;
int size = s.size();
// We're going to modify s in place
// So store a copy
std::string copy = s;
s = "";
// Add + 1 to avoid the loop cutting off short
// Or do i <= size / n;
for (int i = 0; i < size / n + 1; i++)
{
std::string chunk(copy.begin() + beg, copy.begin() + end);
// If there's no n sized chunks left
// don't reverse
if (end < size)
reverse(chunk);
s += chunk;
beg += n;
// Don't go past the size of the string
end += (end + n > size ? size - end : n);
}
}
int main()
{
std::string s("ABCDEFGHIJK");
std::string target("CBAFEDIHGJK");
reverse(3, s);
std::cout << s << "|" << target <<"|\n";
std::cout << s.size() << " " << target.size() << "\n"; // 11 11
std::cout << std::boolalpha << (s == target); // true
return 0;
}