Classis task for splitting weights into 2 trucks (C++) (Dynamic Programming) - c++

I have a task that by given line of weights of cages and I have to split them into 2 trucks. The split should be done like this that |a - b| to have least value where 'a' is the common weight of the cages in the first truck and 'b' is the common weight of the cages of second truck. My program seems to work but when I upload it to hackerrank abort function is called. So where is my fault? Here is the code:
#include <iostream>
#include <vector>
#include <sstream>
#include <cstring>
using namespace std;
int main()
{
string input;
int k;
while (getline(cin, input))
{
/* splitting the input into integers */
vector<int> v;
istringstream iss(input);
while (iss >> k) v.push_back(k);
/* --- II --- */
unsigned long sum = 0;
unsigned i, j;
for (i = 0; i < v.size(); i++)
sum += v[i];
vector<char> can;
can.push_back(1);
for (i = 1; i <= sum; i++)
can[i] = 0;
for (i = 0; i < v.size(); i++)
{
for (j = sum; j+1 > 0; j--)
{
if (can[j])
{
can[j + v[i]] = 1;
}
}
}
for (i = sum / 2; i > 1; i--)
{
if (can[i])
{
if (i <= sum - i)
{
cout << i << " " << sum - i << endl;
break;
}
else
{
cout << "a should be <= b";
break;
}
}
}
}
return 0;
}

How can this work?
You create an empty vector of char, push one single value into it and that try to assign value passed the first:
...
vector<char> can;
can.push_back(1); // can contains one single value
for (i = 1; i <= sum; i++)
can[i] = 0; // Error "vector subscript out of range" in debug mode
If you do not ask the control of vector subscript you will just invoke undefined behaviour.
But if you just want to expand the vector, you can repeatedly can push_back:
for (i = 1; i <= sum; i++)
can.push_back(0);

Related

minimizing memory use in c++

I was working on a problem in codeforces and I have no problems in the functionality of the code but the code exceeds the memory usage. Can someone explain how to improve this? How to learn about memory management in general while programming because I didn't find anything related to that. Here's my code :
Summary of the problem: You are given 6 input numbers, the first 5 numbers should be multiplied each by another integer and the summation of them after multiplication is the sixth integer in the input. You should find all the combinations of the numbers the can be multiplied by each value in the input to seek the summation. the output is basically the sum of the integers chosen for each number in the input to be multiplied by.
#include <iostream>
#include <vector>
#ifndef MAX
#define MAX 100
#endif
using namespace std;
void storeAndFilter(vector <int> &arr,int chosenNumConst, int mypasha);
void print(vector<int> &v);
int printsum(vector<int> &v);
int main(int argc, char const *argv[])
{
//array of input options
int a1, a2, a3, a4, a5, pasha;
cin >> a1 >> a2 >> a3 >> a4 >> a5 >> pasha;
//declarations of vectors
vector<int> arrStrA1;
vector<int> arrStrA2;
vector<int> arrStrA3;
vector<int> arrStrA4;
vector<int> arrStrA5;
//sorting and filtering the vectors
storeAndFilter(arrStrA1,a1,pasha);
storeAndFilter(arrStrA2,a2,pasha);
storeAndFilter(arrStrA3,a3,pasha);
storeAndFilter(arrStrA4,a4,pasha);
storeAndFilter(arrStrA5,a5,pasha);
//cout<<"All Posibilities valid (Minimized by removing values < pasha) : "<<endl;
// print (arrStrA1);
// print (arrStrA2);
// print (arrStrA3);
// print (arrStrA4);
// print (arrStrA5);
//scores vectors
vector<int> resultsA1;
vector<int> resultsA2;
vector<int> resultsA3;
vector<int> resultsA4;
vector<int> resultsA5;
int i,j,k,l,m;
for (i=0; i < (int)arrStrA1.size(); ++i)
{
for (j=0; j < (int)arrStrA2.size(); ++j)
{
for (k=0; k < (int)arrStrA3.size(); ++k)
{
for (l=0; l < (int)arrStrA4.size(); ++l)
{
for (m=0; m < (int)arrStrA5.size(); ++m)
{
if(arrStrA1.at(i)+arrStrA2.at(j)+arrStrA3.at(k)+arrStrA4.at(l)+arrStrA5.at(m)==pasha)
{
resultsA1.push_back(arrStrA1.at(i));
resultsA2.push_back(arrStrA2.at(j));
resultsA3.push_back(arrStrA3.at(k));
resultsA4.push_back(arrStrA4.at(l));
resultsA5.push_back(arrStrA5.at(m));
}
}
}
}
}
}
//divise each term by the card value
for (int i = 0; i < (int)resultsA1.size(); ++i)
{
if (a1==0)
resultsA1.at(i) /= 1;
else
resultsA1.at(i) /= a1;
}
for (int i = 0; i < (int)resultsA2.size(); ++i)
{
if (a2==0)
resultsA2.at(i) /= 1;
else
resultsA2.at(i) /= a2;
}
for (int i = 0; i < (int)resultsA3.size(); ++i)
{
if(a3==0)
resultsA3.at(i) /= 1;
else
resultsA3.at(i) /= a3;
}
for (int i = 0; i < (int)resultsA4.size(); ++i)
{
if (a4==0)
resultsA4.at(i) /= 1;
else
resultsA4.at(i) /= a4;
}
for (int i = 0; i < (int)resultsA5.size(); ++i)
{
if(a5==0)
resultsA5.at(i) /= 1;
else
resultsA5.at(i) /= a5;
}
//Uncomment to show the table list after division
// print(resultsA1);
// print(resultsA2);
// print(resultsA3);
// print(resultsA4);
// print(resultsA5);
int scra1=printsum(resultsA1);
int scra2=printsum(resultsA2);
int scra3=printsum(resultsA3);
int scra4=printsum(resultsA4);
int scra5=printsum(resultsA5);
cout << scra1 <<" "<< scra2 <<" "<< scra3 <<" "<<scra4 <<" "<< scra5 <<endl;
return 0;
}
void print(vector<int> &v)
{
int size = v.size();
cout<<"========================"<<endl;
for (int i = 0; i < size; ++i)
cout<<v.at(i)<<endl;
cout<<"========================"<<endl;
}
int printsum(vector<int> &v)
{
int sum =0;
for (int i = 0; i < (int)v.size(); ++i)
sum += v.at(i);
return sum;
}
void storeAndFilter(vector <int> &arr,int chosenNumConst, int mypasha)
{
arr.reserve(10);
int i=0;
for (; i <= MAX; ++i)
{
arr.push_back(i*chosenNumConst);
if (arr.at(i)>mypasha)
break;
}
arr.resize(i);
}
Some stuff that I thought about:
Arrays instead of Vectors maybe better
The nested for loops may be the one that is taking too much memory
But to be clear, the nested for loops doesn't make too much calculations, they find all the combinations of 5 numbers '5 loops' to sum to a specific value. Filtering before entering the loop is applied so maybe the nested loop isn't the issue.
Max memory constrain in the problem is: 256 MB
You can use much less memory by not using all those vectors. You can just write your code like this:
// make sure we handle zero properly
auto end = [&](int num){
return num == 0 ? num : pasha/num;
};
for (auto i=0, end_i = end(a1); i <= end_i; ++i)
{
for (auto j=0, end_j = end(a2); j <= end_j; ++j)
{
for (auto k=0, end_k = end(a3); k <= end_k; ++k)
{
for (auto l=0, end_l = end(a4); l <= end_l; ++l)
{
for (auto m=0, end_m = end(a5); m <= end_m; ++m)
{
if(a1*i+a2*j+a3*k+a4*l+a5*m==pasha)
{
std::cout << i << " " << j << " " << k << " " << l << " " << m << "\n";
}
}
}
}
}
}
and it outputs all the valid results. For Example for the input 0 2 3 4 5 6 it produces
0 0 2 0 0
0 1 0 1 0
0 3 0 0 0
See working example here

display wheter or not an array entered by the user is unique or not

I am new to C++ I am making an array based off of user input and displaying whether the array is unique or not. my initial thought is I have to end up creating another array to store values and then compare the elements. My code compiles without errors but does not do what I want it to do. I can't used advanced methods such as hashmaps or vectors. Any help or insight is greatly appreciated!
#include <iostream>
#include <string>
using namespace std;
int main()
{
int myArray[6];
string name;
int i, k;
int ov = 0;
int newVal = 0;
for (int index = 0; index < 6; index++)
{
cout << "Enter number a number: ";
cin >> myArray[index];
}//end loop for
for (i = 0; i < 6; i++)
{
ov = myArray[i];
}
for (k = i + 1; k < 6; k++)
{
if (ov == myArray[k])
{
newVal = 1;
}
}
if (newVal == 1)
{
cout << "Not all unique";
}
else
{
cout << "All unique";
}
cin.get();
return 0;
}

C++ Vector Subscript Issues

I was making an app that calculates the mean, median, and range of any integers, but I ran into the issue: Vector subscript out of range. I've looked at some other posts about this, and still haven't been able to fix it.
Here's my code:
#include <iostream>
#include <Algorithm>
#include <Windows.h>
#include <vector>
using namespace std;
int main() {
//Variables
int sze;
int mraw = 0;
double mean;
double median;
double range;
int fullnum = 0;
int lastnum = 1;
vector<int> med;
cout << "How many numbers do you have? ";
cin >> sze;
int *arr = new int[sze];
for (int i = 0; i < sze; i++) {
med.push_back(arr[i]);
}
//Getting numbers
for (int i = 0; i < sze, i++;) {
system("cls");
cout << "Enter number #" << i + 1 << ": ";
cin >> arr[i];
}
//Mean
for (int i = 0; i < sze; i++){
fullnum += arr[i];
}
mean = fullnum / sze;
//Median
sort(med.begin(), med.end());
int mvs = sze;
while (med.size() >= 2) {
med.erase(med.begin());
med.erase(med.begin() + med.size() - 1);
mvs--;
}
if (mvs == 2) {
mraw = med[1] + med[2];
median = mraw / 2;
}
else {
median = mvs;
}
//Range
vector<int> rnge;
for (int i = 0; i < sze; i++) {
rnge.push_back(arr[i]);
lastnum++;
}
sort(rnge.begin(), rnge.end());
int bigsmall[2];
bigsmall[1] = rnge[1];
bigsmall[2] = rnge[lastnum];
range = bigsmall[2] - bigsmall[1];
//Outputs
cout << "Mean: " << mean << "\nMedian: " << median << "\nRange: " << range;
system("cls");
return 0;
}
You have what would be an off-by-one error if lastnum was initialized to 0.
When rnge is empty, presumably lastnum is 0. This means access rnge[lastnum] is in error, as rnge is empty.
Applying an inductive argument shows that lastnum is the count of number of elements, and not the index of the last element. Thus, rnge[lastnum] is always out of range.
In actuality, you have initialized lastnum to 1, so your bug is actually off-by-two.

Max Sum Of Integers

EDIT: solved! I was treating negative numbers test case as 0, instead of having the output be negative as well. thanks for the help!
Here is the challenge description: https://www.codeeval.com/open_challenges/17/
I keep getting a partially solved score. I want to know why. As in my eyes, this code works. And I believe that it is O(N) time. Thanks for looking!
Here is my code:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
int max(int a, int b)
{
if (a > b)
return a;
else return b;
}
int maxSubArray(vector<int> values)
{
int max_so_far = values[0];
int curr_max = values[0];
for(int i = 1; i < values.size(); ++i)
{
curr_max = max(values[i], curr_max + values[i]);
max_so_far = max(max_so_far, curr_max);
}
return max_so_far;
}
int main(int argc, char *argv[])
{
std::vector<vector<int> > Values; //to hold the values of the stock price change
ifstream file(argv[1]);
std::string line; //for the txt file input
int value = 0; //for holding the value of stock change
while (std::getline(file, line))
{
int pos = 0;
if(line.length() == 0)
continue;
else
{
std::istringstream iss(line);
std::vector<int> list; // temporary list of values to be pushed back into the 2-d vector
while (iss >> value)
{
list.push_back(value);
}
Values.push_back(list);
}
}
for(int i = 0; i < Values.size(); ++i)
{
cout << maxSubArray(Values[i]);
cout << endl;
}
/*
cout << " Printing the values : " << endl;
for (int j = 0; j < Values.size(); ++j)
{
for (int k = 0; k < Values[j].size(); ++k)
cout << Values[j][k] << " ";
cout << endl;
}
*/
return 0;
}
so I swapped out some code now. I get better score but I it's still a partial.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
int max(int a, int b)
{
if (a > b)
return a;
else return b;
}
int maxSubArray(vector<int> values)
{
int max_so_far = values[0];
int curr_max = values[0];
if (curr_max < 0)
{
curr_max = 0;
max_so_far = 0;
}
for(int i = 1; i < values.size(); ++i)
{
curr_max = max(values[i], curr_max + values[i]);
curr_max = max(curr_max, 0);
max_so_far = max(max_so_far, curr_max);
}
return max_so_far;
}
int main(int argc, char *argv[])
{
std::vector<vector<int> > Values; //to hold the values of the stock price change
ifstream file(argv[1]);
std::string line; //for the txt file input
std::string token; //for the subtring that will be converted from char to int
int value = 0; //for holding the value of stock change
int count = 0;// for holding how many total cases
while (!file.eof())
{
int pos = 0;
getline(file, line);
if(line.length() == 0)
continue;
else
{
std::vector<int> list; // temporary list of values to be pushed back into the 2-d vector
while ((pos = line.find(",")) != std::string::npos )
{
token = line.substr(0,pos);
value = atoi(token.c_str());
line.erase(0, pos + 1);
list.push_back(value);
}
value = atoi(line.c_str());
list.push_back(value);
Values.push_back(list);
++count;
}
}
for(int i = 0; i < Values.size(); ++i)
{
cout << maxSubArray(Values[i]);
cout << endl;
}
cout << " Printing the values : " << endl;
for (int j = 0; j < Values.size(); ++j)
{
for (int k = 0; k < Values[j].size(); ++k)
cout << Values[j][k] << " ";
cout << endl;
}
return 0;
}
Why are you passing the vector by value here?
int maxSubArray(vector<int> values)
That looks like a significant optimization opportunity.
I think you don't read the problem exactly right. When they say 'all contiguous sub ararys', they mean you have to take the max over all i andj of for(idx = i; i < j; ++i) { total += vec[idx]; }. Right now your code basically assumes i = 0 which isn't what you are supposed to do.
Just from looking at the output examples they provide, I can see that your code isn't going to give the answer that they expect.
it seems right, the only thing I can think of is that when the list gets long, your result can overflow, so change int to long long.
Besides technical optimizations suggested in other answers, concerning the algorithm, i think a little fix can make your algorithm work. When curr_max drops to a negative value, due to encountering a negative integer that exceeds curr_max, you can simply drop all the previous integers including the current value and start over. This fix is simple, you can add one line to your loop like this:
for(int i = 1; i < values.size(); ++i)
{
curr_max = max(values[i], curr_max + values[i]);
curr_max = max(curr_max, 0); // <---------------- add this line
max_so_far = max(max_so_far, curr_max);
}

C++ insertion sort

I have this function called WordSort(worddata W [], int count) that is fed two variables
1 - worddata is the array holding information on a given word in a file. count is just the counter variable to see which word in the array we are looking at.
the words.txt file that is read into this program would just be a string of words.
this is a list of words
there are letters and numbers
23 people recommend this program.
Heres the function:
void WordSort (worddata W [], int count)
{
for (int i=1; i < count; i++)
{
for (int j=i; j > 0 && W[j-1].word > W[j].word; j--)
{
Swap(W[j], W[j-1]);
}
}
}
The swap function is suppose to swap every element with the one before it as long as j > 0 or the list is over. Im confused on how to complete the swap function, here's the example i was given.
void Swap (worddata & a, worddata & b)
{
int += a;
a = b;
b =+;
}
Swap is suppose to swap every element with the one before it
I think the WordSort function works fine, the only thing missing is the Swap function. Could anyone point me in the right direction or explain insertion sorting better to me?
void insertion_sort()
{
/* Algorithm : Insertion Sort
* Coded by .
*/
int num;
/*
* Asking the User no of Integers he/she wants to enter
*/
cout << "Enter no of integers u want to enter: ";
cin >> num;
/* Creating an Array to store the integers*/
int s[num];
/*Taking Integers from the User */
for(int i = 0 ; i < num ; i++)
{
cout << "Integer " << i+1 << " is : ";
int x;
cin >> x;
s[i] = x;
}
/* The Magic of INSERTION SORT */
for(int j = 1 ; j <= (num-1) ; j++)
{
int key = s[j];
int k = j-1;
while(k >=0 && key <= s[k])
{
s[k+1] = s[k];
k = k - 1;
}
s[k+1]=key;
}
/*Printing Out the Sorted List */
cout << "The Sorted List is \n\n";
for(int i = 0 ; i < num ; i++)
{
cout << s[i] << " ";
}
}
Use standard library std::swap instead. In your loop:
for (...)
{
std:swap(W[j], W[j-1]);
}
std::swap requires worddata class to have a copy constructor and an assignment operator defined explicitly or implicitly.
Swap should look like this -- I have no idea how your example is even close.
void Swap (worddata & a, worddata & b)
{
worddata temp = a;
a = b;
b = temp;
}
Insertion sort using "for loop" (2 iterations)
#include<iostream>
using namespace std;
int insertion(int arr[], int size_arr)
{
int i,j,n, temp;
for(i=1;i<size_arr; i++){
j=i-1;
temp = arr[i];
for (j; j >= 0; j--)
{
if(arr[j] > temp){
arr[j+1] = arr[j];
arr[j] = temp;
}
}
arr[j] = temp;
}
for(i=0;i<size_arr;i++){
cout<<arr[i]<<endl;
}
return 0;
}
int main(){
int arr[] = {3,38,1,44,66,23,105,90,4,6};
int size_arr = sizeof(arr) / sizeof(arr[0]);
insertion(arr,size_arr);
return 0;
}