I'm currently trying to solve some problems of the Euler-Projects, but I'm currently stuck at the second problem. Here is what I have right now:
void p002()
{
unsigned int result = 0;
std::vector<int> fibonacci{ 1,2 };
for (int i = 2; fibonacci.at(i) < 4000000; i++)
{
fibonacci.at(i) = fibonacci.at(i - 1) + fibonacci.at(i - 2); //<- Doesn't work
if (fibonacci.at(i) % 2 == 0)
result += fibonacci.at(i);
}
std::cout << result;
}
Could someone help me out and tell me why this one line doesn't seem to work? (I get an "abort() called" error when trying to execute the code.)
In case anyone wonders: The task is to get the sum of all integers of the fibonacci sequence with a lower value than 4,000,000 which are even-valued.
Thanks!
vector::at throws an exception if you try to access an element at an index that is out of bounds. Your vector contains 2 elements (at indices 0 and 1). Therefore fibonacci.at(2) is out of bounds, and an exception is thrown. You don't catch the exception, so std::terminate is called. By default, std::terminate points to abort which terminates your process.
Solution: Add enough elements into the vector so that fibonacci.at(i) isn't out of bounds.
Related
While I was solving a problem in LeetCode, I found something very strange.
I have this line which I assume gives me a time limit exceeded error:
s.erase(i-k, k);
when I comment(//) this line, it doesn't show me time exceed error, but the strange part was, it has never executed even when i didn't comment it.
below is the entire code.
and Here is the problem link.
class Solution {
public:
string removeDuplicates(string s, int k) {
char prev = s[0];
int cnt = 1;
cnt = 1;
for(int i = 1; i < s.size() + 1; i++){
if(s[i] == prev){
cnt++;
} else {
if(cnt == k){
// when input is "abcd" it never comes to this scope
// which is impossible to run erase function.
s.erase(i-k, k);
i = 0;
}
if(i >= s.size()) break;
cnt = 1;
prev = s[i];
}
}
return s;
}
};
When Input is "abcd", it never even go to the if scope where 'erase' function is in.
Although 'erase' function never run, it still affect on the time complexity, and I can't get the reason.
Does anyone can explain this? or is this just problem of LeetCode?
Many online contest servers report Time Exceeding when program encounters critical error (coding bug) and/or crashes.
For example error of reading out of bounds of array. Or dereferencing bad (junk) pointers.
Why Time Exceeded. Because with critical error program can hang up and/or crash. Meaning it also doesn't deliver result in time.
So I think you have to debug your program to find all coding errors, not spending your time optimizing algorithm.
Regarding this line s.erase(i-k, k); - it may crash/hang-up when i < k, then you have negative value, which is not allowed by .erase() method. When you get for example i - k equal to -1 then size_t type (type of first argument of erase) will overflow (wrap around) to value 18446744073709551615 which is defnitely out of bounds, and out of memory border, hence your program may crash and/or hang. Also erase crashes when there is too many chars deleted, i.e. for erase s.erase(a, b) you have to watch that a + b <= s.size(), it is not controlled by erase function.
See documentation of erase method, and don't put negative values as arguments to this method. Check that your algorithm never has negative value i.e. never i < k when calling s.erase(i-k, k);, also never i-k + k > s.size(). To make sure there is no program crash you may do following:
int start = std::min(std::max(0, i-k), int(s.size()));
int num = std::min(k, std::max(0, int(s.size()) - start));
s.erase(start, num);
I am learning c++ and for a test problem I am using a for loop with condition prices.size()-1 so the vector does not go out of range.
std::vector<int> prices {7,1,5,3,6,4};
int maxProfit(vector<int>& prices) {
int total {0};
for (size_t i = 0; i < prices.size()-1; i++) {
if (prices.at(i+1) > prices.at(i)) {
total += prices.at(i+1) - prices.at(i);
}
}
return total;
}
But it is throwing this this runtime error that I cannot decipher:
terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check: __n (which is 1) >= this->size() (which is 0)
I cannot figure out the problem, can someone please show me what I am doing wrong.
Look at the error message carefully:
this->size() (which is 0)
The error message indicates that the passed-in vector is empty. Its size() is 0. Now take a closer look at the for-loop:
for (size_t i = 0; i < prices.size()-1; i++)
We've established that prices.size() is 0, so this becomes, effectively:
for (size_t i = 0; i < -1; i++)
But i is a size_t, which is an unsigned type, so -1 gets casted to an unsigned type.
Now, perform a little experiment yourself, see what output you get from the following statement:
std::cout << (size_t)-1 << std::endl;
Because of this, even though the vector is empty, the for loop's condition will still evaluate to true, and inside the for loop the code will attempt to access a non-existent array value, hence the exception.
Note that the function's parameter of prices has nothing to do with the global prices vector. The code from your program that you did not show passes in an empty vector, resulting in this error. Why the vector that gets passed in is empty, this is something you will need to figure out on your own.
Note that it's fairly easy to tweak the for-loop, just slightly, so that this edge case gets correctly handled. Simply change the for loop's condition as follows:
for (size_t i = 0; i+1 < prices.size(); i++)
Even though this seems to be the same thing, it's not (at least until you manage to create an array with about four billion, or so, values -- more on a 64 bit platform). Welcome to C++.
I have some code, where I'm using std::forward_list
Part of my code tests for vector subscripts being out of range, as well as if the element in the vector has certain properties (in this case, is not -1).
When I have just the first or second node of the list, it works fine and I can catch the error, as that's just a normal part of the program. However, on the next loop around, when I have 3 elements in the list, I get the vector subscript out of range debug assertion, and it isn't caught by my try/catch. Is there a different technique I must use to resolve this error?
Here's a snippet of the code, where it's problematic:
for(int i = 0; i < 8; i++)
{
if(curr->moves[i].at(0) >= 0 && curr->moves[i].at(1) >= 0)
{
next->setPos(curr->moves[i].at(0),curr->moves[i].at(1)); //just sets values of a vector
next->setMoves(); //sets values of a 2d vector
for(int j = 0; j < 8; j++)
{
try{if(board.kBoard[next->moves[i].at(0)][next->moves[i].at(1)] != -1) //the debug assertion is thrown here, but I cannot catch it
next->moves[i].at(2) = 1;}
catch(out_of_range const &err)
{next->moves[i].at(2) = 1;}
}
...
}
}
I've commented where the issue occurs. You'll (at least on my screen) have to scroll to the right to see it. I believe that, potentially, I can use another catch statement, but I don't know which error to use, given that I'm already using out_of_range, which normally would handle this issue. A screenshot of what the error looks like when it's thrown is this. To be completely clear, the issue occurs at try{if(board.kBoard[next->moves[i].at(0)][next->moves[i].at(1) != -1), where I have commented. It doesn't go to the catch statement at all, I think because it's using _DEBUG_ERROR()
While, theoretically, a try/catch statement could catch the error here, it isn't wise to intentionally cause errors as part of an algorithm; try/catch should be used to report when errors happen. In this case, I should have used:
if(next->moves[i].at(0) >= 0 && next->moves[i].at(1) >= 0) //1
if(board.kBoard[next->moves[i].at(0)][next->moves[i].at(1)] != -1) //2
next->moves[i].at(2) = 1; //3
else
next->moves[i].at(2) = 1; //3
This allows me to check if the subscript is out of range (1), check if an element of the board is not -1 (2), and set moves[i].at(2) to 1, in those cases (3).
This avoids any out_of_range errors, obviating the need for try/catch entirely.
I have gathered a large amount of extremely useful information from other peoples' questions and answers on SO, and have searched duly for an answer to this one as well. Unfortunately I have not found a solution to this problem.
The following function to generate a list of primes:
void genPrimes (std::vector<int>* primesPtr, int upperBound = 10)
{
std::ofstream log;
log.open("log.txt");
std::vector<int>& primesRef = *primesPtr;
// Populate primes with non-neg reals
for (int i = 2; i <= upperBound; i++)
primesRef.push_back(i);
log << "Generated reals successfully." << std::endl;
log << primesRef.size() << std::endl;
// Eratosthenes sieve to remove non-primes
for (int i = 0; i < primesRef.size(); i++) {
if (primesRef[i] == 0) continue;
int jumpStart = primesRef[i];
for (int jump = jumpStart; jump < primesRef.size(); jump += jumpStart) {
if (primesRef[i+jump] == 0) continue;
primesRef[i+jump] = 0;
}
}
log << "Executed Eratosthenes Sieve successfully.\n";
for (int i = 0; i < primesRef.size(); i++) {
if (primesRef[i] == 0) {
primesRef.erase(primesRef.begin() + i);
i--;
}
}
log << "Cleaned list.\n";
log.close();
}
is called by:
const int SIZE = 500;
std::vector<int>* primes = new std::vector<int>[SIZE];
genPrimes(primes, SIZE);
This code works well. However, when I change the value of SIZE to a larger number (say, 500000), the compiler returns a "segmentation error." I'm not familiar enough with vectors to understand the problem. Any help is much appreciated.
You are accessing primesRef[i + jump] where i could be primesRef.size() - 1 and jump could be primesRef.size() - 1, leading to an out of bounds access.
It is happening with a 500 limit, it is just that you happen to not have any bad side effects from the out of bound access at the moment.
Also note that using a vector here is a bad choice as every erase will have to move all of the following entries in memory.
Are you sure you wanted to do
new std::vector<int> [500];
and not
new std::vector<int> (500);
In the latter case, you are specifying the size of the vector, whose location is available to you via the variable named 'primes'.
In the former, you are requesting space for 500 vectors, each sized to the default that the STL library wants.
That would be something like (on my system : 24*500 bytes). In the latter case, 500 length vector(only one vector) is what you are asking for.
EDIT: look at the usage - he needs just one vector.
std::vector& primesRef = *primesPtr;
The problem lies here:
// Populate primes with non-neg reals
for (int i = 2; i <= upperBound; i++)
primesRef.push_back(i);
You only have N-2 elements in your vector pushed back, but then try to access an element at N-1 (i+jump). The fact that it did not fail on 500 is just dumb luck that the memory being overwritten was not catastrophic.
This code works well. However, when I change the value of SIZE to a larger number (say, 500000), ...
That may blow your stack, and be to big allocated with it. You need dynamic memory allocation for all of the std::vector<int> instances you believe to need.
To achieve that, simply use a nested std::vetcor like this.
std::vector<std::vector<int>> primes(SIZE);
instead.
But to get straight on, I seriously doubt you need number of SIZE vector instances to store all of the prime numbers found, but just a single one initialized like this:
std::vector<int> primes(SIZE);
I'm making a C++ game which requires me to initialize 36 numbers into a vector. You can't initialize a vector with an initializer list, so I've created a while loop to initialize it faster. I want to make it push back 4 of each number from 2 to 10, so I'm using an int named fourth to check if the number of the loop is a multiple of 4. If it is, it changes the number pushed back to the next number up. When I run it, though, I get SIGABRT. It must be a problem with fourth, though, because when I took it out, it didn't give the signal.
Here's the program:
for (int i; i < 36;) {
int fourth = 0;
fourth++;
fourth%=4;
vec.push_back(i);
if (fourth == 0) {
i++;
}
}
Please help!
You do not initialize i. Use for (int i = 0; i<36;). Also, a new variable forth is allocated on each iteration of the loop body. Thus the test fourth==0 will always yield false.
I want to make it push back 4 of each number from 2 to 10
I would use the most straight forward approach:
for (int value = 2; value <= 10; ++value)
{
for (int count = 0; count < 4; ++count)
{
vec.push_back(value);
}
}
The only optimization I would do is making sure that the capacity of the vector is sufficient before entering the loop. I would leave other optimizations to the compiler. My guess is, what you gain by omitting the inner loop, you lose by frequent modulo division.
You did not initialize i, and you are resetting fourth in every iteration. Also, with your for loop condition, I do not think it will do what you want.
I think this should work:
int fourth = 0;
for (int i = 2; i<=10;) {
fourth++;
fourth%=4;
vec.push_back(i);
if (fourth==0) {
i++;
}
}
I've been able to create a static array declaration and pass that array into the vector at initialization without issue. Pretty clean too:
const int initialValues[36] = {0,1,2...,35};
std::vector foo(initialValues);
Works with constants, but haven't tried it with non const arrays.