Сигнал SIGSEGV при повторении карты в переполнении стека

Я пытаюсь исправить это в течение приблизительно 5 дней, и не повезло, каждое решение, которое я попробовал, не удалось.

Я нашел причину SIGSEGV ниже, но ничего не помогло
Что такое ошибка во время выполнения SIGSEGV в C ++?

Хорошо, вот код.
У меня есть 2 экземпляра, которые содержат некоторые ключевые слова-функции и их оценки

Я хочу получить их евклидово расстояние, что означает, что я должен сохранить все ключевые слова для каждого экземпляра, затем найти различия для ключевых слов первого и второго, а затем найти различия для оставшихся второго пример. Что я хочу, так это при выполнении итерации первой карты, чтобы иметь возможность удалять элементы со второй. Следующий метод вызывается несколько раз, так как у нас есть две коллекции сообщений, и каждое сообщение из первого сравнивается с каждым сообщением из второго.

У меня есть этот код, но он внезапно останавливается, хотя я проверил, что он работает в течение нескольких секунд с несколькими Cout, я положил в некоторых местах

Обратите внимание, что это для университетской задачи, поэтому я не могу использовать повышение и все эти приемы. Но я хотел бы знать, как обойти проблему, с которой я сталкиваюсь.

float KNNClassifier::distance(const Instance& inst1, const Instance& inst2) {
map<string,unsigned> feat1;
map<string,unsigned> feat2;
for (unsigned i=0; i<inst1.getNumberOfFeatures(); i++) {
feat1[inst1.getFeature(i)]=i;
}
for (unsigned i=0; i<inst2.getNumberOfFeatures(); i++) {
feat2[inst2.getFeature(i)]=i;
}
float dist=0;

map<string,unsigned>::iterator it;
for (it=feat1.begin(); it!=feat1.end(); it++) {
if (feat2.find(it->first)!=feat2.end()) {//if and only if it exists in inst2
dist+=pow( (double) inst1.getScore(it->second) - inst2.getScore(feat2[it->first]) , 2.0);
feat2.erase(it->first);
}
else {
dist+=pow( (double) inst1.getScore(it->second) , 2.0);
}
}

for (it=feat2.begin(); it!=feat2.end(); it++) {//for the remaining words
dist+=pow( (double) inst2.getScore(it->second) , 2.0);
}
feat1.clear(); feat2.clear(); //ka8arizoume ta map gia thn epomenh xrhsh
return sqrt(dist);
}

и я тоже попробовал эту идею, чтобы не пришлось что-то удалять, но она тоже внезапно останавливается.

float KNNClassifier::distance(const Instance& inst1, const Instance& inst2) {
map<string,unsigned> feat1;
map<string,unsigned> feat2;
map<string,bool> exists;
for (unsigned i=0; i<inst1.getNumberOfFeatures(); i++) {
feat1[inst1.getFeature(i)]=i;
}
for (unsigned i=0; i<inst2.getNumberOfFeatures(); i++) {
feat2[inst2.getFeature(i)]=i;
exists[inst2.getFeature(i)]=false;
if (feat1.find(inst2.getFeature(i))!=feat1.end()) {
exists[inst2.getFeature(i)]=true;
}
}
float dist=0;
map<string,unsigned>::iterator it;
for (it=feat1.begin(); it!=feat1.end(); it++) {
if (feat2.find(it->first)!=feat2.end()) {
dist+=pow( (double) inst1.getScore(it->second) - inst2.getScore(feat2[it->first]) ,      2.0);
}
else {
dist+=pow( (double) inst1.getScore(it->second) , 2.0);
}
}

for (it=feat2.begin(); it!=feat2.end(); it++) {
if(it->second==false){//if it is true, it means the diff was done in the previous iteration
dist+=pow( (double) inst2.getScore(it->second) , 2.0);
}
}

feat1.clear(); feat2.clear(); exists.clear();
return sqrt(dist);
}

0

Решение

Сам по себе код, кажется, в порядке (ошибка, которую я думал, я обнаружил ранее, была не одна). Тем не мение,
может быть более простой подход:

  1. Вместо того чтобы искать строку из первого набора во втором наборе, можно было бы перемещаться по двум спискам одновременно и перемещать итератор к меньшему элементу или к обоим итераторам, если они используют одну и ту же строку. Соответствующее вычисление выполняется непосредственно в каждом случае.
  2. Я бы лично использовал два отсортированных std::vector<std::pair<std::string, unsigned int> > за это но std::map<std::string, unsigned int> работает так же.

У меня нет доступа к вашему Instance класс и, таким образом, не проверял это, но что-то вроде ниже должно работать.

struct compare1st {
bool operator()(std::pair<std::string, unsigned int> const& p1,
std::pair<std::string, unsigned int> const& p2) const {
return p1.first < p2.first;
}
};

std::vector<std::pair<std::string, unsigned int> > fill(Instance const& inst) {
std::vector<std::pair<std::string, unsigned int> > rc;
for (unsigned int i(0), end(inst.getNumberOfFeatures()); i != end; ++i) {
rc.push_back(std::make_pair(inst.getFeature(i), i));
}
std::sort(rc.begin(), rc.end(), compare1st());
return rc;
}
double square(double d) { // pow(d, 2.0) is fairly expensive
return d * d;
}

float KNNClassifier::distance(const Instance& inst1, const Instance& inst2) {
typedef std::pair<std::string, unsigned int> Pair;
std::vector<Pair> feat1 = fill(inst1);
std::vector<Pair> feat2 = fill(inst2);

std::vector<Pair>::const_iterator it1(feat1.begin()), end1(feat1.end());
std::vector<Pair>::const_iterator it2(feat2.begin()), end2(feat2.end());
double result(0.0);
while (it1 != end1 && it2 != end2) {
if (it1 != end1 && (it2 == end2 || it1->first < it2->first)) {
result += square(inst1.getScore((it1++)->second);
}
else if (it2 != end2 && (it1 == end1 || it2->first < it1->first))
result += square(inst2.getScore((it2++)->second);
}
else {
result += square(inst1.getScore((it1++)->second)
-  inst2.getScore((it2++)->second);
}
}
return sqrt(result);
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]