简体   繁体   中英

strange index issue for a simple vector

I have one array like {7, 3, 1, 5, 2} for example. I want to get a max value from one index onwards, so the result should be like {7, 5, 5, 5, 2}. I just use a for loop like below. It throws strange heap overflow problem.

    int maxProfit(vector<int>& prices) {
      vector<int> maxRight;
      int runningMax = 0;
      for(auto i=(prices.size()-1);i>=0;i--){
        if(runningMax < prices[i]){
          runningMax = prices[i];
        }
        maxRight.push_back(runningMax);
      }  
      maxRight.push_back(runningMax);
      std::reverse(maxRight.begin(), maxRight.end());
      ......

But if i change to the below code, it works. Isn't the below code the same as the above one? I just changed the comparison of the index i to 0 or to 1.

    int maxProfit(vector<int>& prices) {
      vector<int> maxRight;
      int runningMax = 0;
      for(auto i=(prices.size()-1);i>=1;i--){
        if(runningMax < prices[i]){
          runningMax = prices[i];
        }
        maxRight.push_back(runningMax);
        
      }  
      if(runningMax < prices[0]){
        runningMax=prices[0];
      }
      std::reverse(maxRight.begin(), maxRight.end());
      ......

As was pointed out in a comment,

auto i=(prices.size()-1) , i is deduced to be unsigned value, and the condition i >= 0 is always true. You have accessing out of bounds of array.

Instead of using an index, use an iterator, in this case a std::vector::reverse_iterator .

for(auto it = prices.rbegin(); it != prices.rend(); ++it)
{
    if(runningMax < *it)
    {
        runningMax = *it;
    }
    maxRight.push_back(runningMax);    
}

As the variable i declared in the for loop

for(auto i=(prices.size()-1);i>=0;i--){

has the unsigned integer type std::vector<int>::size_type then you will get an infinite loop because when i is equal to 0 then the expression i-- will afain produces a non-negative number.

Another problem is that the for loop will again invoke undefined behavior if the passed vector is empty dues to the initialization in the declaration part of the for loop

auto i=(prices.size()-1)

because prices.size()-1 produces a positive value in this case.

In the second function implementation you forgot to push a calculated value for the first element of the vector prices . You just wrote after the loop

  if(runningMax < prices[0]){
    runningMax=prices[0];
  }

that does not make a great sense. ` You could write a separate function that returns the desired vector of maximum prices.

Here is a demonstrative program.

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

std::vector<int> max_prices( const std::vector<int> &prices )
{
    std::vector<int> maxRight;
    maxRight.reserve( prices.size() );
    
    for ( auto first = std::rbegin( prices), last = std::rend( prices ); 
          first != last; 
          ++first )
    {
        if ( maxRight.empty() )
        {
            maxRight.push_back( *first );
        }
        else 
        {
            maxRight.push_back( std::max( maxRight.back(), *first ) );
        }
    }         
    
    std::reverse( std::begin( maxRight ), std::end( maxRight ) );
    
    return maxRight;
}

int main() 
{
    std::vector<int> prices = { 7, 3, 1, 5, 2 };

    auto maxRight = max_prices( prices );
    
    for ( const auto &price : maxRight )
    {
        std::cout << price << ' ';
    }
    std::cout << '\n';
    
    return 0;
}

The program output is

7 5 5 5 2 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM