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

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;
}

Related

Manage multiple variable in one, big if-else

I have to solve problem with some Word's like editor and it's codes, witch return some logic.
Now I have over 4000 variables:
string code1 = "onePlusOne";
string code2 = "onePlusTwo";
...
string code4000 = "onePlusFourThousands"
and the same number of logic if-else statements:
if(code == code1)
return 2;
else if(code == code2)
return 3;
...
else if(code = code4000)
return 4001;
Client can paste code into editor to get value, for example:
"Some test, #onePlusTwenty# some test."
..and the result will be:
"Some test, 21 some test."
My problems are:
over 4000 variables in code,
over 4000 lines of if-else (with returns it's over 10 000 lines).
contradiction with SOLID :)
I was thinking about store those codes in database (but this solve almost nothing), also I can sort those codes into groups (but this only will help me to split if-else into many others if-else).
I will be grateful for any idea how to mange this.
You can use a key-value structure for storing your data and instead of writing +10,000 LOC, use a for loop to replace your values. For exampleL
struct key_value {
string key;
int value;
};
And for loop will be like
for(int i = 0; i < MAPSIZE; i ++) {
if(YOUR_COMPARE_MODULE) {
// replace here
}
}

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.

Vector + for + if

OK, so the goal of this was to write some code for the Fibonacci numbers itself then take those numbers figure out which ones were even then add those specific numbers together. Everything works except I tried and tried to figure out a way to add the numbers up, but I always get errors and am stumped as of how to add them together. I looked elsewhere but they were all asking for all the elements in the vector. Not specific ones drawn out of an if statement.
P.S. I know system("pause") is bad but i tried a few other options but sometimes they work and sometimes they don't and I am not sure why. Such as cin.get().
P.S.S I am also new to programming my own stuff so I have limited resources as far as what I know already and will appreciate any ways of how I might "improve" my program to make it work more fluently. I also take criticism well so please do.
#include "../../std_lib_facilities.h"
int main(){
vector<int>Fibonacci;
int one = 0;
int two = 1;
int three = 0;
int i = 0;
while (i < 4000000){
i += three;
three = two + one; one = two; two = three;
cout << three << ", ";
Fibonacci.push_back(three);
//all of the above is to produce the Fibonacci number sequence which starts with 1, 2 and adds the previous one to the next so on and so forth.
//bellow is my attempt and taking those numbers and testing for evenness or oddness and then adding the even ones together for one single number.
}
cout << endl;
//go through all points in the vector Fibonacci and execute code for each point
for (i = 0; i <= 31; ++i)
if (Fibonacci.at(i) % 2 == 0)//is Fibonacci.at(i) even?
cout << Fibonacci.at(i) << endl;//how to get these numbers to add up to one single sum
system("pause");
}
Just do it by hand. That is loop over the whole array and and keep track of the cumulative sum.
int accumulator = 0; // Careful, this might Overflow if `int` is not big enough.
for (i = 0; i <= 31; i ++) {
int fib = Fibonacci.at(i);
if(fib % 2)
continue;
cout << fib << endl;//how to get these numbers to add up to one single sum
accumulator += fib;
}
// now do what you want with "accumulator".
Be careful about this big methematical series, they can explode really fast. In your case I think the calulation will just about work with 32-bit integers. Best to use 64-bit or even better, a propery BigNum class.
In addition to the answer by Adrian Ratnapala, I want to encourage you to use algorithms where possible. This expresses your intent clearly and avoids subtle bugs introduced by mis-using iterators, indexing variables and what have you.
const auto addIfEven = [](int a, int b){ return (b % 2) ? a : a + b; };
const auto result = accumulate(begin(Fibonacci), end(Fibonacci), 0, addIfEven);
Note that I used a lambda which is a C++11 feature. Not all compilers support this yet, but most modern ones do. You can always define a function instead of a lambda and you don't have to create a temporary function pointer like addIfEven, you can also pass the lambda directly to the algorithm.
If you have trouble understanding any of this, don't worry, I just want to point you into the "right" direction. The other answers are fine as well, it's just the kind of code which gets hard to maintain once you work in a team or have a large codebase.
Not sure what you're after...
but
int sum=0; // or long or double...
for (i = 0; i <= 31; ++i)
if (Fibonacci.at(i) % 2 == 0) {//is Fibonacci.at(i) even?
cout << Fibonacci.at(i) << endl;//how to get these numbers to add up to one single sum
sum+=Fibonacci.at(i);
}
// whatever
}

Cannot get the random string

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];

length of sub-sequence in the string

I need to implement lastSeq function,which gets as argument string str and char chr
and returns the length of last sequence of repeated chr (the sequence can be of any length)
for example:
lastSeq("abbaabbbbacd",'a') should return 1
lastSeq("abbaabbbbacd",'b') should return 4
lastSeq("abbaabbbbacd",'t') should return 0
Is there C++ function which can solve it?
This appear to be homework, so I'm just going to give you direction so that you can find the answer by yourself.
First, how would you do it yourself, without a computer to give the correct result for your samples. From those manual run, how would you generalize then in simple steps so that you can solve the problem for all different inputs.
By this point you should have a rough algorithm to solve the problem. What do you know about storage of string in C++, and the method that are available from that class? Can some one them be used to solve some of the steps of your algorithm?
Try to write a program using those function, to compile it and to run it. Do you get the expected result? If not, can you try to print intermediate state (using std::cout << "Some value: " << variable << "\n";) to try to debug it.
Once you have done all of that, and if you are still having issues, update your question with your code, and we'll be able to give you more directed help.
int lastSeq(char *str, char chr)
{
int i = strlen(str);
int l = 0;
while(--i>=0)
if(*(str + i) == chr && ++l)
break;
while(--i>=0 && chr == *(str + i) && ++l);
return l;
}