我对下面的代码有疑问。我的编译器告诉我,我有一个
_Xout_of_range("invalid vector<T> subscript");
我一直在浏览所有代码,试图找出它的位置。我的教授说,它与我使用.size()有关,或者当我试图找到我的矢量大小时,我做了一些额外的事情,导致它超出界限。你们可以推荐一些建议吗?
//
//DiscreteDistribution.hpp
//
#ifndef _DISCRETE_DISTRIBUTION_GUARD
#define _DISCRETE_DISTRIBUTION_GUARD
#include <utility>
#include <vector>
#include <iostream>
#include <sstream>
#include <iomanip>
#include "Random.h"
#include "Types.h"
//Reference used: http://www.cplusplus.com/reference/utility/pair/
/*
// Map-based distribution <KEY, WEIGHT>
// where the weight is cumulative (allowing random number generation)
// to return the key value
*/
template<typename KEY_T>
class DiscreteDistribution
{
private:
WEIGHT_T max() const
{
return _valueToWeightMap.back().second;
}
public:
DiscreteDistribution() :_valueToWeightMap{}, _rng{}
{}
DiscreteDistribution(const DiscreteDistribution<KEY_T>& orig) : _valueToWeightMap {orig._valueToWeightMap}
{
}
const DiscreteDistribution& operator=(const DiscreteDistribution<KEY_T>& orig)
{
return orig;
}
virtual ~DiscreteDistribution()
{
_valueToWeightMap.clear();
}
/* @param key -- key value for mapping
* @param weight -- weight of the particular key
* If the key is not in the distribution, add it, otherwise,
* @throws std::string object for negative weights (when the @param weight is cast to a standard int)
*/
void add(KEY_T key, WEIGHT_T weights)
{
WEIGHT_T delta = 0;
bool keycheck = false;
int index = -1;
//Throw exception if weight below zero.
if ( (int) weights < 0)
{
throw std::string("Warning::was this weight intended; Negative weight?");
}
//Check for existing pairs.
for (int i = 0; i < _valueToWeightMap.size(); i++)
{
//If _vTwM index equals key. Set the index to 'i' and boolean to true.
if (_valueToWeightMap.at(i).first == key)
{
index = i;
keycheck = true;
}
}
//If the index is less than zero...and there are no existing pairs.
if (index < 0)
{
//And keycheck is true (see past evaluation above)...
if (keycheck)
{
//Get the max weight and set it to instance variable WEIGHT_T delta and add it to the 'weights' value
//to get the new weight to add to the pair.
delta = _valueToWeightMap.at(_valueToWeightMap.size()).second;
weights += delta;
}
//New pair to push back.
_valueToWeightMap.push_back(std::pair<KEY_T, WEIGHT_T> ( key, weights ));
}
else
{
//Find the change in weight set to delta.
delta = _valueToWeightMap.at(index).second - ((int) weights);
//Loop through and find the change in weight at each 'i'.
for (int i = index; i < _valueToWeightMap.size(); i++)
{
_valueToWeightMap.at(i).second -= delta;
}
}
}
/* @param key -- key value for mapping
* @return the weight in the discrete distribution
* Get the weight at the given key value.
*/
WEIGHT_T weight(KEY_T key) const
{
WEIGHT_T weightAtKey;
for (int i = 0; i < _valueToWeightMap.size(); i++)
{
//if the key _value at the index i is equal to the key value being passed in...get it's weight (if it has one).
if (_valueToWeightMap.at(i).first == key)
{
//Current minus the prev to get the weight difference.
weightAtKey = _valueToWeightMap.at(i).second - _valueToWeightMap.at(i - 1).second;
}
}
return weightAtKey;
}
/*
* Take the value(key) at whatever the index and divide that over the cumulative weight to find the
* probability after adjusting for the difference.
*/
double DiscreteDistribution::probability(KEY_T key) const
{
//Set the weight by finding the given key value's weight.
double wgt = (double) weight(key);
if (wgt != 0)
{
//Take the cumulative weight divided by the max to get probability.
return wgt / max();
}
return 0;
}
// @return Based on the given weights, roll a die to return the resulting key value
// Use Random rng to find this.
KEY_T operator()() const
{
//Find the cumulative weight between 1 and the max.
int die = _rng.nextInt(1, max());
//Loop through and compare weights and return the key that closely corresponds to the weight found.
//Example <'A', 49>
// <'B', 40>
// <'C', 35>
//Die roll is 45. Since 45 is less than the key value at 'A', it will not return' A', but instead,
//Returns 'B' since it's the closest value to 45.
for(std::pair<KEY_T, WEIGHT_T> pair : _valueToWeightMap)
{
if(die <= pair.second)
{
return pair.first;
}
}
return 0;
}
// toString and overloaded output operator
std::string toString() const;
friend std::ostream& operator<<(std::ostream& os, const DiscreteDistribution& dis)
{
//Simply output the ToString.
os << dis.toString();
return os;
}
protected:
// Map of keys to cumulative weights
std::vector<std::pair<KEY_T, WEIGHT_T> > _valueToWeightMap;
// The random number generator
Random _rng;
};
#endif
答案 0 :(得分:2)
你的教授是对的。您无法在其size()
索引向量,因为容器在C ++中是0索引的。
这超出范围:
_valueToWeightMap.at(_valueToWeightMap.size())
答案 1 :(得分:1)
您无法访问大小的矢量。罪魁祸首就是这条线
delta = _valueToWeightMap.at(_valueToWeightMap.size()).second;
如果您想访问最后一个元素,请执行此操作
delta = _valueToWeightMap.at(_valueToWeightMap.size() - 1).second;