Cannot get the random string - c++

I am using C++ to create an app for Random Questions. But I don't think that works (due to my bad logics). What I am trying is this:
class English {
public:
string get_questions (int number) {
if (number == 1) {
// Chapter 1
string questions[10] = {
"In what way is man considere to be a lower species when compared to animals, in general?",
"What specific triats of character make man the lowest animal in Mark Twain's views?",
"What aspects of human nature are pointed when man is compared with the anaconda, bees, roosters, cats.",
"What specific traits of character make man the lowest animal in Mark Twain's views?",
"Discuss the Importance of the experiments conducted by the Mark Twain.",
"Can people improve themselves and remove this label in thismillennium?",
"What are the traits due to which man cannot claim to have reached the meanest of the Higher Animals?",
"\"The damned Human Race\" was written in 1900, is it valid today?",
"Do you think Mark Twain was accurate while comparing Human nature to that of the birds, insects and other animals?",
"Why did Mark Twain rejected Darwin's theory, what were his conclusions in this regard?"
};
string result = questions[rand() % 9 + 0] + "\n";
return result;
}
}
};
And the code that I am using is something like this:
cout << English().get_questions(chapter);
Although I have more lines, but they are just simple cout and cin to get the chapter and subject values. They won't be a trouble for this.
The main issue here is that everytime I am done writing the code, when I compile and execute it, same question is provided as a result everytime. Forexample, for the current random logic, I get this question:
Can people improve themselves and remove this label in this millennium?
Whenever I change the logic, I get a new result but similar in every condition (code execution for that particular logic)! Where as what I want is to get a random question, each time the code is executed, Should I change the place where this random number is generated? Or am I doing wrong somewhere else?

You should be initializing random number generator using srand function using random seed value to change this behaviour of rand() function.
You can use something like srand (time(NULL)); to initialize random generator using different seed.
Please have look at http://www.cplusplus.com/reference/cstdlib/srand/

You are not seeding your random number generator so every time you run the program you will get the same sequence of random numbers. Use srand once at the start of the program.

You need to use function std::srand declared in header <cstdlib> that to set a random sequence.
For example
class English {
public:
English() { if ( !init ) std::srand( unsigned( std::time( 0 ) ) ); init = true; }
string get_questions (int number) const {
if (number == 1) {
// Chapter 1
string questions[10] = { /*...*/ };
string result = questions[rand() % 10] + "\n";
return result;
}
}
private:
static bool init;
};
bool English::init = false;
Take into account that i made changes in function get_questions

If you are using a C++11 compliant compiler, a better solution is to use the <random> library:
// initialize your string array
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(0,9);
int index = distribution(generator);
return questions[index];

Related

Comparing Values in a Single Vector

I'm working on a GA and seem to be having problems with the tournament selection. I think this is due to the fact that I'm not comparing what I want to compare (in terms of fitness values)
srand(static_cast <unsigned> (time(0)));
population Pop;
vector<population> popvector;
vector<population> survivors;
population *ptrP;
for (int i = 0; i <= 102; i++)
{
ptrP = new population;
ptrP->generatefit;
ptrP->findfit;
popvector.push_back(*ptrP);
//include finding the persons "overall". WIP
}
cout << "The fit values of the population are listed here: " << endl;
vector<population> ::iterator it; //iterator to print everything in the vector
for (it = popvector.begin(); it != popvector.end(); ++it)
{
it->printinfo();
}
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); // generate a seed for the shuffle process of the vector.
cout << "Beggining selection process" << endl;
shuffle(popvector.begin(), popvector.end(), std::default_random_engine(seed));
//Shuffling done to randomize the parents I will be taking.
// I also want want to pick consecutive parents
for (int i = 0; i <= 102; i = i + 3)
{
if (popvector[i] >= popvector[i++]);
}
}
Now what I think my problem is, is that when im trying to compare the Overall values (Not found yet, working on how to properly model them to give me accurate Overall fitness values) I'm not comparing what I should be.
I'm thinking that once I find the persons "Overall" I should store it in a Float vector and proceed from there, but I'm unsure if this is the right way to proceed if I wish to create a new "parent" pool, since (I think) the "parent pool" has to be part of my population class.
Any feedback is appreciated.
srand(static_cast <unsigned> (time(0)));
This is useless: you're calling std::shuffle in a form not based on std::rand:
shuffle(popvector.begin(), popvector.end(), std::default_random_engine(seed));
If somewhere else in the program you need to generate random numbers, do it via functions / distributions / engines in random pseudo-random number generation library (do not use std::rand).
Also consider that, for debugging purpose, you should have a way to initialize the random engine with a fixed seed (debug needs repeatable results).
for (int i = 0; i <= 102; i++)
Do not use magic numbers.
Why 102? If it's the population size, store it in a constant / variable (populationSize?), document the variable use and "enjoy" the fact that when you need to change the value you haven't to remember the locations where it's used (just in this simple snippet there are two distinct use points).
Also consider that the population size is one of those parameters you need to change quite often in GA.
ptrP = new population;
ptrP->generatefit;
ptrP->findfit;
popvector.push_back(*ptrP);
Absolutely consider Sam Varshavchik's and paddy's remarks.
for (int i = 0; i <= 102; i = i + 3)
{
if (popvector[i] >= popvector[i++]);
// ...
Generally it's not a good practice to change the index variable inside the body of a for loop (in some languages, not C / C++, the loop variable is immutable within the scope of the loop body).
Here you also have an undefined behaviour:
popvector[i] >= popvector[i++]
is equivalent to
operator>=(popvector[i], popvector[i++])
The order that function parameters are evaluated is unspecified. So you may have:
auto a = popvector[i];
auto b = popvector[i++];
operator>=(a, b); // i.e. popvector[i] >= popvector[i]
or
auto b = popvector[i++];
auto a = popvector[i];
operator>=(a, b); // i.e. popvector[i + 1] >= popvector[i]
Both cases are wrong.
In the first case you're comparing the same elements and the expression is always true.
In the second case the comparison probably is the opposite of what you were thinking.
Take a look at:
Undefined behavior and sequence points
What are all the common undefined behaviours that a C++ programmer should know about?
and always compile source code with -Wall -Wextra (or their equivalent).
I'm not sure to correctly understand the role of the class population. It may be that the name is misleading.
Other questions / answers you could find interesting:
C++: "std::endl" vs "\n"
http://herbsutter.com/2013/05/13/gotw-2-solution-temporary-objects/ (the section about premature pessimization)

Is there a way to make a function do something different the second time a number appears?

Im trying to make a small program about the method in which the amount of money awarded to players at the end of a game is decided. So far I have used a RNG to simulate what happens in a round of the game but have gotten stuck. I want to find out how to design my code in order for it to do something different the second time the same number is generated from the RNG.
while (active==1)
{
random=rand()%11+1;
if (random==11)
{
bomb=1;
}
}
Thanks for any responses :)
Keep a map of (number, count) pairs:
std::unordered_map<int, std::size_t> number_frequencies;
while (active) {
int number = random_number();
++number_frequencies[number];
if (number_frequencies[number] == 2) {
// do something
} else {
// do something else
}
}
First of all, for clarity, apply the following:
Define MAX to whatever maximum value you want to have (e.g., 11)
Use random between 0 and MAX-1 (instead of between 1 and MAX)
Then, you can try to adjust the following piece of code to your requirements:
#define MAX 11
...
int count[MAX] = {0};
while (active == 1)
{
random = rand()%MAX;
count[random]++;
...
}
The count array indicates the number of times that each random value was generated.
So at each iteration, you can use count[random] in order to choose what action to take.

How would I randomly create typos in a std::string?

Ok so I'm working on a chatbot and I have a private std::string called m_sResponse. This string is outputted using
void print_response() const {
if(m_sResponse.length() > 0) {
std::cout << m_sResponse << std::endl;
}
}
I want to create a function that will misspell m_sRensponse let's say 5% of the time so the chatbot seams more human like. How would I accomplish this?
To make it seem more realistic, I'd make a map<char,vector<char>> of appropriate 'substitution' keys based off of keyboard layouts (e.g. QWERTY). Basically, it seems more real if your typo is "responsw" than "responsl" since "w" and "e" are next to each other. You'll also want to randomly delete or insert letters too. I'd assign a frequency to "errors" and then a frequency of each kind of error.
Now that you've got this and the other answers handling the randomness aspect (if(rand(100)<5)), you should be able to replicate the desired typo handler.
Pseudocode:
if rand(100) < 5
randomIndex = rand(string.length())
randomChar = rand(26)
string[randomIndex] = randomChar
You can use a random seed and use %5 for like 20% of the time ish.
if((rand() % 5) == 0) {
int t = rand() & m_sResponse.length();
char a = m_sResponse[t];
m_sResponse[t] = m_sResponse[t+1];
m_sResponse[t+1] = a;
}

C++ functions that takes multiple numbers and perform different jobs

I have an exercise where I should input multiple numbers which finish with zero and then perform different calculations with them. So far I have created a do..while-loop for storing the numbers. I´ve been told that this is possible to do without an array, if that´s wrong please tell me right away. The functions I need to do is to add all the numbers together, locate the highest number and the second highest number, and also the mid (mean) value of all the numbers.
I think there are different libraries I should use and there may be different options also.
Please help me to understand the different libraries and how to use them.
The search results I´ve found on the the web does not give me the answers I´m looking for because I could not find a similar problem to mine.
This is my code so far:
#include<iostream>
#include<string>
using namespace std;
int sumCalc (int);
int midValCalc (int);
int secHighCalc (int);
int highestCalc (int);
void printCalc ();
int main() {
int nums;
cout << "Input numbers, quit with 0: ";
do {
cin >> nums;
cout << nums << " "; // This is just to see the result
}
while (nums != 0);
return 0;
}
What is wrong with this add function?
int sumCalc (int total) {
total = 0;
while (nums != 0) {
total += nums;
}
return nums;
}
I don't think you need any unusual libraries for this.
Think about how you'd calculate these things mentally. For example, if you want to sum a list of numbers that I read off to you, you'd just keep track of the running total, and forget each number as you added it - so that only needs one variable. If you want to keep track of the greatest number entered, again, you simply remember the biggest one you've seen so far and compare new numbers as you get them.
You can probably solve these.
If you need to get the mean and highest and second-highest numbers you don't need an array(you don't need to store the numbers)
Essentially, you can keep track of the highest and second highest numbers that the user has entered, and if the user enters a number higher than those, you can adjust accordingly.
As for the mean average, you can also keep a running sum and count(# of numbers entered) which you can use to calculate the mean with whenever you need to.

append an integer variable to char variable in C++

I'm new in C++, I have a small project,
I should get 10 numbers from user and then show in result.
so I wrote this code :
#include<stdio.h>
int main() {
int counter=1,
allNumbers;
float score;
while(counter <= 10) {
scanf("%f",&score);
counter++;
}
printf("Your entered numbers are : %s\n",allNumber);
}
for example user enter 2 3 80 50 ... and I want show 2,3,80,50,... in result.
But I don't know what should I do !
I do not know what book you are using, but the authors appear to teach you C before going into the C++ land. Without discussing their motives, I'll write an answer to be similar to your style of code before discussing an ideal C++ solution.
You need an array to store your numbers: double score[10]
Array are indexed starting from zero, so change counter to start at zero and go to nine (instead of starting at one and going to ten, like you have now)
Since score is an array, use &score[count] in the call of scanf
To print ten numbers you need a loop as well. You need a flag that tells you whether or not you need a comma after the number that you print. Add a printf("\n") after the loop.
As far as an "ideal" C++ solution goes, it should look close to this one:
istream_iterator<double> eos;
istream_iterator<double> iit(cin);
vector<double> score;
copy(iit, eos, back_inserter(score));
ostream_iterator<double> oit (cout, ", ");
copy(score.begin(), score.end(), oit);
However, discussing it would remain hard until you study the C++ standard library and its use of iterators.
You can do it by declaring an array of ten numbers.
your code goes here:
#include <stdio.h>
int main() {
int counter=0;
float allNumbers[10];
while(counter < 10) {
scanf("%f",&allNumbers[counter]);
counter++;
}
printf("Your entered numbers are : \n");
counter=0;
while(counter < 10) {
printf("%f , ",allNumbers[counter]);
counter++;
}
}