the code I have problem is:
vector<int> steps_list;
steps_list.reserve(runs);
for (int i=0;i<runs;i++){
int steps=0;
bool in_con=false;
srand(time(0));
int init_pos=rand()%mylat;
while (in_con==false) {
srand(time(0));
int step=2*(rand()%2)-1;
init_pos+=step;
init_pos=init_pos%grid.size();
if (grid[init_pos]==0){
in_con=true;
}
steps+=1;
}
steps_list.push_back(steps);
}
for (int i=0;i<mylat;i++){
cout<<steps_list[i]<<" ";
}
I want to store in steps_list vector all the different steps ,but instead of that it stores only one step and it fills the vector with that.
I can't figure where is my problem.I am not familiar with vectors.
You need to move this line
srand(time(0));
outside the loop, and preferably do this once at the beginning of your program.
You are seeding the random number generator, and my guess is the time you obtain has second resolution. The loop iterations take less than a second, so you are always seeding with the same value and obtaining the same random numbers.
I'm guessing but the error might be that you call srand(time(0)) before each call of rand(). That's a very good way to make your random numbers completely unrandom.
Could that be an explanation for what you see?
In any case call srand(time(0)) once at the beginning of the program and nowhere else.
Related
I am facing following problem with recursion. It is simple backtracking to print all the permutation, but I want to stop it from the base condition. For example, 4 character string will show 4!=24 strings. But I want to show first 20 strings only.
k is used for the purpose, k=20,for the example. Suppose, str="ABCD". I want to stop recursion after exactly 20 operations. How can I do this? I have tried to solve it in this way.
void permutation(string str,int l,int r,int k)
{
k--;
if(l==r||k==0) {
cout<<str<<endl;
return;
}
else{
for(int i=l;i<r;i++)
{
swap(str[l],str[i]);
permutation(str,l+1,r,k);
swap(str[l],str[i]);
}
}
}
If you want to use the unfortunately named k as a counter like that, it will count recursion levels, not results. If you want to count results, you need to store the counter outside of your function, either as a static or as a reference you pass to your function, and increment it every time you output a result.
You have two solutions to count the number of times results are printed:
1- Defining k as a global variable outside the function.
2- Defining k as a static variable: static int k = 0;.
Note that in both these solutions, k should be eliminated from the parameter list of the function.
I would also suggest choosing meaningful names for your variables. This way, it will be easier to understand and follow the code both for you and someone else who is going to help.
I am trying to create a simple game where the user inputs a number, and the computer tries to guess it. The program randomly generates a number between 1 & 100. Whenever the user says a number is too high it stores that value, and every value above that, in an array and vice versa for too low. Then I want the program to generate another random number, but if the number it generates is within the array of wrong numbers, it tries again. But I have absolutely no idea how to check if the number is present in the array. Is this possible?
Yes, this is possible. You will want to use the std::find() algorithm, the reference page for which can be found Here.
It is called as std::find(std::begin(array), std::end(array), someObject);
and returns an iterator to the first element in the range [first,last) that compares equal to someObject. If no such element is found, the function returns last element i.e. end of range.
In building your random number game I would consider whether, checking if the computers guess is out of range and then guessing again if so, is the best way to approach the problem (because it's not the best way).
Also before asking a question please try to find similar questions such as This, or This before asking a new question in order to prevent stackoverflow from becoming too cluttered
For that game you don't need an array. Look at the following program:
#include <iostream>
constexpr long long average (long long a, long long b)
{
return (a+b)>>1;
}
int main()
{
char ans;
long long start, end;
std::cin >> start >> end;
do
{
auto n=average(start,end);
std::cout << n << std::endl;
std::cin >> ans;
if(ans=='<') end=n-1;
else if(ans=='>') start=n+1;
}
while(ans!='=');
}
Think of a number in the range [start, end] and the program will guess it.
It uses binary search algorithm so it will need approximately log2(end-start+1) tries in the worst case.
I encountered a problem that requires the program to count the number of points within an interval. This problem provides a large amount of unsorted points, and lo,hi(restriction lo<=hi), and it aims to enumerate the points within [lo,hi]. The problem is that although my code is correct, it is too time-consuming to finish within given time (2200ms). My code can finish this mission in O(n). I would like to ask if there are any faster methods.
int n,m,c,lo,hi;
cin>>n>>m;
int arr[n];
for(int i=0;i<n;i++){
cin>>arr[i];
}
cin>>lo>>hi;
c=0;
for(int j=0;j<n;j++){
if(arr[j]<=hi&&lo<=arr[j])c++;
}
cout<<c<<endl;
It is impossible to solve this problem in less than O(n) time, because you must consider all inputs at least once.
However, you might be able to reduce the constant factor of n — have you consider storing a set of (start, end) intervals, rather than a simple array? What is the input size which causes this to be slow?
Edit: upon further testing, it seems the bottleneck is actually the use of cin to read numbers.
Try replacing every instance of cin >> x; with scanf("%d", &x); — for me, this brings the runtime down to about 0.08 seconds.
You can do it faster than O(N) only if you need to do lookups more than once on the same data set:
Sort the array or its copy. For lookup you can use binary search - which is O(log2 N) complex.
Instead of flat array to use something like binary tree, lookup complexity will be as in #1.
I need to create a set of random numbers between 0 and 800. The problem is at the moment that I need to do this fast and each number shall be returned only once.
My current approach is:
Create a std::vector containing the numbers from 0 to 800
Pick a number using numberVector[rand() % numberVector.length()]
Delete this number from the vector
I have to do this very often and my current approach is slow. Is there some way to speed things up here?
Create a std::vector containing the numbers from 0 to 800
Shuffle the vector.
This should be useful: c++ - How to shuffle a std::vector? - Stack Overflow
Take the elements of the vector one by one, from the head to the tail. You don't have to delete the element: just store the index of last used element.
std::shuffle (std::random_shuffle) your std::vector
pop_back elements
Delete this number from the vector
You're probably doing too much work for this. Remember, for example, that deleting from the end of the vector is a lot faster than deleting from the front of the vector.
Since you don't care where in the vector your numbers are, you can speed things up by moving the number you want to delete to the end of the vector; e.g.
int take_from_vector(vector<int> &vec, size_t pos)
{
int rv = vec[pos];
swap(vec[pos], vec.back());
vec.pop_back();
return rv;
}
However, if you're generating just a few things, it is probably faster to use rejection sampling: you keep track of which numbers you've generated, then reject any repeats. e.g.
int generate_another_number(set<int> &already_generated, int bound)
{
while (true) {
int rv = rand() % bound;
auto pos = already_generated.insert(rv);
if (pos.second) { return rv; }
}
}
Depending on how many things you're generating, you might want to use unordered_set<int> instead of set. Or maybe even use vector and just iterate over the vector to see if it contains the generated number.
P.S. consider using C++'s random number generation features, rather than the ancient rand() function.
I am trying to write a function in C++ using MPFR to calculate multiple values. I am currently using an mpfr array to store those values. It is unknown how many values need to be calculated and stored each time. Here is the function:
void Calculator(mpfr_t x, int v, mpfr_t *Values, int numOfTerms, int mpfr_bits) {
for (int i = 0; i < numOfTerms; i++) {
mpfr_init2(Values[i], mpfr_bits);
mpfr_set(Values[i], x, GMP_RNDN);
mpfr_div_si(Values[i], Values[i], pow(-1,i+1)*(i+1)*pow(v,i+1), GMP_RNDN);
}
}
The program itself has a while loop that has a nested for loop that takes these values and does calculations with them. In this way, I don't have to recalculate these values each time within the for loop. When the for loop is finished, I clear the memory with
delete[] Values;
before the the while loops starts again in which case, it redeclares the array with
mpfr_t *Values;
Values = new mpfr_t[numOfTerms];
The number of values that need to be stored are calculated by a different function and is told to the function through the variable numOfTerms. The problem is that for some reason, the array slows down the program tremendously. I am working with very large numbers so the thought is that if I recalculate those values each time, it gets extremely expensive but this method is significantly slower than just recalculating the values in each iteration of the for loop. Is there an alternative method to this?
EDIT** Instead of redeclaring the array over each time, I moved the declaration and the delete[] Values outside of the while loop. Now I am just clearing each element of the array with
for (int i = 0; i < numOfTerms; i++) {
mpfr_clear(Values[i]);
}
inside of the while loop before the while loop starts over. The program has gotten noticeably faster but is still much slower than just calculating each value over.
If I understand correctly, you are doing inside a while loop: mpfr_init2 (at the beginning of the iteration) and mpfr_clear (at the end of the iteration) on numOfTerms MPFR numbers, and the value of numOfTerms depends on the iteration. And this is what takes most of the time.
To avoid these many memory allocations by mpfr_init2 and deallocations by mpfr_clear, I suggest that you declare the array outside the while loop and initially call the mpfr_init2 outside the while loop. The length of the array (i.e. the number of terms) should be what you think is the maximum number of terms. What can happen is that for some iterations, the chosen number of terms was too small. In such a case, you need to increase the length of the array (this will need a reallocation) and call mpfr_init2 on the new elements. This will be the new length of the array for the remaining iterations, until the array needs to be enlarged again. After the while loop, do the mpfr_clear's.
When you need to enlarge the array, have a good strategy to choose the new number of elements. Just taking the needed value of numOfTerms for the current iteration may not be a good one, since it may yield many reallocations. For instance, make sure that you have at least a N% increase. Do some tests to choose the best value for N... See Dynamic array for instance. In particular, you may want to use the C++ implementation of dynamic arrays, as mentioned on this Wikipedia article.