C++ Cutting Rod Dynamic programming - c++

I am new to dynamic programming and trying to solve an evergreen problem: cutting rod. I have been trying for hours and I am stuck. I am trying to debug it but without success.
Here is my code
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int length = 5;
int peaces[2][4] = {{1, 2, 3, 4}, {2, 5, 7, 8}};
/*
length 1, 2, 3, 4
value: 2, 5, 7, 8
*/
//create working matrix: number of lengths X lengths
int work[4][6];
//fill in the first column with zeros
for( int k = 0; k < 5; k++ )
{
work[k][0] = 0;
}
//fill in the first row with zeroes
for( int k = 0; k <= length; k++ )
{
work[0][k] = 0;
}
for( int i = 1; i < 5; i++ ) // number of lengths
{
cout << endl << " i: " << i << " " << endl;
for( int j = 1; j < 6; j++ )
{
cout << endl << " j: " << j << " " << endl;
if( j >= i )
{
work[i][j] = max( work[i - 1][j], work[i][j - i] + peaces[1][i-1] );
}
else
{
work[i][j] = work[i - 1][j];
}
cout << endl;<< "inserted:" << work[i][j]<< endl;
for( int i = 0; i < 5; i++ )
{
for( int j = 0; j < 6; j++ )
{
cout << work[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
}
for( int i = 0; i < 5; i++ )
{
for( int j = 0; j < 6; j++ )
{
cout << work[i][j] << " ";
}
cout << endl;
}
return 0;
};
Something very strange happens and I can't figure out why: in the last iteration of the for loop I get right solution, but when exit the loop and I print the 2D array, it is changed, not the same as the one in the last iteration. Between two printing no operation is done on the array.
I know that this is not an optimized solution, but that is the first one I have come up with.
Question: Why is not the array filled the right way? What have I done wrong?

The best way to avoid issues like this is to define variables for the dimensions in the first place. For example,
int xlen = 4;
int ylen = 5;
int work[xlen][ylen];
Then, you can use xlen and ylen in your loops and if you want to change the size of the arrays, you just change the xlen and ylen.
Alternatively, you can find the size using answers that you find here: How do I find the length of an array?
And finally, you should read up on the standard template library, which gives you "smarter" objects you can use.

Related

Array Sum with Pointers i have a problem in the sum

I have this code. and I have a problem with it. When I run it for these numbers "1,1,1,1,1" it answers me right but when I use these numbers "2,1,3,2,2" or any other numbers it answers me wrong. What is the problem?
#include <iostream>
using namespace std;
int main() {
int size = 5;
int array1[size];
int i, j, *p;
int sum = 0;
p = &array1[j];
for (int i = 0; i < size; i++) {
cout << "give next number";
cin >> array1[i];
cout << "\n";
}
cout << "the array is:"
<< "\n";
for (int j = 0; j < size; j++) {
cout << array1[j] << "\n";
sum = sum + *p;
}
cout << "the sum of array elements is: " << sum;
return 0;
}
So you have one problem
p = &array1[j];
What you are doing is taking the address of jth element of an array. In you case j is uninitialized which leads to UB since j might contain any variable.
To fix this you can initialize j to 0 (j = 0). Or to just get an address of first element in array you can do following:
p = array;
Than comes your loop, which is summit value at address of arr[j] which is UB as I stated above.
cout << "the array is:" << "\n";
for (j = 0; j < size; j++) {
cout << array1[j] << "\n";
sum = sum + *(p + j);
}
Your problem here was that you were adding array1[0] all the time. (That is if you initialized j to 0).
Other things to note is that you are re declaring i and j
int i, j, *p;
...
for (int i = 0; ...)
...
for (int j = 0; ...)
You could do just
for (i = 0; ...)
...
for (j = 0; ...)
to set already declared variables to 0.
Here is entire program:
#include <iostream>
int main() {
int size = 5;
int array1[size];
int i, j, *p;
int sum = 0;
// p = &array1[j]; // UB j not initialized but used
/* solution 1
j = 0;
p = &array1[j]
*/
// solution 2 which is same as solution 1
p = array1; // gets address of array[0]
for (i = 0; i < size; i++) { // no need for `int` in front of i
// i is already declared above
// my preference is to declare i here
// and remove declaration above
std::cout << "give next number";
std::cin >> array1[i];
std::cout << "\n";
}
std::cout << "the array is:"
<< "\n";
for (j = 0; j < size; j++) { // same as above
std::cout << array1[j] << "\n";
sum = sum + *(p + j);
}
std::cout << "the sum of array elements is: " << sum;
return 0;
}
input:
give next number5
give next number4
give next number3
give next number2
give next number1
output
the array is:
5
4
3
2
1
the sum of array elements is: 15

Sliding Maximum window brute force method

Given a large array of integers and a window of size 'w', find the current maximum in the window as the window slides through the entire array.
I have made two for loops, the first loops is working correctly but the inner loop doesn't move correctly based on different window sizes.
I tried to draw it on paper, but I still can't get a formula for the inner loop
int main() {
vector<int> arr = { -4, 2, -5, 3, 6 };
int window = 3;
for (int i = 0; i < arr.size() - window; i++)
{
int max = arr[i];
for (int j = i + 1; j < i + window; j++)
{
cout << " i = "<<i << "j = " << j << endl;
if (max < arr[j])
max = arr[j];
}
cout << max << " " << endl;
}
Your inner loop is correct. It's your outer loop's that's off by 1, it should be:
for (int i = 0; i <= arr.size() - window; i++)
With your array of 5 elements and the window size of 3, the last window is array[2] through array[4]. arr.size() is 5. window is 3. 5-3=2, and you need to still iterate for that window starting position.
Try this:
#include <algorithm>
int main() {
std::vector<int> arr = { -4, 2, -5, 3, 6 };
int window = 3;
for (std::size_t i = 0; i < arr.size() - window + 1; i++)
// one of your bugs is here --------------------^
{
int max = 0;
// this way, it's easier to see how the window slides
for (std::size_t j = 0; j < window; j++)
{
std:: cout << " i = "<<i << "j = " << j+i << std::endl;
max=std::max(arr[i+j],max);
// --------------^
// i becomes the window's offset
// j is the offset inside the window
// using std::max eliminates a i+j twice with an if
// ... (and will be inlined anyway)
}
std::cout << max << " " << std::endl;
}
return 0;
}

Using Multidimensional Arrays to Keep Track of Indices in C++

I'm working on a project where I need to sort an array from least to greatest, but save the values of the indices. For example, with the array {2, 7, 8, 1, 3}, the sorted indices would be {3, 0, 4, 1, 2}. I thought that I could use a two dimensional array to accomplish this; I would add the index to each component, sort the array, then retrieve the original index from the second element. It hasn't been working for me as well as I hoped though, I have my current code below and it keeps giving me a segmentation fault. I don't know what I'm doing wrong, but I'm assuming its something in my for loops.
#include <iostream>
#include <algorithm>
using namespace std;
const int SIZE = 7;
int main()
{
int intArray[SIZE] = {5, 3, 32, -1, 1, 104, 53};
int i, j, k, l = 0;
int temp[SIZE][2];
//fills multidimensional array temp with data from intArray or index #
for(i = 0; i < 7; i++){
for(j = 0; j < 2; j++){
switch (j)
{
case '0':
temp[i][j] = *intArray;
break;
case '1':
temp[i][j] = i;
break;
}
}
}
sort(intArray, intArray + SIZE);
//prints each component of temp individually
cout << "Sorted Array looks like this." << endl;
for (k = 0; i < 7; i++){
for (l = 0; j < 2; i++){
cout << &temp[k][l] << endl;
}
}
return 0;
}
The following loop is much simpler and does what it should:
for(i = 0; i < 7; i++){
temp[i][0] = intArray[i];
temp[i][1] = i;
}
One error in your code is the line
temp[i][j] = *intArray;
This always assigns the 1st element of intArray.
The thing that causes the segmentation fault is probably the & in the output statement, just remove it.
Aside from that, I agree with the recommendation in the comment by RyanP.
Use std::map. The code will be the easiest. Test on cpp.sh
#include <iostream>
#include <map>
int main()
{
std::map<int,int>arr = {{5,0}, {3,1}, {32,2}, {-1,3}, {1,4}, {104,5}, {53,6}};
for(auto&x:arr) std::cout << x.first << " - > " << x.second << std::endl;
return 0;
}
I ended up using what Frank Puffer said and chose to use a simple bubble sort instead of using any of the built in functions. Here is a link to what my final program looked like http://ideone.com/cpEgGA
#include <iostream>
#include <algorithm>
using namespace std;
const int SIZE = 7;
int main()
{
int intArray[SIZE] = {5, 3, 32, -1, 1, 104, 53};
int i, j, k, l, m = 0;
int temp2[SIZE][2];
int indices[SIZE] = {};
for(i = 0; i < 7; i++){
temp2[i][0] = intArray[i];
temp2[i][1] = i;
}
cout << "Unsorted Array looks like this." << endl;
for (j = 0; j < 7; j++){
cout << temp2[j][0];
cout << " : ";
cout << temp2[j][1] << endl;
}
for(k = 0; k < SIZE; k++)
{
for(j = 0; j < SIZE-1-k; j++)
{
if(temp2[j+1][0] < temp2[j][0])
{
l = temp2[j][0];
temp2[j][0] = temp2[j+1][0];
temp2[j+1][0] = l;
l = temp2[j][1];
temp2[j][1] = temp2[j+1][1];
temp2[j+1][1] = l;
}
}
}
cout << "Sorted Array looks like this." << endl;
for (m = 0; m < SIZE; m++)
{
cout << temp2[m][0];
cout << " : ";
cout << temp2[m][1] << endl;
}
for(i = 0; i < SIZE; i++){
indices[i] = temp2[i][1];
}
cout << "Indices of Sorted Array look like this." << endl;
for(i = 0; i < SIZE; i++){
cout << indices[i] << endl;
}
return 0;
}

How do I output a 2D char array using nested for loops?

I am trying to output a simple 2D char array using nested for loops
It does not output in a "Square form", and also it is crashing.
#include <iostream>
using namespace std;
int main(){
char array[x][y] = {
"000000",
"0 0",
"0 0",
"000000",
};
for (int i = 1; i <=x; i++) {
for (int j = 1; j <=y; j++)
cout << array[i][j];
}
}
C++ uses Zero-based indexing
your loops should be like
for (int i = 0; i <x; i++)
https://en.wikipedia.org/wiki/Zero-based_numbering
That's why it's crashing
Also you don't print line breaks. Insert cout << std::endl in the outer loop
The arrays are zero based, so you should loop from 0 to x-1 rather than from 1 to x.
You also need a line break, otherwise it will all be written on the same line.
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; i++) {
cout << array[i][j];
}
cout << std::endl;
}
I suppose that x and y are constants defined like
const size_t x = 4;
const size_t y = 7;
C++ does not allow to use non-constant expressions as array sizes though some compilers have their own language extensions that allow to use variable length arrays.
In this case this array
char array[x][y] = {
"000000",
"0 0",
"0 0",
"000000",
};
can be outputed the following way
for ( auto &s : array ) std::cout << s << std::endl;
Take into account that indices of arrays in C++ start from 0. So if to use indices then the loop can look like
for ( size_t i = 0; i < x; i++ ) std::cout << array[i] << std::endl;
Take into account that to output this shape there is no need to declare a 2D array.:)
Here is a demonstrative program
#include <iostream>
#include <iomanip>
int main()
{
size_t n = 4;
size_t m = 6;
char c = '*';
for ( size_t i = 0; i < n; i++ )
{
std::cout << c
<< std::setfill( i % ( n - 1 ) == 0 ? c : ' ' )
<< std::setw( m - 1 )
<< c << std::endl;
}
}
Its output is what you expect:)
******
* *
* *
******
and can someone explain me why the second method outputs the array on other location ? i mean it starts to output on 2nd line while 1st method outputs from 00coord (by coord its mean location in console ,, not array position)
for (int i = 0; i < x; i++)
cout << array[i] << endl;
for (int i = 0; i <x; i++) {
cout << endl;
for (int j = 0; j <y; j++)
cout << map[i][j];
}

Checking duplicated numbers in Array

The function should check if there is any duplicated number but it's not working somehow.
anyone knows why?
#include <iostream>
using namespace std;
int main()
{
int const size = 10;
int arry[size] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 ,10};
int i = 0;
int k = 1;
for (i = 0; i < size; i++)
{
for (k = 1; k < size; k++)
{
if (arry[i] == arry[k])
{
cout << arry[i] << " " << arry[k] << endl;
cout << "duplicate" << endl;
return 0;
}
}
}
cout << "no duplicate" << endl;
return 0;
}
You should skip when i == k.
for (i = 0; i < size; i++)
{
for (k = i+1; k < size; k++) // <-- either change HERE
{
if (i != k && arry[i] == arry[k])
// ^^^^^^ or HERE
{
cout << arry[i] << " " << arry[k] << endl;
cout << "duplicate" << endl;
return 0;
}
}
}
You're checking every combination twice - for example, you're comparing element 2 with element 5, and then 5 with 2. Aside from the fact that you're also checking an element with itself (which is what timrau's answer is guarding against), you're doing the same work twice.
So try
for (i = 0; i < size; i++)
{
for (k = i + 1; k < size; k++)
instead.
Your approach still doesn't scale very well, it's essentially O(n^2). It would be faster to sort your array and then look for duplicate neighbors.
A more efficient approach should be to sort the array first:
std::vector<int> a = {4, 3, 2, 1, 2, 5, 6};
std::sort(std::begin(a), std::end(a));
for (std::size_t i = 1; i < a.size(); ++i) {
if (a[i - 1] == a[i]) {
std::cout << a[i] << " " << a[i] << std::endl;
std::cout << "duplicate" << std::endl;
return 0;
}
}
return 0;