How to list all strings of length 12 in C++? - c++

I'm a novice programmer studying my own. I tried to make a program that lists all strings of length 12 such as its characters are from a-z. However, there seems to be a bug I could find. It outputs for example The word is ). Could anyone tell me what I'm doing wrong, and is there some easier way to do the program?
#include <iostream>
#include <string>
int main(int argc, char *argv[])
{
using namespace std;
string l ("qwertyuiopasdfghjklzxcvbnm");
string test ("");
for(int i1 = 0;i1 < 26;++i1)
for(int i2 = 0;i2 < 26;++i2)
for(int i3 = 0;i3 < 26;++i3)
for(int i4 = 0;i4 < 26;++i4)
for(int i5 = 0;i5 < 26;++i5)
for(int i6 = 0;i6 < 26;++i6)
for(int i7 = 0;i7 < 26;++i7)
for(int i8 = 0;i8 < 26;++i8)
for(int i9 = 0;i9 < 26;++i9)
for(int i10 = 0;i10 < 26;++i10)
for(int i11 = 0;i11 < 26;++i11)
for(int i12 = 0;i12 < 26;++i12) {
test = l[i1]+l[i2]+l[i3]+l[i4]+l[i5]+l[i6]+l[i7]+l[i8]+l[i9]+l[i10]+l[i11]+l[i12];
cout << "The word is " << test << "." << endl;
test = "";
}
return 0;
}

l[i1]+l[i2] won't do what you expect. You're adding two expressions of type char so you'll get a result of type int.
An easy fix is:
test = std::string() + l[i1]+l[i2]+l[i3]+l[i4]+l[i5]+l[i6]+l[i7]+l[i8]+l[i9]+l[i10]+l[i11]+l[i12];

As I mentioned in my comment, when you see a permutations problem like this you should think of how to write a recursive algorithm.
In this case, ask yourself what each step (level) looks like. Well, you're given the string up to that point, you need to iterate through the letters, and you need to call the next level down each time so it can continue the process.
Working that out into code, "given the string up to this point" means your recursive function is passed in the prefix string, and a number indicating where it is in the chain:
void print_all_strings(const std::string& prefix, unsigned remain) {
Iterating through the letters is something you've already got (use a for loop), but the way you're doing it is not great. Instead of typing all the characters into a string and iterating through those characters, you're better off realizing that you can iterate through characters in a for loop like you can iterate through numbers, since characters are numbers in C++ (and C). In other words, 'a' + 1 == 'b' and so forth. So your loop becomes:
for(char c = 'a'; c <= 'z'; c++)
Finally, you need to handle the next level down. That means using the prefix and remain parameters to figure out what to do next. Well, there's one thing we know: if there are 0 letters left, then don't add a letter, but instead print the string and return!
if(remain == 0) {
cout << "The word is " << prefix << "." << endl;
return;
}
In other cases, we need to add a letter. That's where std::string + char => std::string comes in. (Note that char + char => char!)
print_all_strings(prefix + c, remain - 1);
Putting it all together:
void print_all_strings(const std::string& prefix, unsigned remain) {
if(remain == 0) {
cout << "The word is " << prefix << "." << endl;
return;
}
for(char c = 'a'; c <= 'z'; c++)
print_all_strings(prefix + c, remain - 1);
}
int main(int argc, char *argv[])
{
print_all_strings("", 12);
return 0;
}
But then, as CiaPan explained, your computer will die before this program finishes.

Related

C++ outputs strange characters instead of numbers (Windows)

I need to program a lotto generator for my education that will randomly roll numbers and check for duplicate entries and replace them otherwise. When I start the program there are no error messages and the program runs but I only see strange characters instead of numbers. A picture of the problem
What is wrong with my code?
#include <iostream>
#include <array>
#include <time.h>
std::array<unsigned char, 6> lottoZahlen = {0, 0, 0, 0, 0, 0};
void arrayFuellen();
unsigned char checkDuplikate(unsigned char);
void arraySortieren();
int main()
{
arrayFuellen();
arraySortieren();
std::cout << "\n---- Ihre Glueckszahlen lauten: ----" << std::endl;
for (unsigned char lottoGlueck : lottoZahlen)
{
std::cout << lottoGlueck << std::endl;
}
std::cout << "---- Glueckszahlen Ende ----" << std::endl;
}
void arrayFuellen()
{
srand(time(NULL));
unsigned char wuerfelZahl = 0;
unsigned char wuerfelZahlChecked = 0;
for (unsigned char i = 0; i < sizeof(lottoZahlen); i++)
{
wuerfelZahl = rand() % 45 + 1;
wuerfelZahlChecked = checkDuplikate(wuerfelZahl);
lottoZahlen[i] = wuerfelZahlChecked;
}
}
unsigned char checkDuplikate(unsigned char checkZahl)
{
srand(time(NULL));
bool dublette = false;
do
{
dublette = false;
for (unsigned char j = 0; j < sizeof(lottoZahlen); j++)
{
if (checkZahl == lottoZahlen[j])
{
checkZahl = rand() % 45 + 1;
dublette = true;
}
}
} while (dublette);
return checkZahl;
}
void arraySortieren()
{
unsigned char merker = 0;
bool vertauscht = false;
do
{
vertauscht = false;
for (unsigned char i = 1; i < sizeof(lottoZahlen); i++)
{
if (lottoZahlen[i - 1] > lottoZahlen[i])
{
merker = lottoZahlen[i];
lottoZahlen[i] = lottoZahlen[i - 1];
lottoZahlen[i - 1] = merker;
vertauscht = true;
}
}
} while (vertauscht);
}
"char" is a type that is used to store characters, and the output stream will interpret it as such in your for-loop. So if you have value 65, it will actually be displayed as a capital A (which has ASCII value 65). To display numbers, you should use a type that the output stream recognizes as a number, such as "int".
There are several ways of doing what you want, printing char as integer/decimal value:
using casging int():
std::cout << int(lottoGlueck) << "\n";
using good old (C style) printf(), some would say do not use this, but there are advantages and disadvantages to using printf().
printf("%d\n", lottoGlueck);
As suggested, you can use std::to_string(), I personally do not recommend this for printing a single character, simply because it converts a character to a string to print out an integer.
In production code I use number 1, in debugging I use 2. There are disadvantages/advantages to using both, but you can read this to better understand those.
When it comes to pinging strings as decimal values, you have std::to_string() and also std::cout << std::dec << string << "\n".
you are printing non printable characters:
https://upload.wikimedia.org/wikipedia/commons/d/dd/ASCII-Table.svg
the ones between [] are not printable characters.
if you write: int i = 5 and then std::cout << i
it will print the corresponding character, with value 5. But the value 5 is not the character '5', so if you expect it to be a printable number, you need to convert it:
std::cout << std::to_string(i)
(not sure if this was your intention though :) )
In addition to the answers to your question, you can check whether your value is printable or not by using isprint().
std::cout << isprint(lottoGlueck) << std::endl;
This will print 0 (false) if your value is non-printable.

Prevent loop from echoing if another same-value array element has been already echoed in C++

First of all, sorry for the mis-worded title. I couldn't imagine a better way to put it.
The problem I'm facing is as follows: In a part of my program, the program counts occurences of different a-zA-Z letters and then tells how many of each letters can be found in an array. The problem, however, is this:
If I have an array that consists of A;A;F;A;D or anything similar, the output will be this:
A - 3
A - 3
F - 1
A - 3
D - 1
But I am required to make it like this:
A - 3
F - 1
D - 1
I could solve the problem easily, however I can't use an additional array to check what values have been already echoed. I know why it happens, but I don't know a way to solve it without using an additional array.
This is the code snippet (the array simply consists of characters, not worthy of adding it to the snippet):
n is the size of array the user is asked to choose at the start of the program (not included in the snippet).
initburts is the current array member ID that is being compared against all other values.
burts is the counter that is being reset after the loop is done checking a letter and moves onto the next one.
do {
for (i = 0; i < n; i++) {
if (array[initburts] == array[i]) {
burts++;
}
}
cout << "\n\n" << array[initburts] << " - " << burts;
initburts++;
burts = 0;
if (initburts == n) {
isDone = true;
}
}
while (isDone == false);
Do your counting first, then loop over your counts printing the results.
std::map<decltype(array[0]), std::size_t> counts;
std::for_each(std::begin(array), std::end(array), [&counts](auto& item){ ++counts[item]; });
std::for_each(std::begin(counts), std::end(counts), [](auto& pair) { std::cout << "\n\n" << pair.first << " - " pair.second; });
for (i = 0; i < n; i++)
{
// first check if we printed this character already;
// this is the case if the same character occurred
// before the current one:
bool isNew = true;
for (j = 0; j < i; j++)
{
// you find out yourself, do you?
// do not forget to break the loop
// in case of having detected an equal value!
}
if(isNew)
{
// well, now we can count...
unsigned int count = 1;
for(int j = i + 1; j < n; ++j)
count += array[j] == array[i];
// appropriate output...
}
}
That would do the trick and retains the array as is, however is an O(n²) algorithm. More efficient (O(n*log(n))) is sorting the array in advance, then you can just iterate over the array once. Of course, original array sequence gets lost then:
std::sort(array, array + arrayLength);
auto start = array;
for(auto current = array + 1; current != array + arrayLength; ++current)
{
if(*current != *start)
{
auto char = *start;
auto count = current - start;
// output char and count appropriately
}
}
// now we yet lack the final character:
auto char = *start;
auto count = array + arrayLength - start;
// output char and count appropriately
Pointer arithmetic... Quite likely that your teacher gets suspicious if you just copy this code, but it should give you the necessary hints to make up your own variant (use indices instead of pointers...).
I would do it this way.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string s;
vector<int> capCount(26, 0), smallCount(26, 0);
cout << "Enter the string\n";
cin >> s;
for(int i = 0; i < s.length(); ++i)
{
char c = s.at(i);
if(c >= 'A' && c <= 'Z')
++capCount[(int)c - 65];
if(c >= 'a' && c <= 'z')
++smallCount[(int)c - 97];
}
for(int i = 0; i < 26; ++i)
{
if(capCount[i] > 0)
cout << (char) (i + 65) << ": " << capCount[i] << endl;
if(smallCount[i] > 0)
cout << (char) (i + 97) << ": " << smallCount[i] << endl;
}
}
Note: I have differentiated lower and upper case characters.
Here's is the sample output:
output

difference between string size() function and strlen in this particular case

I recently did this question
Specification:
Input Format The first line contains the number of test cases, T. Next,
T lines follow each containing a long string S.
Output Format For each long string S, display the number of times SUVO
and SUVOJIT appears in it.
I wrote the following code for this :
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int suvo = 0;
int suvojit = 0;
string s;
cin >> s;
for (int i = 0; i <= s.size() - 7; i++) {
if (s.substr(i, 7) == "SUVOJIT")
suvojit++;
}
for (int i = 0; i <= s.size() - 4; i++) {
if (s.substr(i, 4) == "SUVO")
suvo++;
}
cout << "SUVO = " << suvo - suvojit << ", SUVOJIT = " << suvojit << "\n";
}
return 0;
}
The code about gave out of bounds exception for substr() function for this test case:
15
RSUVOYDSUVOJITNSUVOUSUVOJITESUVOSUVOSGSUVOKSUVOJIT
SUVOJITWSUVOSUVOJITTSUVOCKSUVOJITNSUVOSUVOJITSUVOJITSUVOSUVOSUVOJITTSUVOJ
SUVOSUVOSUVOJITASUVOJITGCEBISUVOJITKJSUVORSUVOQCGVHRQLFSUVOOHPFNJTNSUVOJITKSSUVO
SUVOJITSUVOJITJGKSUVOJITISUVOJITKJLUSUVOJITUBSUVOX
MMHBSUVOFSUVOFMSUVOJITUMSUVOJITPSVYBYPMCSUVOJIT
OASUVOSUVOJITSUVOSTDYYJSUVOJITSUVOJITSUVO
RLSUVOCPSUVOJITYSUVOSUVOOGSUVOOESUVOJITMSUVO
WVLFFSUVOJITSUVOVSUVORLESUVOJITPSUVOJITSUVO
RSUVOSUVOJITQWSUVOUMASUVOSUVOJITXNNRRUNUSUVOJIT
HYLSSUVOSUVOSUVOJITPOSUVOJIT
DGMUCSSSUVOJITMJSUVOHSUVOCWTGSUVOJIT
OBNSSUVOYSUVOSUVOJITSUVOJITRHFDSUVODSUVOJITEGSUVOSUVOSUVOJITSUVOSUVOJITSSUVOSUVOSUVOSSUVOJIT
AG
NSUVOJITSUVOSUVOJIT
CGJGDSUVOEASUVOJITSGSUVO
However, when instead of using the s.size() function, I converted the string into a char constant and took the length of it using strlen, then the code caused no error and everything went smoothly.
So, my question is... Why did this happen?
This is my working code with the change:
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int suvo = 0;
int suvojit = 0;
string s;
cin >> s;
int le = strlen(&s[0]);
for (int i = 0; i <= le - 7; i++) {
if (s.substr(i, 7) == "SUVOJIT")
suvojit++;
}
for (int i = 0; i <= le - 4; i++) {
if (s.substr(i, 4) == "SUVO")
suvo++;
}
cout << "SUVO = " << suvo - suvojit << ", SUVOJIT = " << suvojit << "\n";
}
return 0;
}
In one case, you use size_t, in the other case you use int.
If the length is for example 6 characters, then s.size () - 7 is not -1, but one huge number and everything goes wrong. But if you write int len = strlen (...), then len - 7 is indeed -1 and everything is fine.
When I see a number subtracted from size_t, that's an immediate red flag. Write "i + 7 ≤ s.size()", not "i ≤ s.size() - 7".
First of all, in my testing your second leads to a problem as well:
Second, especially with older compilers (well, libraries, really) this can be horrendously inefficient, creating a huge number of temporary strings that you only use to compare with another string1.
So, let's consider how the job should be done instead. std::string has a member named find for situations like this. It returns the position of one string inside another, or std::string::npos if there is none. It allows you to specify a starting position at which to begin searching, when you don't want to start from the beginning.
We also, of course, have two instances of essentially identical code, once to search for SUVO, the other to search for SUVOJIT. The code would be much better off with the search code moved into a function, so we only have the search code in one place.
int count_pos(std::string const &haystack, std::string const &needle) {
size_t pos = 0;
int ret = 0;
while ((pos = haystack.find(needle, pos)) != std::string::npos) {
++ret;
++pos;
}
return ret;
}
Note that this also eliminates quite a bit more messy "stuff" like having to compute the maximum possible position at which at match could take place.
1. Why does compiler/library age matter? Older libraries often used a COW string that dynamically allocated storage for every string. More recent ones typically include what's called a "short string optimization", where storage for a short string is allocated inside the string object itself, avoiding the dynamic allocation.

How would I cycle through all of the various possibilities in this situation?

I saw a programming assignment that I decided to try, and it's basically where the user inputs something like "123456789=120", and the program has to insert a '+' or '-' at different positions to make the statement true. For example, in this case, it could do 123+4-5+6-7+8-9 = 120. There are only 3^8 possible combinations, so I think it would be okay to brute force it, but I don't know exactly in what order I could go in/how to actually implement that. More specifically, I don't know what order I would go in in inserting the '+' and '-'. Here is what I have:
#include <iostream>
#include <cmath>
using namespace std;
int string_to_integer(string);
int main()
{
string input, result_string;
int result, possibilities;
getline(cin, input);
//remove spaces
for(int i = 0; i < input.size(); i++)
{
if(input[i] == ' ')
{
input.erase(i, 1);
}
}
result_string = input.substr(input.find('=') + 1, input.length() - input.find('='));
result = string_to_integer(result_string);
input.erase(input.find('='), input.length() - input.find('='));
possibilities = pow(3, input.length() - 1);
cout << possibilities;
}
int string_to_integer(string substring)
{
int total = 0;
int power = 1;
for(int i = substring.length() - 1; i >= 0; i--)
{
total += (power * (substring[i] - 48));
power *= 10;
}
return total;
}
The basic idea: generate all the possible variations of +, - operators (including the case where the operator is missing), then parse the string and obtain the sum.
The approach: combinatorially, it is easy to show that we can do this by associating the operators (or the absence thereof) with the base-3 digits. So we can just iterate over every 8-digit ternary number, but instead of printing 0, 1 and 2, we will append a "+", a "-" or nothing before the next digit in the string.
Note that we do not actually need a string for this; one could use digits and operators etc. directly as well, computing the result on the fly. I only took the string-based approach because it's simple to explain, trivial to implement, and additionally, it gives us some visual feedback, which helps understanding the solution.
Now that we have constructed our string, we can just parse it; the simplest solution is to use the C standard library function strtol() for this purpose, which will take signs into account and it will return a signed integer. Because of this, we can just sum all the signed integers in a simple loop and we are done.
Code:
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
int main()
{
const char *ops = " +-";
// 3 ^ 8 = 6561
for (int i = 0; i < 6561; i++) {
// first, generate the line
int k = i;
std::string line = "1";
for (int j = 0; j < 8; j++) {
if (k % 3)
line += ops[k % 3];
k /= 3;
line += (char)('2' + j);
}
// now parse it
int result = 0;
const char *s = line.c_str();
char *p;
while (*s) {
int num = strtol(s, &p, 10);
result += num;
s = p;
}
// output
std::cout << line << " = " << result << (result == 120 ? " MATCH" : "") << std::endl;
}
return 0;
}
Result:
h2co3-macbook:~ h2co3$ ./quirk | grep MATCH
12-3-45+67+89 = 120 MATCH
1+2-34-5+67+89 = 120 MATCH
12-3+4+5+6+7+89 = 120 MATCH
1-23+4+56-7+89 = 120 MATCH
1+2+34-5+6-7+89 = 120 MATCH
123+4+5-6-7-8+9 = 120 MATCH
1+2-3+45+6+78-9 = 120 MATCH
12-3+45+67+8-9 = 120 MATCH
123+4-5+6-7+8-9 = 120 MATCH
123-4+5+6+7-8-9 = 120 MATCH
h2co3-macbook:~ h2co3$
The following bool advance(string& s) function will give you all combinations of '+', '-' and ' ' strings of arbitrary length except one and return false if no more are available.
char advance(char c)
{
switch (c)
{
case ' ': return '+';
case '+': return '-';
default: case '-': return ' ';
}
}
bool advance(string& s)
{
for (int i = 0; i < s.size(); ++i)
if ((s[i] = advance(s[i])) != ' ')
return true;
return false;
}
You have to first feed it with a string containing only spaces having desired length and then repeat 'advancing' it. Usage:
string s = " ";
while (advance(s))
cout << '"' << s << '"' << endl;
The above code will print
"+ "
"- "
" + "
"++ "
"-+ "
" - "
.
.
.
" ---"
"+---"
"----"
Note that the 'first' combination with just 4 spaces is not printed.
You can interleave those combinations with your lhs, skipping spaces, to produce expressions.
Another very similar approach, in plain C OK, in C++ if you really want it that way ;) and a bit more configurable
The same base 3 number trick is used to enumerate the combinations of void, + and - operators.
The string is handled as a list of positive or negative values that are added together.
The other contribution is very compact and elegant, but uses some C tricks to shorten the code.
This one is hopefully a bit more detailled, albeit not as beautiful.
#include <iostream>
#include <string>
using namespace std;
#include <string.h>
#include <math.h>
void solver (const char * str, int result)
{
int op_max = pow(3, strlen(str)); // number of operator permutations
// loop through all possible operator combinations
for (int o = 0 ; o != op_max ; o++)
{
int res = 0; // computed operation result
int sign = 1; // sign of the current value
int val = str[0]-'0'; // read 1st digit
string litteral; // litteral display of the current operation
// parse remaining digits
int op;
for (unsigned i=1, op=o ; i != strlen (str) ; i++, op/=3)
{
// get current digit
int c = str[i]-'0';
// get current operator
int oper = op % 3;
// apply operator
if (oper == 0) val = 10*val + c;
else
{
// add previous value
litteral += sign*val;
res += sign*val;
// store next sign
sign = oper == 1 ? 1 : -1;
// start a new value
val = c;
}
}
// add last value
litteral += sign*val;
res += sign*val;
// check result
if (res == result)
{
cout << litteral << " = " << result << endl;
}
}
}
int main(void)
{
solver ("123456789", 120);
}
Note: I used std::strings out of laziness, though they are notoriously slow.

How do I increment letters in c++?

I'm creating a Caesar Cipher in c++ and i can't figure out how to increment a letter.
I need to increment the letter by 1 each time and return the next letter in the alphabet. Something like the following to add 1 to 'a' and return 'b'.
char letter[] = "a";
cout << letter[0] +1;
This snippet should get you started. letter is a char and not an array of chars nor a string.
The static_cast ensures the result of 'a' + 1 is treated as a char.
> cat caesar.cpp
#include <iostream>
int main()
{
char letter = 'a';
std::cout << static_cast<char>(letter + 1) << std::endl;
}
> g++ caesar.cpp -o caesar
> ./caesar
b
Watch out when you get to 'z' (or 'Z'!) and good luck!
It works as-is, but because the addition promotes the expression to int you want to cast it back to char again so that your IOStream renders it as a character rather than a number:
int main() {
char letter[] = "a";
cout << static_cast<char>(letter[0] + 1);
}
Output: b
Also add wrap-around logic (so that when letter[0] is z, you set to a rather than incrementing), and consider case.
You can use 'a'+((letter - 'a'+n)%26);
assuming after 'z' you need 'a' i.e. 'z'+1='a'
#include <iostream>
using namespace std;
int main()
{
char letter='z';
cout<<(char)('a' + ((letter - 'a' + 1) % 26));
return 0;
}
See this https://stackoverflow.com/a/6171969/8511215
Does letter++ work?
All in all char is a numeric type, so it will increment the ascii code.
But I believe it must be defined as char letter not an array. But beware of adding one to 'Z'. You will get '[' =P
#include <iostream>
int main () {
char a = 'a';
a++;
std::cout << a;
}
This seems to work well ;)
char letter = 'a';
cout << ++letter;
waleed#waleed-P17SM-A:~$ nano Good_morning_encryption.cpp
waleed#waleed-P17SM-A:~$ g++ Good_morning_encryption.cpp -o Good_morning_encryption.out
waleed#waleed-P17SM-A:~$ ./Good_morning_encryption.out
Enter your text:waleed
Encrypted text:
jnyrrq
waleed#waleed-P17SM-A:~$ cat Good_morning_encryption.cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
//the string that holds the user input
string text;
//x for the first counter than makes it keeps looping until it encrypts the user input
//len holds the value (int) of the length of the user input ( including spaces)
int x, len;
//simple console output
cout << "Enter your text:";
//gets the user input ( including spaces and saves it to the variable text
getline(cin, text);
//give the variable len the value of the user input length
len = (int)text.length();
//counter that makes it keep looping until it "encrypts" all of the user input (that's why it keeps looping while its less than len
for(x = 0; x < len; x++) {
//checks each letts (and spaces) in the user input (x is the number of the offset keep in mind that it starts from 0 and for example text[x] if the user input was waleed would be w since its text[0]
if (isalpha(text[x])) {
//converts each letter to small letter ( even though it can be done another way by making the check like this if (text[x] =='z' || text[x] == 'Z')
text[x] = tolower(text[x]);
//another counter that loops 13 times
for (int counter = 0; counter < 13; counter++) {
//it checks if the letts text[x] is z and if it is it will make it a
if (text[x] == 'z') {
text[x] = 'a';
}
//if its not z it will keeps increamenting (using the loop 13 times)
else {
text[x]++;
}
}
}
}
//prints out the final value of text
cout << "Encrypted text:\n" << text << endl;
//return 0 (because the the main function is an int so it must return an integer value
return 0;
}
Note: this is called caeser cipher encryption it works like this :
ABCDEFGHIJKLMNOPQRSTUVWXYZ
NOPQRSTUVWXYZABCDEFGHIJKLM
so for example my name is waleed
it will be written as : JNYRRQ
so its simply add 13 letters to each letter
i hope that helped you
It works but don't forget that if you increment 'z' you need to get 'a' so maybe you should pass by a check function that output 'a' when you get 'z'.
cast letter[n] to byte* and increase its referenced value by 1.