I've neglected to work on this code (or any other coding projects) for a while, so while I know what is basically wrong with the code, I've been having a hard time finding exactly where the vector is going out of range. I've been running gdb on it all morning to no avail. I'm trying to make a min-heap out of a vector "theData" in C++.
#include <iostream>
#include <vector>
#include <algorithm>
using std::vector;
using std::cin;
using std::cout;
using std::swap;
using std::pair;
using std::make_pair;
class HeapBuilder {
private:
vector<int> data_;
vector< pair<int, int> > swaps_;
void WriteResponse() const {
cout << swaps_.size() << "\n";
for (int i = 0; i < swaps_.size(); ++i) {
cout << swaps_[i].first << " " << swaps_[i].second << "\n";
}
}
void ReadData() {
int n;
cin >> n;
data_.resize(n);
for(int i = 0; i < n; ++i)
cin >> data_[i];
}
void makeMinHeap(vector<int> &theData, int i, int n) {
int minIndex;
int left = 2*i;
int right = 2*i + 1;
if (left < n && theData.at(left) < theData.at(i)) {
minIndex = left;
}
else if (right < n && theData.at(right) < theData.at(i)) {
minIndex = right;
}
if (minIndex != i) {
swap(theData.at(i), theData.at(minIndex));
swaps_.push_back(make_pair(i, minIndex));
makeMinHeap(theData, minIndex, n);
}
}
void GenerateSwaps() {
swaps_.clear();
int size = data_.size();
for (int i = (size/2); i >= 0; i--) {
makeMinHeap(data_, i, size);
}
}
public:
void Solve() {
ReadData();
GenerateSwaps();
WriteResponse();
}
};
int main() {
std::ios_base::sync_with_stdio(false);
HeapBuilder heap_builder;
heap_builder.Solve();
return 0;
}
You are not putting in a check for minIndex.
Look what happens when your left<=n and right <=n both fails, most likely when the whole recursion is about to stop, since you just check
minIndex != i
// ^-- default each time is garbage which in case last>n && right>n leaves it garbage
// hence when it comes to
if(minIndex!=i){
// It's actually true where it was suppose to break out n thus throws out_of_range
}
Quick n easy solution would be to add a flagcheck
bool flagcheck = false;
if(){ flagcheck = true; }
else if(){ flagcheck = true; }
if(minIndex!=i && flagcheck){}
Related
This question already has an answer here:
Clion exit code -1073741571 (0xC00000FD)
(1 answer)
Closed 2 years ago.
The c++ code below works fine for some inputs, but it is stuck at test 9 (number of inputs here is 6000) where it gives me this message "Process returned -1073741571 (0xC00000FD)".
This code reads information for n babies (their gender and name). Next it counts the appearances of each name then sorts the list of structures according to the appearances. Finally, it removes the duplicates and prints the top m female names and top m male names.
What does this error mean and what do I need to change to eliminate this error?
#include <iostream>
#include <fstream>
#include <algorithm>
#include <string.h>
using namespace std;
ifstream fin("input.txt");
struct baby
{
string gender,name;
int cnt;
};
bool cmp(baby a,baby b)
{
if (a.cnt>b.cnt)
return true;
else if (a.cnt==b.cnt && a.name<b.name)
return true;
return false;
}
int howmany(baby babies[],int n,int i)
{
int cnt=0;
for (int j=0; j<n; j++)
{
if (babies[i].name==babies[j].name && babies[i].gender==babies[j].gender)
{
cnt++;
}
}
return cnt;
}
void getData(baby babies[],int n)
{
for (int i=0; i<n; i++)
{
fin>>babies[i].gender>>babies[i].name;
}
}
int removeDuplicates(baby babies[],int n)
{
int j=0;
for (int i=0; i<n-1; i++)
{
if (babies[i].name!=babies[i+1].name)
babies[j++]=babies[i];
}
babies[j++]=babies[n-1];
return j;
}
int main()
{
int n,i,top,j;
fin>>n>>top;
baby babies[50000];
getData(babies,n);
for (i=0; i<n; i++)
{
babies[i].cnt=howmany(babies,n,i);
}
sort(babies,babies+n,cmp);
j=removeDuplicates(babies,n);
int cnt=0;
for (int i=0; i<j; i++)
{
if (cnt<top)
{
if (babies[i].gender=="F")
{
cout<<babies[i].name<<" ";
cnt++;
}
}
}
cout<<endl;
cnt=0;
for (int i=0; i<j; i++)
{
if (cnt<top)
{
if (babies[i].gender=="M")
{
cout<<babies[i].name<<" ";
cnt++;
}
}
}
return 0;
}
As you can see in Window's NT status reference, error code 0xC00000FD means stack overflow (usually caused by infinite recursion). In your case, it seems that you simply allocate a far too large array on the stack (line 57, baby babies[50000];), which is an array of size 50000*20=1000000. The simplest solution will be a dynamic allocation
baby* babies = new baby[50000];
// Your code here
delete[] babies;
A better solution would be to use std::vector which is a dynamic array that can grow and shrink. The simplest thing to do is to take a vector of size 50000, this way:
#include <vector>
...
std::vector<baby> babies(50000);
However, this is a poor solution as your pre-allocate 50000 elements even though you probably need much much less, and a better solution would be to add an element on-demand, using .push_back(element) method, or in your case, allocate n elements to the vector (impossible in a stack-allocated array).
I added your code with some modifications of mine:
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
ifstream fin("input.txt");
struct baby
{
string gender;
string name;
int cnt = 0;
};
bool cmp(const baby& a, const baby& b)
{
if (a.cnt > b.cnt) {
return true;
}
return a.cnt == b.cnt && a.name < b.name;
}
bool are_equal(const baby& lhs, const baby& rhs)
{
return lhs.gender == rhs.gender && lhs.name == rhs.name;
}
int howmany(const std::vector<baby>& babies, int i)
{
int cnt = 0;
for (int j = 0; j < babies.size(); j++)
{
if (babies[i].name == babies[j].name && babies[i].gender == babies[j].gender)
{
cnt++;
}
}
return cnt;
}
void getData(std::vector<baby>& babies)
{
for (int i = 0; i < babies.size(); i++)
{
fin >> babies[i].gender >> babies[i].name;
}
}
int removeDuplicates(std::vector<baby>& babies)
{
int j = 0;
for (int i = 0; i < babies.size() - 1; i++)
{
if (babies[i].name != babies[i + 1].name) {
babies[j++] = babies[i];
}
}
babies[j++] = babies.back();
return j;
}
void remove_duplicates_improved(std::vector<baby>& babies)
{
babies.erase(babies.begin(), std::unique(babies.begin(), babies.end(), are_equal));
}
int main()
{
int n;
int top;
fin >> n >> top;
std::vector<baby> babies(n);
getData(babies);
for (int i = 0; i < n; i++)
{
babies[i].cnt = howmany(babies, i);
}
sort(babies.begin(), babies.begin() + n, cmp);
remove_duplicates_improved(babies);
int cnt = 0;
for (int i = 0; i < babies.size(); i++)
{
if (cnt < top)
{
if (babies[i].gender == "F")
{
cout << babies[i].name << " ";
cnt++;
}
}
}
cout << endl;
cnt = 0;
for (int i = 0; i < babies.size(); i++)
{
if (cnt < top)
{
if (babies[i].gender == "M")
{
cout << babies[i].name << " ";
cnt++;
}
}
}
return 0;
}
Good luck
I've been trying to solve the Minimum Spanning Tree on Kattis. (https://open.kattis.com/problems/minspantree) The first test runs fine, the second gives an unspecified runtime error. I've been struggling with this for over a week. It must be some logical error, but no matter how much effort i'm putting into it, I can't see what's wrong.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <tuple>
using namespace std;
class DisjointSet {
public:
vector<int> parent, rank;
DisjointSet(int _size) {
parent.resize(_size);
rank.resize(_size); // Maybe this?
// make the sets
for (int i = 0; i < _size; i++) { // fill set
parent[i] = i;
rank[i] = 0;
}
}
void make_set(int v) {
parent[v] = v;
rank[v] = 0;
}
int find_set(int v) {
if (v == parent[v])
return v;
return parent[v] = find_set(parent[v]);
}
void union_sets(int a, int b) {
a = find_set(a);
b = find_set(b);
if (a != b) {
if (rank[a] < rank[b])
swap(a, b);
parent[b] = a;
if (rank[a] == rank[b])
rank[a]++;
}
}
};
bool sort_weight(const tuple<int, int, int> &one, const tuple<int, int, int> &two) {
return get<2>(one) < get<2>(two); // Weight
}
bool sort_node(const tuple<int, int, int> &one, const tuple<int, int, int> &two) {
if (get<0>(one) != get<0>(two)) {
return get<0>(one) < get<0>(two); // node one
}
return get<1>(one) < get<1>(two); // node two
}
int main()
{
int n_nodes = 0, n_arcs = 0;
int tmp_node1, tmp_node2, tmp_weight;
while (cin >> n_nodes >> n_arcs) { // Until the end
if (n_nodes == 0 && n_arcs == 0) { break; }
if (n_arcs < n_nodes - 1) { // If it is not possible to build a MST
cout << "Impossible\n";
}
else {
int cost = 0;
DisjointSet s(n_nodes); // make set
vector<tuple<int, int, int>> vArcs;
vector<tuple<int, int, int>> vResult;
vArcs.resize(n_arcs);
for (int i = 0; i < n_arcs; i++) {
cin >> tmp_node1 >> tmp_node2 >> tmp_weight;
vArcs[i] = make_tuple(tmp_node1, tmp_node2, tmp_weight);
}
sort(vArcs.begin(), vArcs.end(), sort_weight); // Sort by weight lowest to highest
for (int i = 0; i < n_arcs && vResult.size()<(n_nodes - 1); i++)
{
if (s.find_set(get<0>(vArcs[i])) != s.find_set(get<1>(vArcs[i]))) {
cost += get<2>(vArcs[i]);
vResult.push_back(vArcs[i]);
s.union_sets(get<0>(vArcs[i]), get<1>(vArcs[i]));
}
}
// We are done, order and print
sort(vResult.begin(), vResult.end(), sort_node);
cout << cost << "\n";
for (int i = 0; i < vResult.size(); i++)
{
cout << get<0>(vResult[i]) << " " << get<1>(vResult[i]) << "\n";
}
}
}
}
You need to read the whole input for each test case, even if the number of edges is below n - 1.
In my Intro to Computer Science class I am beginning to learn the basics of sorting algorithms. So far, we have gone over Bubble, Selection, and Insertion Sort.
After class today, the instructor has requested us to "enhance" the program by adding code to print out the vector/array after every swap during the sorting. I am at a complete loss as to how I would make this happen. I'm thinking something like :
if (swapped) { cout << vec << " "; }
but without even trying, I'm certain this wouldn't work. Any help is very much appreciated. Here's my code so far:
#include <string>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> createVec(int n) {
unsigned seed = time(0);
srand(seed);
vector<int> vec;
for (int i = 1; i <= n; ++i) {
vec.push_back(rand() % 100 + 1);
}
return vec;
}
void showVec(vector<int> vec) {
for (int n : vec) {
cout << n << " ";
}
}
void bubbleSort(vector<int> &vec) {
int n = vec.size();
bool swapped = true;
while (swapped) {
swapped = false;
for (int i = 1; i <= n-1; ++i) {
if (vec[i-1] > vec[i]) {
swap(vec[i-1], vec[i]);
swapped = true;
}
}
}
}
void selectionSort(vector<int> &vec) {
int n = vec.size();
int maxIndex;
for (int i = 0; i <= n-2; ++i) {
maxIndex = i;
for (int j = i+1; j <= n-1; ++j) {
if (vec[j] < vec[maxIndex]) {
maxIndex = j;
}
}
swap(vec[i], vec[maxIndex]);
}
}
int main()
{
vector<int> numbers = createVec(20);
showVec(numbers);
cout << endl;
//bubbleSort(numbers);
selectionSort(numbers);
showVec(numbers);
return 0;
}
For example in the called function selectionSort substitute this statement
swap(vec[i], vec[maxIndex]);
for the following statement
if ( i != maxIndex )
{
swap(vec[i], vec[maxIndex]);
showVec( vec );
cout << endl;
}
Also the function showVec should declare the parameter as having a constant referenced type
void showVec( const vector<int> &vec) {
for (int n : vec) {
cout << n << " ";
}
}
Below is my program to build a min-heap using a 0 based array with standard logic from the book. I am using 2*i+1 for left child and 2*i+2 for right child since its a zero based array, still I am getting a wrong output. What am I missing?
#include <iostream>
#include <vector>
#include <algorithm>
using std::vector;
using std::cin;
using std::cout;
class HeapBuilder {
private:
vector<int> data_;
void WriteResponse() const {
for (int i = 0; i < data_.size(); ++i) {
cout << data_[i] << "\n";
}
}
void ReadData() {
int n;
cin >> n;
data_.resize(n);
for (int i = 0; i < n; ++i)
cin >> data_[i];
}
void MinHeapSort(int index)
{
int left = (2 * index) + 1;
int right = (2 * index) + 2;
int smallest;
if (left < data_.size() && data_[left] < data_[index])
smallest = left;
else
smallest = index;
if (right < data_.size() && data_[right] < data_[index])
smallest = right;
if (smallest != index)
{
swap(data_[smallest], data_[index]);
MinHeapSort(smallest);
}
}
void Heapify() {
for (int i = (data_.size() - 1) / 2; i >= 0; i--)
{
MinHeapSort(i);
}
}
public:
void Solve() {
ReadData();
Heapify();
WriteResponse();
}
};
int main() {
std::ios_base::sync_with_stdio(false);
HeapBuilder heap_builder;
heap_builder.Solve();
return 0;
}
Replaced if (right < data_.size() && data_[right] < data_[index]) with
if (right < data_.size() && data_[right] < data_[smallest])
That worked, silly mistake.
My code is in
#include <iostream>
#include <string>
#include <algorithm>
#include <climits>
#include <vector>
#include <cmath>
using namespace std;
struct State {
int v;
const State *rest;
void dump() const {
if(rest) {
cout << ' ' << v;
rest->dump();
} else {
cout << endl;
}
}
State() : v(0), rest(0) {}
State(int _v, const State &_rest) : v(_v), rest(&_rest) {}
};
void ss(int *ip, int *end, int target, const State &state) {
if(target < 0) return; // assuming we don't allow any negatives
if(ip==end && target==0) {
state.dump();
return;
}
if(ip==end)
return;
{ // without the first one
ss(ip+1, end, target, state);
}
{ // with the first one
int first = *ip;
ss(ip+1, end, target-first, State(first, state));
}
}
vector<int> get_primes(int N) {
int size = floor(0.5 * (N - 3)) + 1;
vector<int> primes;
primes.push_back(2);
vector<bool> is_prime(size, true);
for(long i = 0; i < size; ++i) {
if(is_prime[i]) {
int p = (i << 1) + 3;
primes.push_back(p);
// sieving from p^2, whose index is 2i^2 + 6i + 3
for (long j = ((i * i) << 1) + 6 * i + 3; j < size; j += p) {
is_prime[j] = false;
}
}
}
}
int main() {
int N;
cin >> N;
vector<int> primes = get_primes(N);
int a[primes.size()];
for (int i = 0; i < primes.size(); ++i) {
a[i] = primes[i];
}
int * start = &a[0];
int * end = start + sizeof(a) / sizeof(a[0]);
ss(start, end, N, State());
}
It takes one input N (int), and gets the vector of all prime numbers smaller than N.
Then, it finds the number of unique sets from the vector that adds up to N.
The get_primes(N) works, but the other one doesn't.
I borrowed the other code from
How to find all matching numbers, that sums to 'N' in a given array
Please help me.. I just want the number of unique sets.
You've forgotten to return primes; at the end of your get_primes() function.
I'm guessing the problem is:
vector<int> get_primes(int N) {
// ...
return primes; // missing this line
}
As-is, you're just writing some junk here:
vector<int> primes = get_primes(N);
it's undefined behavior - which in this case manifests itself as crashing.