First time on stack overflow.
I have this assignment due for class where we have a guessing game where our program has to generate a string of Uppercase letters of n length and n different defined by the user. I got most of my assignment working but when generate the string I am lost with how I could put these conditions in place for it to work.
char create_sequence(){
return rand() % 26 + 65;
}
Do you have any tips?
If you know sequence length, you don't need amount of different characters. This is because you require length <= characters.
To create sequence of n unique characters write a separate function:
vector<char> create_sequence(int n) {
vector<char> letters;
for (char ch = 'A'; ch <= 'Z'; ++ch) {
letters.push_back(ch);
}
vector<char> sequence;
for (int i = 0; i < n; ++i) {
int index = rand() % letters.size();
sequence.push_back(letters[index]);
letters.erase(letters.begin() + index, letters.begin() + index + 1);
}
return sequence;
}
Well, personally I think you are not far from the answer:
rand() % 26 + 65
Will effectively returns an uppercase ASCII letter. As long as you initialize the random seed once srand (time(NULL));, you can then call your instruction as many times as you want to get random values. So all you miss is a simple loop. Here is an example for 5 characters:
#include <iostream>
#include <string>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
char randomChar(){
return rand() % 26 + 65;
}
std::string randomString(int length)
{
srand (time(NULL));
std::string rc("");
for(int i=0; i<length; ++i)
{
rc += randomChar();
}
return rc;
}
int main()
{
std::cout << "Random string (x5) is " << randomString(5) << "\n";
}
Related
I am making a program and I need to generate all 9 digits numbers which have each digit different to the other digits, the 0 is not a valid digit in this case so I am only considering digits from 1 to 9.
So far I have this solution using random number generation, but I am facing performance issues
using namespace std;
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <string>
#include <map>
int main()
{
srand (time(NULL));
int secret;
string number = "";
map <string, bool> m;
int count = 0;
int nine_permutation = 362880;
vector <int> v{0,1,2,3,4,5,6,7,8,9};
int x = 9;
while(count < nine_permutation)
{
for(int i = 0; i < 9; i++)
{
secret = rand() % x +1;
number += to_string(v[secret]);
v.erase(v.begin() + secret);
x--;
}
x = 9;
v = {0,1,2,3,4,5,6,7,8,9};
if(m.count(number) == 0)
{
m[number] = true;
count ++;
}
cout << count << endl;
}
cout << number;
}
So you have 10 digits 0,1,2,3,4,5,6,7,8,9 and number you want to get numbers with nine digits.
I think you can start with 123456789, generate all permutations and then replace each character with '0' which would give set:
{023456789, 103456789, 120456789, 123056789, 123406789, 123450789, 123456089, 123456709, 123456780}. And for each element from this set also generate all permutations.
Something like this:
void allNumbersWithDistinctDigits() {
int idxForZero = 0;
std::string initial("123456789");
std::string local(initial);
do {
while (std::next_permutation(local.begin(), local.end())) {
if (local[0] != '0') {
std::cout << local << std::endl;
}
}
local = initial;
local[idxForZero] = '0';
} while(++idxForZero <= initial.size());
}
Condition if (local[0] != '0') is optional and it gets rid of numbers starting with 0, like: 012345678 which is in fact 8 digits 12345678 or octal number.
I am trying to convert an int to a char using the ASCII value. The int is randomly generated between 97 and 122 (from a to z).
How can I generate a random number between 97 and 122 and convert it to a char?
I searched many answers before asking my question, but none solved the problem or was completely related to my need. Even this didn't work.
Here is what I'm trying to do: in a for loop, the program generates a random number and converts it to an int. This is converted to its ASCII value and then placed into a QString. When the for loop is finished, I send the QString to a line_edit.
By following the above link, I only got an m.
Here's my code:
QString str;
int maxlenght = 16; //the user will be able to set himself the maxlenght
for (int i =0; i<maxlenght; i++)
{
int random = 97 + (rand() % (int)122-97+1);
char letter = (char)random;
if(i > 0)
{
str[i] = letter;
}
}
And though the random number is generated in the loop, it always gives me the same char.
You need to convert string to QString after that.
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
int main()
{
string str="";
int maxlenght = 16; //the user will be able to set himself the maxlenght
for (int i =0; i<maxlenght; i++)
{
int rand_num = 97 + (rand() % (122 - 97 + 1));
char letter = static_cast<char>(rand_num);
str += letter;
}
cout << str << endl;
return 0;
}
How to convert string like 3 word 12 with word to a int only contain number 312 without using stoi in C++? My Codeblode gave me an error stoi is not a member of std when I tried to use it.
Thank you in advance!
Go through the line and skip non-digit symbols. And for digits use -'0' conversion and *10 shift approach. E.G.:
#include <stdio.h>
#include <ctype.h>
//or cctype to use isdigit()
#include <string.h>
//or cstring to use strlen()
int main()
{
char str[] = "3 word 12 with word"; // can be any string
int result = 0; // to store resulting number
// begin of solution
for (int i = 0; i < strlen(str); i++)
{
if (isdigit(str[i]))
{
result *= 10;
result += str[i] - int('0');
}
}
// end of solution
printf("%d\n", result);
return 0;
}
Same idea as in VolAnd's answer. Just, because the question is tagged c++, using some STL stuff.
#include <iostream>
#include <numeric>
#include <string>
using namespace std;
int main(){
std::string input("3 word 12 with word");
int num = std::accumulate(input.begin(), input.end(), 0,
[](int val, const char elem) {
if (isdigit(elem)) {
val = val*10 + (elem-'0');
}
return val;
}
);
std::cout << num << std::endl;
return 0;
}
see http://en.cppreference.com/w/cpp/algorithm/accumulate
note: It gets slightly more interesting if you want to allow a leading minus sign....
And using boost::adaptors::filter(rng, pred) on this one would be fun but slightly overdoing it ;-)
Assuming that s is your initial string.
int toInt(string s) {
string digits;
for(size_t i = 0; i < s.size(); i++)
if(s[i] >= '0' && s[i] <= '9')
digits.push_back(s[i]);
int res = 0;
for(size_t i = 0; i < digits.size(); i++)
res = res * 10 + digits[i] - '0';
return res;
}
Leading zeros are not a problem.
Note however that it is possible to receive an overflow if the resulting digits string will contain a big number.
So my objective is to create a random password generator of length n (n >= 5 && n <= 15) that adds in only two numbers at random locations.
(e.g. 7S4js 86dJxD h6Zqs9K)
I have this working... or so I want to believe. What I want to know is will my code ALWAYS work at determining whether or not a number should be inserted.
'newPassword': Returns a string of length 'len', using 'nums' numbers.
std::string newPassword(int len, int nums)
{
std::string password = "";
// Required numbers
int req = nums;
for (int i = 0; i < len; i++)
{
bool needNum = req > 0;
bool chance = rand() % len > req;
bool useNum = needNum && chance;
if (useNum)
req--;
char c = nextChar(useNum);
password += c;
}
return password;
}
'nextChar': Returns a random character. The character will be a number if 'isNum' is true.
char nextChar(bool isNum)
{
char c;
if (!isNum)
{
// 50% chance to decide upper or lower case
if (rand() % 100 < 50)
{
c = 'a' + rand() % 26;
}
else
{
c = 'A' + rand() % 26;
}
}
else
{
// Random number 0-9
c = '0' + rand() % 10;
}
return c;
}
So specifically, will the 'chance' variable in 'newPassword' work all the time?
rand() is an obsolete and terrible way to generate random numbers. The c++11 <random> header provides much higher quality facilities for dealing with all kinds of random stuff.
Your way of choosing the letter or a digit will not always work. I would approach it in a different way: generate the needed number of letters and digits and then shuffle the string. It might not be the most efficient way, but given your requirements for password length, I'd value code clarity more.
#include <string>
#include <random>
#include <algorithm>
std::string generatePassword(int length, int nDigits)
{
std::string password;
password.resize(length);
std::mt19937 generator{std::random_device{}()};
// Generate capital/lowercase letters
std::uniform_int_distribution<char> letterGen(0, 2 * 26 - 1);
auto digitsBeginIter = std::generate_n(password.begin(), length - nDigits,
[&letterGen, &generator]() {
auto l = letterGen(generator);
return l < 26 ? 'a' + l : 'A' + (l - 26);
});
// Generate the digits
std::uniform_int_distribution<char> digitGen('0', '9');
std::generate_n(digitsBeginIter, nDigits,
[&digitGen, &generator]() { return digitGen(generator); });
// Shuffle the string
std::shuffle(password.begin(), password.end(), generator);
return password;
}
To find the sub-sequences from a string of given length i have a recursive code (shown below) but it takes much time when the string length is big....
void F(int index, int length, string str)
{
if (length == 0) {
cout<<str<<endl;
//int l2=str.length();
//sum=0;
//for(int j=0;j<l2;j++)
//sum+=(str[j]-48);
//if(sum%9==0 && sum!=0)
//{c++;}
//sum=0;
} else {
for (int i = index; i < n; i++) {
string temp = str;
temp += S[i];
//sum+=(temp[i]-48);
F(i + 1, length - 1, temp);
}
}
}
Please help me with some idea of implementing non-recursive code or something else.
You mentioned your current code is too slow when the input string length is large. It would be helpful if you could provide a specific example along with your timing info so we know what you consider to be "too slow". You should also specify what you would consider to be an acceptable run time. Here's an example:
I'll start with an initial version that I believe is similar to your current algorithm. It generates all subsequences of length >= 2:
#include <iostream>
#include <string>
void subsequences(const std::string& prefix, const std::string& suffix)
{
if (prefix.length() >= 2)
std::cout << prefix << std::endl;
for (size_t i=0; i < suffix.length(); ++i)
subsequences(prefix + suffix[i], suffix.substr(i + 1));
}
int main(int argc, char* argv[])
{
subsequences("", "ABCD");
}
Running this program produces the following output:
AB
ABC
ABCD
ABD
AC
ACD
AD
BC
BCD
BD
CD
Now let's change the input string to something longer. I'll use a 26-character input string:
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
This generates 67,108,837 subsequences. I won't list them here :-). On my machine, the code shown above takes just over 78 seconds to run (excluding output to cout) with the 26-character input string.
When I look for ways to optimize the above code, one thing that jumps out is that it's creating two new string objects for each recursive call to subsequences(). What if we could preallocate space once upfront and then simply pass pointers? Version 2:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
void subsequences(char* prefix, int prefixLength, const char* suffix)
{
if (prefixLength >= 2)
printf("%s\n", prefix);
for (size_t i=0; i < strlen(suffix); ++i) {
prefix[prefixLength] = suffix[i];
prefix[prefixLength + 1] = '\0';
subsequences(prefix, prefixLength + 1, suffix + i + 1);
}
}
int main(int argc, char* argv[])
{
const char *inputString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *prefix = (char*) _malloca(strlen(inputString) + 1);
subsequences(prefix, 0, inputString);
}
This generates the same 67,108,837 subsequences, but execution time is now just over 2 seconds (again, excluding output via printf).
Your code might be slow because your string is large. For a sequence of n unique elements there are (n over k) subsequences of length k. That means for the sequence "ABCDEFGHIJKLMNOPQRSTUVWXYZ" there are 10.400.600 different subsequences of length 13. That number grows pretty fast.
Nevertheless, since you asked, here is a non-recursive function that takes a string str and a size n and prints all subsequences of length n of that string.
void print_subsequences(const std::string& str, size_t n)
{
if (n < 1 || str.size() < n)
{
return; // there are no subsequences of the given size
}
// start with the first n characters (indexes 0..n-1)
std::vector<size_t> indexes(n);
for (size_t i = 0; i < n; ++i)
{
indexes[i] = i;
}
while (true)
{
// build subsequence from indexes
std::string subsequence(n, ' ');
for (size_t i = 0; i < n; ++i)
{
subsequence[i] = str[indexes[i]];
}
// there you are
std::cout << subsequence << std::endl;
// the last subsequence starts with n-th last character
if (indexes[0] >= str.size() - n)
{
break;
}
// find rightmost incrementable index
size_t i = n;
while (i-- > 0)
{
if (indexes[i] < str.size() - n + i)
{
break;
}
}
// increment that index and set all following indexes
size_t value = indexes[i];
for (; i < n; ++i)
{
indexes[i] = ++value;
}
}
}