Vector giving inaccurate output - c++

vector<int> vect;
vector<int> sorted;
vect.push_back(5);
vect.push_back(3);
vect.push_back(7);
vect.push_back(2);
vect.push_back(9);
vect.push_back(6);
//Print vector elements
for (int x=0; x<vect.size(); x++)
cout << vect[x] << endl;
int min = 99999, idx=0;
while (vect.size() > 0)
{
for (int x=0; x<vect.size(); x++)
{
if (vect[x] < min)
{
min = vect[x];
idx = x;
}
}
cout << "Min index: " << idx << endl;
sorted.push_back(vect[idx]);
vect.erase(vect.begin()+idx);
}
for (int x=0; x<sorted.size(); x++)
cout << sorted[x] << endl;
I wanted to sort the vector of integers by storing the sorted numbers into vector<int> sorted. But the program always got terminated half way after hitting some unknown program error.
The only output I get is:
5
3
7
2
9
6
Min Index: 3
Min Index: 3
Min Index: 3
Min Index: 3
<Program Terminated At This Point>
I've been working on this for hours and I don't know why I always get index 3 as the smallest number. What have I done incorrectly in my implementation?
I have been thinking on it for hours, and my logic seems correct?

On your first pass, it finds out min is 2.
It then erases 2, which is at index 3.
Then it goes through again, except nothing is smaller than 2.
So it still has index 3, and erases it.
This continues until you no longer have more than 3 items.
Then it fails, because the vector is too small to erase index 3.
Reset your min back to 99999 before your for loop.

As what user Blastfurnace had pointed out. I forgot to reset the Min.
This should solve it.
int idx=0;
while (vect.size() > 0)
{
int min = 99999;
for (int x=0; x<vect.size(); x++)
{
if (vect[x] < min)
{
min = vect[x];
idx = x;
}
}
cout << "Min index: " << idx << endl;
sorted.push_back(vect[idx]);
vect.erase(vect.begin()+idx);
}

Related

hacker rank Mini-Max Sum

this problem
I normally erase the default code and start solving the whole thing myself. However, hackerrank test cases show a different output than the one that appears to me whenever i run against custom input. Why does it show different number?
Keep in mind I have tried different input sizes as float, long long int, int, and double;
#include <bits/stdc++.h>
using namespace std;
int main() {
long long int arr[5], neglect = 0, min = 9999999999999, max = 0, curr = 0;
for (int i = 0; i < 5; i++) {
cin >> arr[i];
}
while (neglect < 5) {
for (int i = 0; i < 5; i++) {
if (i == neglect) {i++;}
curr += arr[i];
}
if (curr < min) {min = curr;}
if (curr > max) {max = curr;}
//cout << curr << endl;
//cout << curr << " " << min << " " << max << endl;
curr = 0;
neglect++;
}
cout << min << " " << max;
}
All i wanted was to solve it in a way that tries all combinations then shows the least and maximum values. I know my code isn't the optimal way to solve it, I know i could just sort the array and exclude first and last elements, but please bear with me.
input: 1 2 3 4 5
claimed output: 11 4198826
but when i debugged it with the same custom input and the commented lines it showed:
14 14 14
13 13 14
12 12 14
11 11 14
10 10 14
10 14
Doesn't that mean that my code should be working?
When you are neglecting the last element you are doing an i++ and this will add the arr[5] to the curr value, but arr[5] is out of bound of the array, thus it can give segfault or unexpected result.
I would suggest that you should not increment the i in the for loop, instead you can use continue when you want to neglect the element.
for (int i = 0; i < 5; i++) {
if (i == neglect) {
continue;
}
curr += arr[i];
}
Also, you can replace the outer for loop with while loop so that you don't have to increment the neglect manually.

Merging points closest to each other in an array of 3 elements each

I am implementing a simple greedy merging algorithm that merges the two points which are closest to each other and averages their position. After merging two points at indices i and j, I need to replace one of them, say i, by the mean of the two points. Then, copy the last point in the array over the other point, say j, after which I can reduce the array size by 1 with all remaining points being within the new reduced range.
I need to repeat the above step until there are only 3 representative points left, each of which represents a group of merged points. I have written the following code, but I guess it is not able to update the array (pts). I would appreciate if anyone could help me figure out the mistake. Thanks in advance. This is my code:-
void merge_point(Point pts[], int &size) {
double a;
int x, y;
Point d;
while(size != 3) {
double min = get_distance(pts[0],pts[1]);
for (int i = 0; i < size; i++) {
for (int j = i+1; j < size; j++) {
get_distance(pts[i], pts[j]);
if ((a = get_distance(pts[i],pts[j])) <= min) {
x = i;
y = j;
}
a = get_distance(pts[i],pts[j]);
}
}
d = mean_point(pts[x],pts[y]);
pts[x] = d;
pts[y] = pts[size-1];
size = size - 1;
}
}
When I am entering the input array as :-
3 8 2
5.7 7.2 2.2
10.83 6.48 2.42
20.577 5.832 2.662
39.0963 5.2488 2.9282
74.283 4.72392 3.22102
141.138 4.25153 3.54312
268.162 3.82638 3.89743
509.507 3.44374 4.28718
968.063 3.09936 4.7159
My expected output should be:-
181.974 4.29686 3.57395
968.063 3.09936 4.7159
509.507 3.44374 4.28718
But, I am getting an output of:-
4.35 7.6 2.1
968.063 3.09936 4.7159
36.6506 5.8958 2.68145
Think I find out the problem, you don't update the min distance as soon as you find a new one during the cicle, try this:
cout << "distance between p[" << i << "] and " << "p[" << j << "]" << "is " << get_distance(pts[i], pts[j]) << '\n';
if ((a = get_distance(pts[i], pts[j])) <= min)
{
cout << "current min distance is between point[" << i << "]" << " and point[" << j << "]" << '\n';
min = a;
x = i;
y = j;
}
you've got to add this instruction:
min = a;
in order to update the min.
Otherwise it will works only for some edge cases.

finding minimum number of jumps

Working on below algorithm puzzle of finding minimum number of jumps. Posted detailed problem statement and two code versions to resolve this issue. I have did testing and it seems both version works, and my 2nd version is an optimized version of version one code, which makes i starts from i=maxIndex, other than continuous increase, which could save time by not iteration all the slots of the array.
My question is, wondering if my 2nd version code is 100% correct? If anyone found any logical issues, appreciate for pointing out.
Problem Statement
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
For example:
Given array A = [2,3,1,1,4]
The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)
First version code
class Solution {
public:
int jump(vector<int>& nums) {
int i = 0, n = nums.size(), step = 0, end = 0, maxend = 0;
while (end < n - 1) {
step++;
for (;i <= end; i++) {
maxend = max(maxend, i + nums[i]);
if (maxend >= n - 1) return step;
}
if(end == maxend) break;
end = maxend;
}
return n == 1 ? 0 : -1;
}
};
2nd version code
class Solution {
public:
int jump(vector<int>& nums) {
int i = 0, n = nums.size(), step = 0, end = 0, maxend = 0;
int maxIndex = 0;
while (end < n - 1) {
step++;
for (i=maxIndex;i <= end; i++) {
if ((i + nums[i]) > maxend)
{
maxend = i + nums[i];
maxIndex = i;
}
if (maxend >= n - 1) return step;
}
if(end == maxend) break;
end = maxend;
}
return n == 1 ? 0 : -1;
}
};
thanks in advance,
Lin
The best way is always to test it. A human cannot always think about special cases but a automated test can cover the most of speciale cases. If you think that your first version works well, you can compare the result of the first with the second one. Here an exemple:
/*
* arraySize : array size to use for the test
* min : min jump in the array
* max : max jump in the array
*/
void testJumps(int arraySize, int min, int max){
static int counter = 0;
std::cout << "-----------Test " << counter << "------------" << std::endl;
std::cout << "Array size : " << arraySize << " Minimum Jump : " << min << " Max Jump" << max << std::endl;
//Create vector with random numbers
std::vector<int> vecNumbers(arraySize, 0);
for(unsigned int i = 0; i < vecNumbers.size(); i++)
vecNumbers[i] = rand() % max + min;
//Value of first function
int iVersion1 = jump1(vecNumbers);
//Second fucntion
int iVersion2 = jump2(vecNumbers);
assert(iVersion1 == iVersion2);
std::cout << "Test " << counter << " succeeded" << std::endl;
std::cout << "-----------------------" << std::endl;
counter++;
}
int main()
{
//Two test
testJumps(10, 1, 100);
testJumps(20, 10, 200);
//You can even make a loop of test
//...
}

I tried coding my own simple moving average in C++

I want a function that works.
I believe my logic is correct, thus my (vector out of range error) must be coming from the lack of familiarity and using the code correctly.
I do know that there is long code out there for this fairly simple algorithm.
Please help if you can.
Basically, I take the length as the "moving" window as it loops through j to the end of the size of the vector. This vector is filled with stock prices.
If the length equaled 2 for a 2 day moving average for numbers 1 2 3 4. I should be able to output 1.5, 2.5, and 3.5. However, I get an out of range error.
The logic is shown in the code. If an expert could help me with this simple moving average function that I am trying to create that would be great! Thanks.
void Analysis::SMA()
{
double length;
cout << "Enter number days for your Simple Moving Average:" << endl;
cin >> length;
double sum = 0;
double a;
while (length >= 2){
vector<double>::iterator it;
for (int j = 0; j < close.size(); j++){
sum = vector1[length + j - 1] + vector1[length + j - 2];
a = sum / length;
vector2.push_back(a);
vector<double>::iterator g;
for (g = vector2.begin(); g != vector2.end(); ++g){
cout << "Your SMA: " << *g;
}
}
}
}
You don't need 3 loops to calculate a moving average over an array of data, you only need 1. You iterate over the array and keep track of the sum of the last n items, and then just adjust it for each new value, adding one value and removing one each time.
For example suppose you have a data set:
4 8 1 6 9
and you want to calculate a moving average with a window size of 3, then you keep a running total like this:
iteration add subtract running-total output average
0 4 - 4 - (not enough values yet)
1 8 - 12 -
2 1 - 13 13 / 3
3 6 4 15 15 / 3
4 9 8 16 16 / 3
Notice that we add each time, we start subtracting at iteration 3 (for a window size of 3) and start outputting the average at iteration 2 (window size minus 1).
So the code will be something like this:
double runningTotal = 0.0;
int windowSize = 3;
for(int i = 0; i < length; i++)
{
runningTotal += array[i]; // add
if(i >= windowSize)
runningTotal -= array[i - windowSize]; // subtract
if(i >= (windowSize - 1)) // output moving average
cout << "Your SMA: " << runningTotal / (double)windowSize;
}
You can adapt this to use your vector data structure.
Within your outermost while loop you never change length so your function will run forever.
Then, notice that if length is two and closes.size() is four, length + j - 1 will be 5, so my psychic debugging skills tell me your vector1 is too short and you index off the end.
This question has been answered but I thought I'd post complete code for people in the future seeking information.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<double> vector1 { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
double length;
cout << "Enter number days for your Simple Moving Average:" << endl;
cin >> length;
double sum = 0;
int cnt = 0;
for (int i = 0; i < vector1.size(); i++) {
sum += vector1[i];
cnt++;
if (cnt >= length) {
cout << "Your SMA: " << (sum / (double) length) << endl;
sum -= vector1[cnt - length];
}
}
return 0;
}
This is slightly different than the answer. A 'cnt' variable in introduced to avoid an additional if statement.

Vector cannot be overwritten

I'm trying to write a program for university. The goal of the program is to make a nurse schedule for a hospital. However, i'm really stuck for the moment. Below you can find one function of the program.
The input for the function is a roster which consists of the shift each nurse has to perform on each day. In this example, we have 32 rows (32 nurses) and 28 columns (representing 28 days). Each cell contains a number from 0 to 6, indicating a day off (0) or a certain shift (1 to 6).
The function should calculate for each day, how many nurses are scheduled for a certain shift. For example, on the first day, there are 8 nurses which perform shift 2, 6 shift 3 and so forth. The output of the function is a double vector.
I think the function is mostly correct but when I call it for different rosters the program always gives the first roster gave.
void calculate_nbr_nurses_per_shift(vector<vector<int>> roster1)
{
for (int i = 0; i < get_nbr_days(); i++)
{
vector<int> nurses_per_shift;
int nbr_nurses_free = 0;
int nbr_nurses_shift1 = 0;
int nbr_nurses_shift2 = 0;
int nbr_nurses_shift3 = 0;
int nbr_nurses_shift4 = 0;
int nbr_nurses_shift5 = 0;
int nbr_nurses_shift6 = 0;
for (int j = 0; j < get_nbr_nurses(); j++)
{
if (roster1[j][i] == 0)
nbr_nurses_free += 1;
if (roster1[j][i] == 1)
nbr_nurses_shift1 += 1;
if (roster1[j][i] == 2)
nbr_nurses_shift2 += 1;
if (roster1[j][i] == 3)
nbr_nurses_shift3 += 1;
if (roster1[j][i] == 4)
nbr_nurses_shift4 += 1;
if (roster1[j][i] == 5)
nbr_nurses_shift5 += 1;
if (roster1[j][i] == 6)
nbr_nurses_shift6 += 1;
}
nurses_per_shift.push_back(nbr_nurses_shift1);
nurses_per_shift.push_back(nbr_nurses_shift2);
nurses_per_shift.push_back(nbr_nurses_shift3);
nurses_per_shift.push_back(nbr_nurses_shift4);
nurses_per_shift.push_back(nbr_nurses_shift5);
nurses_per_shift.push_back(nbr_nurses_shift6);
nurses_per_shift.push_back(nbr_nurses_free);
nbr_nurses_per_shift_per_day.push_back(nurses_per_shift);
}
}
Here you can see the program:
Get_shift_assignment() and schedule_LD are other rosters.
void test_schedule_function()
{
calculate_nbr_nurses_per_shift(schedule_LD);
calculate_nbr_nurses_per_shift(get_shift_assignment());
calculate_coverage_deficit();
}
One more function you need to fully understand the problem is this one:
void calculate_coverage_deficit()
{
int deficit = 0;
for (int i = 0; i < get_nbr_days(); i++)
{
vector<int> deficit_day;
for (int j = 0; j < get_nbr_shifts(); j++)
{
deficit = get_staffing_requirements()[j] - nbr_nurses_per_shift_per_day[i][j];
deficit_day.push_back(deficit);
}
nurses_deficit.push_back(deficit_day);
}
cout << "Day 1, shift 1: there is a deficit of " << nurses_deficit[0][0] << " nurses." << endl;
cout << "Day 1, shift 2: there is a deficit of " << nurses_deficit[0][1] << " nurses." << endl;
cout << "Day 1, shift 3: there is a deficit of " << nurses_deficit[0][2] << " nurses." << endl;
cout << "Day 1, shift 4: there is a deficit of " << nurses_deficit[0][3] << " nurses." << endl;
}
So the problem is that each time I run this program it always gives me the deficits of the first roster. In this case, this is Schedule_LD. When I first run the function with input roster get_shift_assignment() than he gives me the deficits for that roster.
Apparently the nbr_nurses_per_shift_per_day[][] vector is not overwritten the second time I run the function and I don't know how to fix this... Any help would be greatly appreciated.
Let me try to summarize the comments:
By using global variables to return values from your functions it is very likely, that you forgot to remove older results from one or more of your global variables before calling functions again.
To get around this, return your results from the function instead.
Ex:
vector<vector<int>> calculate_nbr_nurses_per_shift(vector<vector<int>> roster1)
{
vector<int> nbr_nurses_per_shift_per_day; // Create the result vector
... // Do your calculations
return nbr_nurses_per_shift_per_day;
}
or if you do not want to return a vector:
void calculate_nbr_nurses_per_shift(vector<vector<int>> roster1, vector<vector<int>> nbr_nurses_per_shift_per_day)
{
... // Do your calculations
}
But clearly, the first variant is a lot less error-prone (in the second example you can forget to clear nbr_of_nurses again) and most compilers will optimize the return nbr_nurses_per_shift_per_day so the whole vector does not get copied.
The second possible issue is that ´get_nbr_days()´ might return numbers that are larger or smaller than the actual size of your vector. To work around this, use either the size() method of vector or use iterators instead.
Your first function would then look like this:
vector<vector<int>> calculate_nbr_nurses_per_shift(vector<vector<int>> roster1)
{
vector<vector<int>> nbr_nurses_per_shift_per_day;
for (vector<vector<int>>::iterator shiftsOnDay = roster1.begin(); shiftsOnDay != roster1.end(); ++shiftsOnDay)
{
vector<int> nurses_per_shift(6, 0); // Create vector with 6 elements initialized to 0
for (vector<int>::iterator shift = shiftsOnDay->begin(); shift != shiftsOnDay->end(); ++shift)
{
if (*shift == 0)
nurses_per_shift[5]++;
else
nurses_per_shift[*shift - 1]++; // This code relies on shift only containing meaningful values
}
nbr_nurses_per_shift_per_day.push_back(nurses_per_shift);
}
return nbr_nurses_per_shift_per_day;
}