What is causing undefined behaviour in my use of realloc - c

I'm trying to write a function that takes in position data, an array and a counter that stores number of elements in that array and populates that array with new position data and increments the counter. And since I need this array outside of the function, I'm dynamically allocating memory using realloc.
Code
I have a struct to store co-ordinate data
typedef struct CoOrdinates
{
int x;
int y;
} CoOrdinates;
and a function that draws a box at any given position
void drawBox(WINDOW* inWindow,
int aAtPositionX,
int aAtPositionY,
int* aOccupiedCoordinateCount,
CoOrdinates** aOccupiedCoordinates)
{
int newCount = (*aOccupiedCoordinateCount) + 1;
size_t sizeResized = sizeof(**aOccupiedCoordinates) * newCount;
*aOccupiedCoordinates = realloc(*aOccupiedCoordinates, sizeResized);
if (*aOccupiedCoordinates == NULL)
{
fprintf(stderr, "Failed to allocate CoOrdinate array at %d in %s.", __LINE__, __FILE__);
exit(-1);
}
else
{
(*aOccupiedCoordinates)[newCount].x = aAtPositionX;
(*aOccupiedCoordinates)[newCount].y = aAtPositionY;
*aOccupiedCoordinateCount = newCount;
mvwprintw(inWindow, aAtPositionY, aAtPositionX, "██");
}
}
where mvwprintw and WINDOW* are defined in ncurses.
Another function is drawTwoVerticleBoxes defined like this
void drawTwoVerticleBoxes(WINDOW* inWindow,
int aAtPositionX,
int aAtPositionY,
int* aOccupiedCoordinateCount,
CoOrdinates** aOccupiedCoordinates)
{
drawBox(inWindow, aAtPositionX, aAtPositionY, aOccupiedCoordinateCount, aOccupiedCoordinates);
drawBox(inWindow, aAtPositionX, aAtPositionY + 1, aOccupiedCoordinateCount, aOccupiedCoordinates);
}
and a function called drawWithColor
void drawWithColor(WINDOW* inWindow,
int aAtPositionX,
int aAtPositionY,
int* aOccupiedCoordinateCount,
CoOrdinates** aOccupiedCoordinates)
{
init_pair(1, COLOR_GREEN, COLOR_BLACK);
wattron(inWindow, COLOR_PAIR(1));
drawTwoVerticleBoxes(
inWindow, aAtPositionX, aAtPositionY, aOccupiedCoordinateCount, aOccupiedCoordinates);
wattroff(inWindow, COLOR_PAIR(1));
Finally all of those are called in renderRoutine
void renderRoutine()
{
...
...
int occupiedCoordinateCount = 0;
CoOrdinates* occupiedCoordinates = NULL;
drawWithColor(windowPointer, 4, 4, &occupiedCoordinateCount, &occupiedCoordinates);
wgetch(windowPointer);
endwin();
for (int i = 0; i < occupiedCoordinateCount; ++i)
{
printf("X: %d, Y: %d \n", occupiedCoordinates[i].x, occupiedCoordinates[i].y);
free(occupiedCoordinates);
}
}
Summery
The idea is, every time a box is drawn, occupiedCoordinates will store CoOrdinate of that position. occupiedCoordinateCount will store how many items occupiedCoordinates have.
Errors
Expected results
X: 4, Y: 4
X: 4, Y: 5
Actual results
X: 0, Y: 0
X: 504864784, Y: 22033
free(): double free detected in tcache 2
Tweaks
If I define a function say drawFiveHorizontalBoxes
void drawThreeHorizontalBoxes(WINDOW* inWindow,
int aAtPositionX,
int aAtPositionY,
int* aOccupiedCoordinateCount,
CoOrdinates** aOccupiedCoordinates)
{
drawBox(inWindow, aAtPositionX, aAtPositionY, aOccupiedCoordinateCount, aOccupiedCoordinates);
drawBox(inWindow, aAtPositionX + 1, aAtPositionY, aOccupiedCoordinateCount, aOccupiedCoordinates);
drawBox(inWindow, aAtPositionX + 2, aAtPositionY, aOccupiedCoordinateCount, aOccupiedCoordinates);
drawBox(inWindow, aAtPositionX + 3, aAtPositionY, aOccupiedCoordinateCount, aOccupiedCoordinates);
drawBox(inWindow, aAtPositionX + 4, aAtPositionY, aOccupiedCoordinateCount, aOccupiedCoordinates);
}
Expected results
X: 4, Y: 4
X: 5, Y: 4
X: 6, Y: 4
X: 7, Y: 4
X: 8, Y: 4
Actual results
realloc(): Invalid next size
core dumped
Edit
(*aOccupiedCoordinates)[*aOccupiedCoordinateCount].x = aAtPositionX;
(*aOccupiedCoordinates)[*aOccupiedCoordinateCount].y = aAtPositionY;
or
(*aOccupiedCoordinates)[newCount - 1].x = aAtPositionX;
(*aOccupiedCoordinates)[newCount - 1].y = aAtPositionY;
shows
X: 4, Y: 4
X: -1300275184, Y: 21961
free(): double free detected in tcache 2
in drawThreeHorizontalBoxes.

One problem is this:
(*aOccupiedCoordinates)[newCount].x = aAtPositionX;
(*aOccupiedCoordinates)[newCount].y = aAtPositionY;
Here newCount is the size of the "array", which will be one out of bounds of the allocated memory.
Use the old counter *aOccupiedCoordinateCount instead (or subtract one from newCount in the index).
A second problem is that you free the memory inside the loop where you print the values:
for (int i = 0; i < occupiedCoordinateCount; ++i)
{
printf("X: %d, Y: %d \n", occupiedCoordinates[i].x, occupiedCoordinates[i].y);
free(occupiedCoordinates);
}
The first iteration will free the memory, so each other iteration will use memory that isn't owned by you anymore, and try to free it again.
The free call should be outside of the loop.

Related

Algorithm not functioning for sort squared array based off of input

I'm working on building an algorithm that sorts in place for an array of nondecreasing integers, and it's not passing some of my tests. I was wondering why? I've included a sample input and output as well.
import java.util.*;
class Program {
public int[] sortedSquaredArray(int[] array) {
int[] res = new int[array.length];
int leftPointer = 0;
int rightPointer = array.length - 1;
int counter = 0;
while (counter < array.length) {
int leftSquared = array[leftPointer] * array[leftPointer];
int rightSquared = array[rightPointer] * array[rightPointer];
if (leftSquared < rightSquared) {
res[counter] = leftSquared;
leftPointer++;
} else if (rightSquared <= leftSquared) {
res[counter] = rightSquared;
rightPointer--;
}
counter++;
}
return res;
}
}
"array": [-50, -13, -2, -1, 0, 0, 1, 1, 2, 3, 19, 20]
expected output:
[0, 0, 1, 1, 1, 4, 4, 9, 169, 361, 400, 2500]
what I'm getting:
[400, 361, 9, 4, 1, 1, 0, 0, 1, 4, 169, 2500]
If the array was specified to be in increasing order, your attempt was very close:
Just fill the result from larger squares to lower.
(If the array starts with a non-negative value, just return (a copy of) the input array.)
Just as #greybeard wrote: your mistake is to fill from the lower end, but you do not know the lowest square yet, since you are checking the two numbers with the BIGGEST square value.
This function should do what you want:
public int[] sortedSquaredArray(int[] array)
{
if (array.length == 0 || array[0] >= 0)
return array;
int[] res = new int[array.length];
int leftPointer = 0;
int leftSquared = array[leftPointer] * array[leftPointer];
int rightPointer = array.length - 1;
int rightSquared = array[rightPointer] * array[rightPointer];
int counter = rightPointer;
while (counter >= 0)
{
if (leftSquared >= rightSquared)
{
res[counter] = leftSquared;
leftPointer++;
leftSquared = array[leftPointer] * array[leftPointer];
}
else
{
res[counter] = rightSquared;
rightPointer--;
rightSquared = array[rightPointer] * array[rightPointer];
}
counter--;
}
return res;
}
Note the optimisations in line 3 and 4 and calculating the squared values only when needed. Also this function is NOT doing in-place sorting! It is returning a new array with the sorted squares. Doing an in-place sorting could be accomplished by re-assigning the values from the sorted array to the passed-in array before returning or using the passed-in array directly but having to move around the array-values a lot, if the left pointer is pointing to the bigger value.
You can watch the code in action with your example data here.

Dot Product and Cross Product in C using structures

I have to create a struct vector3d that includes x,y, and z
Then I have to create two variables of the type struct vector 3d and store two vectors in them
Next, I have to write a function that calculates the dot and cross product of these two vectors. Which return type is necessary?
That's what I have until now. Maybe someone could help me.
#include <stdio.h>
#include <stdlib.h>
int n = 3;
struct vector3d
{
int x, y, z;
};
int dot_product (int v1[], int v2[], int n)
{
int dproduct = 0;
n = 3;
for(int i = 0; i < n; i++)
dproduct += v1[i] * v2[i];
return dproduct;
}
void cross_product (int v1[], int v2[], int crossproduct[])
{
crossproduct[0] = v1[1] * v2[2] - v1[2] * v2[1];
crossproduct[1] = v1[0] * v2[2] - v1[2] * v2[0];
crossproduct[2] = v1[0] * v2[1] - v1[1] * v2[0];
}
int main()
{
struct vector3d v1 = {0,0,0};
struct vector3d v2 = {0,0,0};
printf("Vector 1 - Enter value for x: ");
scanf("%d", &v1.x);
printf("Vector 1 - Enter value for y: ");
scanf("%d", &v1.y);
printf("Vector 1 - Enter value for z: ");
scanf("%d", &v1.z);
printf("Vector 2 - Enter value for x: ");
scanf("%d", &v2.x);
printf("Vector 2 - Enter value for y: ");
scanf("%d", &v2.y);
printf("Vector 2 - Enter value for z: ");
scanf("%d", &v2.z);
}
You can't use int[] in the place of vector3d. You can pass your vector struct and use it to perform your tasks. I have written this code, you can modify it with your needs.
#include <stdio.h>
#include <stdlib.h>
int n = 3;
typedef struct vector3d
{
int x, y, z;
} vector3d;
int dot_product(vector3d v1, vector3d v2)
{
int dproduct = 0;
dproduct += v1.x * v2.x;
dproduct += v1.y * v2.y;
dproduct += v1.z * v2.z;
return dproduct;
}
vector3d cross_product(vector3d v1, vector3d v2)
{
vector3d crossproduct = {0, 0, 0};
crossproduct.x = v1.y * v2.z - v1.z * v2.y;
crossproduct.y = v1.x * v2.z - v1.z * v2.x;
crossproduct.z = v1.x * v2.y - v1.y * v2.x;
return crossproduct;
}
int main()
{
vector3d v1 = {0, 0, 0};
vector3d v2 = {0, 0, 0};
printf("Vector 1 - Enter value for x: ");
scanf("%d", &v1.x);
printf("Vector 1 - Enter value for y: ");
scanf("%d", &v1.y);
printf("Vector 1 - Enter value for z: ");
scanf("%d", &v1.z);
printf("Vector 2 - Enter value for x: ");
scanf("%d", &v2.x);
printf("Vector 2 - Enter value for y: ");
scanf("%d", &v2.y);
printf("Vector 2 - Enter value for z: ");
scanf("%d", &v2.z);
printf("Dotproduct: %d\n", dot_product(v1, v2));
vector3d cp = cross_product(v1, v2);
printf("Crossproduct: x:%d y:%d z:%d", cp.x, cp.y, cp.z);
return 0;
}
//OUTPUT
Vector 1 - Enter value for x: 1
Vector 1 - Enter value for y: 2
Vector 1 - Enter value for z: 3
Vector 2 - Enter value for x: 3
Vector 2 - Enter value for y: 2
Vector 2 - Enter value for z: 1
Dotproduct: 10
Crossproduct: x:-4 y:-8 z:-4
In the future try to think of these small things by your self.
You create an alias of your struct using typedef and use the struct in the vector analysis functions (Passing struct to function). To access the fields of the struct use the . notation. There is another possiblitiy to pass structs to functions as a pointer to the struct, in this case you use the -> notation to access the fields (Passing pointers/references to structs into functions, https://www.tutorialspoint.com/cprogramming/c_structures.htm)
typedef struct
{
int x;
int y;
int z;
} vector3d;
int dot_product (vector3d v1, vector3d v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
In this link instead of 3D vectors complex numbers ('2D vectors' approximately) are used, you can adapt this : https://www.programiz.com/c-programming/c-structure-function

gsl_vector_get() returns wrong value in printf()

I'm trying to write a Newton Solver with gsl. It's a system of two equations that take cartesian coordinate (x, y) and translate them into two angles (it's for a robot arm project I'm building; these angles are sent to the stepper motors to move the effector to the cartesian input coordinates).
Here is my function:
int
calc_angles(gsl_vector* coords, gsl_vector* result_angles)
{
const gsl_multiroot_fdfsolver_type* T;
gsl_multiroot_fdfsolver* s;
int status;
size_t i, iter = 0;
const size_t n = 2;
// coordinates whose's angles is to be found
struct rparams p = { gsl_vector_get(coords, 0), gsl_vector_get(coords, 1) };
gsl_multiroot_function_fdf f = { &coords_f,
&coords_df,
&coords_fdf,
n, &p};
// TODO: calculate inital guess
double angles_init[2] = { 140.0*M_PI/180.0, 30*M_PI/180.0 };
gsl_vector* angles = gsl_vector_alloc(n);
gsl_vector_set(angles, 0, angles_init[0]);
gsl_vector_set(angles, 1, angles_init[1]);
T = gsl_multiroot_fdfsolver_gnewton;
s = gsl_multiroot_fdfsolver_alloc(T, n);
gsl_multiroot_fdfsolver_set(s, &f, angles);
print_state(iter, s);
do
{
iter++;
status = gsl_multiroot_fdfsolver_iterate(s);
print_state(iter, s);
if(status) { break; }
status = gsl_multiroot_test_residual(s->f, 1e-7);
} while (status == GSL_CONTINUE && iter < 1000);
printf("status = %s\n", gsl_strerror(status));
print_state(iter, s);
// store results in result_angles
gsl_vector_memcpy(result_angles, angles);
// sanity check
if(gsl_vector_equal(result_angles, angles))
{
printf("Vectors are equal\n");
}
gsl_multiroot_fdfsolver_free(s);
gsl_vector_free(angles);
return GSL_SUCCESS;
}
//------------------------------------------------------------------------------
int
print_state(size_t iter, gsl_multiroot_fdfsolver* s)
{
printf("iter = %3u x = % .6f % .6f "
"f(x) = % .3e % .3e\n",
iter,
gsl_vector_get(s->x, 0),
gsl_vector_get(s->x, 1),
gsl_vector_get(s->f, 0),
gsl_vector_get(s->f, 1) );
// all good, return success
return GSL_SUCCESS;
}
The function calc_angles takes two vectors, one with the input coordinates that are used to calculate the angles I'm looking for, and a second vector where I want to store said angles. Now, this works as expected and the function does calculate the correct angles for my input cartesian coordinates (I haven't implemented the input reading function yet; so I'm using hard coded values for testing).
Here's my problem: when I call calc_angles in my main function, when I return to main and try to print the resulting angles, they no longer match the calculated values:
int
main(int argc, char* argv[])
{
const size_t n = 2;
// initialize vectors: input coords, initial guess, result angles
gsl_vector* coords = gsl_vector_alloc(n);
gsl_vector* result_angles = gsl_vector_alloc(n);
gsl_vector_set(result_angles, 0, 0.0); // set result angles to zero
gsl_vector_set(result_angles, 1, 0.0);
// TODO: read coordinates from input
// get_coords(coords);
gsl_vector_set(coords, 0, 0.0);
gsl_vector_set(coords, 1, 8.6);
// calc new angles
if(calc_angles(coords, result_angles)) { printf("calc_angles worked"); }
// output new angles
printf("Calculated angles: alpha: % .6f, beta: % .6f\n",
gsl_vector_get(result_angles, 0),
gsl_vector_get(result_angles, 1) );
// deallocate memory
gsl_vector_free(coords);
gsl_vector_free(result_angles);
return 0;
}
Here's the output of the program:
./bin/example_app
iter = 0 x = 2.443461 0.523599 f(x) = 9.998e-02 -2.905e-01
iter = 1 x = 2.308197 0.897453 f(x) = -4.876e-02 8.863e-02
iter = 2 x = 2.336417 0.808354 f(x) = -2.295e-03 1.077e-02
iter = 3 x = 2.342411 0.799205 f(x) = -1.653e-05 2.539e-04
iter = 4 x = 2.342579 0.799014 f(x) = -2.884e-09 3.705e-06
iter = 5 x = 2.342582 0.799011 f(x) = -7.438e-15 5.048e-08
status = success
iter = 5 x = 2.342582 0.799011 f(x) = -7.438e-15 5.048e-08
Vectors are equal
Calculated angles: alpha: 2.443461, beta: 0.523599
You can see that alpha and beta don't match the calculated values any longer. I used gdb to check the memory locations, the values didn't change (so gsl_vector_memcpy() does work correctly). So I assume it's something with printf that isn't working. What am I missing?
I'm new to gsl. Here's the full source code (copied into one file for simplicity):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_sf.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_multiroots.h>
// constants
const double LENGTH = 6.0;
const double TOL = 1.0e-6;
// params struct
struct rparams
{
double x, y;
};
// calculate the primary and secondary angles for the given coordinates in coords
int calc_angles(gsl_vector* coords, gsl_vector* result_angles);
int coords_f(const gsl_vector* angles, void* params, gsl_vector* f);
int coords_df(const gsl_vector* angles, void* params, gsl_matrix* J);
int coords_fdf(const gsl_vector* angles, void* params, gsl_vector* f, gsl_matrix* J);
// IO functions
int get_coords(gsl_vector* coords);
// helper/debug functions
int print_state(size_t iter, gsl_multiroot_fdfsolver* s);
int
main(int argc, char* argv[])
{
const size_t n = 2;
// initialize vectors: input coords, initial guess, result angles
gsl_vector* coords = gsl_vector_alloc(n);
gsl_vector* result_angles = gsl_vector_alloc(n);
gsl_vector_set(result_angles, 0, 0.0); // set result angles to zero
gsl_vector_set(result_angles, 1, 0.0);
// TODO: read coordinates from input
// get_coords(coords);
gsl_vector_set(coords, 0, 0.0);
gsl_vector_set(coords, 1, 8.6);
// calc new angles
if(calc_angles(coords, result_angles)) { printf("calc_angles worked"); }
// output new angles
printf("Calculated angles: alpha: % .6f, beta: % .6f\n",
gsl_vector_get(result_angles, 0),
gsl_vector_get(result_angles, 1) );
// deallocate memory
gsl_vector_free(coords);
gsl_vector_free(result_angles);
return 0;
}
//------------------------------------------------------------------------------
int
calc_angles(gsl_vector* coords, gsl_vector* result_angles)
{
const gsl_multiroot_fdfsolver_type* T;
gsl_multiroot_fdfsolver* s;
int status;
size_t i, iter = 0;
const size_t n = 2;
// coordinates whose's angles is to be found
struct rparams p = { gsl_vector_get(coords, 0), gsl_vector_get(coords, 1) };
gsl_multiroot_function_fdf f = { &coords_f,
&coords_df,
&coords_fdf,
n, &p};
// TODO: calculate inital guess
double angles_init[2] = { 140.0*M_PI/180.0, 30*M_PI/180.0 };
gsl_vector* angles = gsl_vector_alloc(n);
gsl_vector_set(angles, 0, angles_init[0]);
gsl_vector_set(angles, 1, angles_init[1]);
T = gsl_multiroot_fdfsolver_gnewton;
s = gsl_multiroot_fdfsolver_alloc(T, n);
gsl_multiroot_fdfsolver_set(s, &f, angles);
print_state(iter, s);
do
{
iter++;
status = gsl_multiroot_fdfsolver_iterate(s);
print_state(iter, s);
if(status) { break; }
status = gsl_multiroot_test_residual(s->f, 1e-7);
} while (status == GSL_CONTINUE && iter < 1000);
printf("status = %s\n", gsl_strerror(status));
print_state(iter, s);
// store results in result_angles
gsl_vector_memcpy(result_angles, angles);
// sanity check
if(gsl_vector_equal(result_angles, angles))
{
printf("Vectors are equal\n");
}
gsl_multiroot_fdfsolver_free(s);
gsl_vector_free(angles);
return GSL_SUCCESS;
}
//------------------------------------------------------------------------------
int
coords_f(const gsl_vector* angles, void* params, gsl_vector* f)
{
// extract c and y coordinates
double x = ((struct rparams*) params)->x;
double y = ((struct rparams*) params)->y;
// extract input angles
const double alpha = gsl_vector_get(angles, 0);
const double beta = gsl_vector_get(angles, 1);
// calculate coordinates from angles
const double x0 = gsl_sf_cos(alpha) + gsl_sf_cos(beta) - x / LENGTH;
const double y0 = gsl_sf_sin(alpha) + gsl_sf_sin(beta) - y / LENGTH;
// save results
gsl_vector_set(f, 0, x0);
gsl_vector_set(f, 1, y0);
// all good, return success
return GSL_SUCCESS;
}
//------------------------------------------------------------------------------
int
coords_df(const gsl_vector* angles, void* params, gsl_matrix* J)
{
// extract input angle
const double alpha = gsl_vector_get(angles, 0);
const double beta = gsl_vector_get(angles, 1);
// calculate partial derivatives for Jacobian matrix
const double df00 = -gsl_sf_sin(alpha);
const double df01 = -gsl_sf_sin(beta);
const double df10 = gsl_sf_cos(alpha);
const double df11 = gsl_sf_sin(beta);
// set Jacobian matrix
gsl_matrix_set(J, 0, 0, df00);
gsl_matrix_set(J, 0, 1, df01);
gsl_matrix_set(J, 1, 0, df10);
gsl_matrix_set(J, 1, 1, df11);
// all good, return success
return GSL_SUCCESS;
}
//------------------------------------------------------------------------------
int
coords_fdf(const gsl_vector* angles, void* params, gsl_vector* f, gsl_matrix* J)
{
coords_f(angles, params, f);
coords_df(angles, params, J);
// all good, return success
return GSL_SUCCESS;
}
//------------------------------------------------------------------------------
int
get_coords(gsl_vector* coords)
{
// TODO: replace with platform specific code
// read new coordinates from input
float x, y;
printf("Enter new X coordinate: ");
scanf("%f", &x);
printf("Enter new Y coordinate: ");
scanf("%f", &y);
// TODO: check for legal input bounds
// store input in memory
gsl_vector_set(coords, 0, x);
gsl_vector_set(coords, 1, y);
printf("x: %3.3f, y: %3.3f\n", x, y);
// all good, return success
return GSL_SUCCESS;
}
//------------------------------------------------------------------------------
int
print_state(size_t iter, gsl_multiroot_fdfsolver* s)
{
printf("iter = %3u x = % .6f % .6f "
"f(x) = % .3e % .3e\n",
iter,
gsl_vector_get(s->x, 0),
gsl_vector_get(s->x, 1),
gsl_vector_get(s->f, 0),
gsl_vector_get(s->f, 1) );
// all good, return success
return GSL_SUCCESS;
}
Short answer: s -> x stores the state of the solver, you shouldn't use the input array angles to get the output. This is the result of your code after I fixed a couple of minor details
iter = 0 x = 2.443461 0.523599 f(x) = 9.998e-02 -2.905e-01
iter = 1 x = 2.308197 0.897453 f(x) = -4.876e-02 8.863e-02
iter = 2 x = 2.336417 0.808354 f(x) = -2.295e-03 1.077e-02
iter = 3 x = 2.342411 0.799205 f(x) = -1.653e-05 2.539e-04
iter = 4 x = 2.342579 0.799014 f(x) = -2.884e-09 3.705e-06
iter = 5 x = 2.342582 0.799011 f(x) = -7.438e-15 5.048e-08
status = success
iter = 5 x = 2.342582 0.799011 f(x) = -7.438e-15 5.048e-08
calc_angles worked
Calculated angles: alpha: 2.342582, beta: 0.799011
And here is the actual code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_multiroots.h>
#include <gsl/gsl_sf.h>
// constants
const double LENGTH = 6.0;
const double TOL = 1.0e-6;
// params struct
struct rparams
{
double x, y;
};
// calculate the primary and secondary angles for the given coordinates in coords
int calc_angles(gsl_vector* coords, gsl_vector* result_angles);
int coords_f(const gsl_vector* angles, void* params, gsl_vector* f);
int coords_df(const gsl_vector* angles, void* params, gsl_matrix* J);
int coords_fdf(const gsl_vector* angles, void* params, gsl_vector* f, gsl_matrix* J);
// IO functions
int get_coords(gsl_vector* coords);
// helper/debug functions
int print_state(size_t iter, gsl_multiroot_fdfsolver* s);
int
main(int argc, char* argv[])
{
const size_t n = 2;
// initialize vectors: input coords, initial guess, result angles
gsl_vector* coords = gsl_vector_alloc(n);
gsl_vector* result_angles = gsl_vector_alloc(n);
gsl_vector_set(result_angles, 0, 0.0); // set result angles to zero
gsl_vector_set(result_angles, 1, 0.0);
// TODO: read coordinates from input
// get_coords(coords);
gsl_vector_set(coords, 0, 0.0);
gsl_vector_set(coords, 1, 8.6);
// calc new angles
if(!calc_angles(coords, result_angles)) { printf("calc_angles worked\n"); }
// output new angles
printf("Calculated angles: alpha: % .6f, beta: % .6f\n",
gsl_vector_get(result_angles, 0),
gsl_vector_get(result_angles, 1) );
// deallocate memory
gsl_vector_free(coords);
gsl_vector_free(result_angles);
return 0;
}
//------------------------------------------------------------------------------
int
calc_angles(gsl_vector* coords, gsl_vector* result_angles)
{
const gsl_multiroot_fdfsolver_type* T;
gsl_multiroot_fdfsolver* s;
int status;
size_t iter = 0;
const size_t n = 2;
// coordinates whose's angles is to be found
struct rparams p = { gsl_vector_get(coords, 0), gsl_vector_get(coords, 1) };
gsl_multiroot_function_fdf f = { &coords_f,
&coords_df,
&coords_fdf,
n, &p};
// TODO: calculate inital guess
double angles_init[2] = { 140.0*M_PI/180.0, 30*M_PI/180.0 };
gsl_vector* angles = gsl_vector_alloc(n);
gsl_vector_set(angles, 0, angles_init[0]);
gsl_vector_set(angles, 1, angles_init[1]);
T = gsl_multiroot_fdfsolver_gnewton;
s = gsl_multiroot_fdfsolver_alloc(T, n);
gsl_multiroot_fdfsolver_set(s, &f, angles);
print_state(iter, s);
do
{
iter++;
status = gsl_multiroot_fdfsolver_iterate(s);
print_state(iter, s);
if(status) { break; }
status = gsl_multiroot_test_residual(s->f, 1e-7);
} while (status == GSL_CONTINUE && iter < 1000);
printf("status = %s\n", gsl_strerror(status));
print_state(iter, s);
// store results in result_angles
gsl_vector_memcpy(result_angles, s -> x);
// sanity check
if(gsl_vector_equal(result_angles, angles))
{
printf("Vectors are equal\n");
}
gsl_multiroot_fdfsolver_free(s);
gsl_vector_free(angles);
return GSL_SUCCESS;
}
//------------------------------------------------------------------------------
int
coords_f(const gsl_vector* angles, void* params, gsl_vector* f)
{
// extract c and y coordinates
double x = ((struct rparams*) params)->x;
double y = ((struct rparams*) params)->y;
// extract input angles
const double alpha = gsl_vector_get(angles, 0);
const double beta = gsl_vector_get(angles, 1);
// calculate coordinates from angles
const double x0 = gsl_sf_cos(alpha) + gsl_sf_cos(beta) - x / LENGTH;
const double y0 = gsl_sf_sin(alpha) + gsl_sf_sin(beta) - y / LENGTH;
// save results
gsl_vector_set(f, 0, x0);
gsl_vector_set(f, 1, y0);
// all good, return success
return GSL_SUCCESS;
}
//------------------------------------------------------------------------------
int
coords_df(const gsl_vector* angles, void* params, gsl_matrix* J)
{
// extract input angle
const double alpha = gsl_vector_get(angles, 0);
const double beta = gsl_vector_get(angles, 1);
// calculate partial derivatives for Jacobian matrix
const double df00 = -gsl_sf_sin(alpha);
const double df01 = -gsl_sf_sin(beta);
const double df10 = gsl_sf_cos(alpha);
const double df11 = gsl_sf_sin(beta);
// set Jacobian matrix
gsl_matrix_set(J, 0, 0, df00);
gsl_matrix_set(J, 0, 1, df01);
gsl_matrix_set(J, 1, 0, df10);
gsl_matrix_set(J, 1, 1, df11);
// all good, return success
return GSL_SUCCESS;
}
//------------------------------------------------------------------------------
int
coords_fdf(const gsl_vector* angles, void* params, gsl_vector* f, gsl_matrix* J)
{
coords_f(angles, params, f);
coords_df(angles, params, J);
// all good, return success
return GSL_SUCCESS;
}
//------------------------------------------------------------------------------
int
get_coords(gsl_vector* coords)
{
// TODO: replace with platform specific code
// read new coordinates from input
float x, y;
printf("Enter new X coordinate: ");
scanf("%f", &x);
printf("Enter new Y coordinate: ");
scanf("%f", &y);
// TODO: check for legal input bounds
// store input in memory
gsl_vector_set(coords, 0, x);
gsl_vector_set(coords, 1, y);
printf("x: %3.3f, y: %3.3f\n", x, y);
// all good, return success
return GSL_SUCCESS;
}
//------------------------------------------------------------------------------
int
print_state(size_t iter, gsl_multiroot_fdfsolver* s)
{
printf("iter = %3ld x = % .6f % .6f "
"f(x) = % .3e % .3e\n",
iter,
gsl_vector_get(s->x, 0),
gsl_vector_get(s->x, 1),
gsl_vector_get(s->f, 0),
gsl_vector_get(s->f, 1) );
// all good, return success
return GSL_SUCCESS;
}

Segfault with SDL_BlitSurface() in loop

I was given a char *map that contains the different elements that you can find on screen. Those elements are e, for electricity, c, for coin, and _, for empty space.
I've done a loop that will go through the array and will detect whenever I have one of those characters. Here's the problem though, when I look to blit the corresponding sprite for each letter my program segfaults.
When I took out SDL_BlitSurface() the program works correctly, doing the amount of loops necesary.
I feel that I'm missing something before SDL_BlitSurface()
Here's the function where everything goes wrong:
void print_map()
{
int i;
SDL_Rect pos;
int x;
int y;
if ((th_client[1].coin = IMG_Load("./images/coin.png")) == NULL)
printf("Erreur\n");
y = 0;
i = 0;
while (y != 10)
{
pos.y = (y * 10) + 5;
x = 0;
while (x != 95)
{
pos.x = (x * 10) + 5;
printf("pos x: %d\n", pos.x);
if (th_client[1].map[i] == 'c')
{
printf("char : %c\n", th_client[1].map[i]);
if ((SDL_BlitSurface(th_client[i].screen, NULL,th_client[i].coin, &pos)) == -1) // <- it blows up right here
printf("Erreur\n");
}
x++;
i++;
}
y++;
printf("y : %d\n", y);
}
SDL_FreeSurface(th_client[1].coin);
}
th_client[1] corresponds to the graphics thread, inside there's I've got a structure with everything needed to initialize SDL.
Output:
pos x: 5
...
pos x: 945
y : 1 // <- jumps into the next line
pos x: 5
...
pos x: 355
char : c // <- Coin found
Segmentation fault

Maximum sum of non consecutive elements

Given an array of positive integers, what's the most efficient algorithm to find non-consecutive elements from this array which, when added together, produce the maximum sum?
Dynamic programming? Given an array A[0..n], let M(i) be the optimal solution using the elements with indices 0..i. Then M(-1) = 0 (used in the recurrence), M(0) = A[0], and M(i) = max(M(i - 1), M(i - 2) + A[i]) for i = 1, ..., n. M(n) is the solution we want. This is O(n). You can use another array to store which choice is made for each subproblem, and so recover the actual elements chosen.
Let A be the given array and Sum be another array such that Sum[i] represents the maximum sum of non-consecutive elements from arr[0]..arr[i].
We have:
Sum[0] = arr[0]
Sum[1] = max(Sum[0],arr[1])
Sum[2] = max(Sum[0]+arr[2],Sum[1])
...
Sum[i] = max(Sum[i-2]+arr[i],Sum[i-1]) when i>=2
If size is the number of elements in arr then sum[size-1] will be the answer.
One can code a simple recursive method in top down order as:
int sum(int *arr,int i) {
if(i==0) {
return arr[0];
}else if(i==1) {
return max(arr[0],arr[1]);
}
return max(sum(arr,i-2)+arr[i],sum(arr,i-1));
}
The above code is very inefficient as it makes exhaustive duplicate recursive calls. To avoid this we use memoization by using an auxiliary array called sum as:
int sum(int *arr,int size) {
int *sum = malloc(sizeof(int) * size);
int i;
for(i=0;i<size;i++) {
if(i==0) {
sum[0] = arr[0];
}else if(i==1) {
sum[1] = max(sum[0],arr[1]);
}else{
sum[i] = max(sum[i-2]+arr[i],sum[i-1]);
}
}
return sum[size-1];
}
Which is O(N) in both space and time.
O(N) in time and O(1) in space (DP) solution:
int dp[2] = {a[0], a[1]};
for(int i = 2; i < a.size(); i++)
{
int temp = dp[1];
dp[1] = dp[0] + a[i];
dp[0] = max(dp[0], temp);
}
int answer = max(dp[0], dp[1]);
/**
* Given an array of positive numbers, find the maximum sum of elements such
* that no two adjacent elements are picked
* Top down dynamic programming approach without memorisation.
* An alternate to the bottom up approach.
*/
public class MaxSumNonConsec {
public static int maxSum(int a[], int start, int end) {
int maxSum = 0;
// Trivial cases
if (start == end) {
return a[start];
} else if (start > end) {
return 0;
} else if (end - start == 1) {
return a[start] > a[end] ? a[start] : a[end];
} else if (start < 0) {
return 0;
} else if (end >= a.length) {
return 0;
}
// Subproblem solutions, DP
for (int i = start; i <= end; i++) {
int possibleMaxSub1 = maxSum(a, i + 2, end);
int possibleMaxSub2 = maxSum(a, start, i - 2);
int possibleMax = possibleMaxSub1 + possibleMaxSub2 + a[i];
if (possibleMax > maxSum) {
maxSum = possibleMax;
}
}
return maxSum;
}
public static void main(String args[]) {
int a[] = { 8, 6, 11, 10, 11, 10 };
System.out.println(maxSum(a, 0, a.length - 1));
}
}
The solution by #Ismail Badawi does not seem to work in the following case: Let us take the array: 8, 3, 1, 7 Then in this case, the algo returns max sum = 9 whereas it should be 15.
A solution to correct it is given an array A[0..n], let M(i) be the optimal solution using the elements with indices 0..i. Then M(0) = A[0], and M(i) = max(M(i - 1), M(i - 2) + A[i], M(i-3) + A[i]) for i = 3, ..., n. M(n) is the solution we want. This is O(n).
IIUC: say your array is 1,2,3,4,5 then 3+5 would be 'correct' and 4+5 not, this means you'll have to find the largest numbers and check if they are consecutive. So an algorithm would be to make use of a second array, for the number of elements you need to add which you fill by traversing the original array and finding the largest non-consecutive integers, then add this up.
For the above array I guess [1,3], [1,4], [1,5], [1,3,5], [2,4], [2,5], [3,5] would be valid non-consecutive integers to be summed, the max sum would be 9 in this case [1,3,5]. So, to adapt the above algorithm, I would suggest you step through the array using several temporary arrays to find all the non-consecutive integer lists, and then check which is the largest. Keep in mind that 'most elements' does not mean 'largest sum'.
Dynamic programming solution is the most elegant of all.
And it serves for any value of the distance between two numbers that should not be considered.
But for k= 1, which is for consecutive numbers constraint, I tried using backtracking.
There are different patterns to be compared for the maximum sum. Below is the list :
Number of patterns for 1 = 1
[1]
Number of patterns for 2 = 2
[1][2]
Number of patterns for 3 = 2
[1, 3][2]
Number of patterns for 4 = 3
[1, 3][1, 4][2, 4]
Number of patterns for 5 = 4
[1, 3, 5][1, 4][2, 4][2, 5]
Number of patterns for 6 = 5
[1, 3, 5][1, 3, 6][1, 4, 6][2, 4, 6][2, 5]
Number of patterns for 7 = 7
[1, 3, 5, 7][1, 3, 6][1, 4, 6][1, 4, 7][2, 4, 6][2, 4, 7][2, 5, 7]
Number of patterns for 8 = 9
[1, 3, 5, 7][1, 3, 5, 8][1, 3, 6, 8][1, 4, 6, 8][1, 4, 7][2, 4, 6, 8][2, 4, 7][2, 5, 7][2, 5, 8]
Number of patterns for 9 = 12
[1, 3, 5, 7, 9][1, 3, 5, 8][1, 3, 6, 8][1, 3, 6, 9][1, 4, 6, 8][1, 4, 6, 9][1, 4, 7, 9][2, 4, 6, 8][2, 4, 6, 9][2, 4, 7, 9][2, 5, 7, 9][2, 5, 8]
Following is the code in java:
public class MaxSeqRecursive {
private static int num = 5;
private static int[] inputArry = new int[] { 1,3,9,20,7 };
private static Object[] outArry;
private static int maxSum = 0;
public static void main(String[] args) {
List<Integer> output = new ArrayList<Integer>();
output.add(1);
convert(output, -1);
for (int i = 0; i < outArry.length; i++) {
System.out.print(outArry[i] + ":");
}
System.out.print(maxSum);
}
public static void convert( List<Integer> posArry, int prevValue) {
int currentValue = -1;
if (posArry.size() == 0) {
if (prevValue == 2) {
return;
} else {
posArry.add(2);
prevValue = -1;
}
}
currentValue = (int) posArry.get(posArry.size() - 1);
if (currentValue == num || currentValue == num - 1) {
updateMax(posArry);
prevValue = (int) posArry.get(posArry.size() - 1);
posArry.remove(posArry.size() - 1);
} else {
int returnIndx = getNext(posArry, prevValue);
if (returnIndx == -2)
return;
if (returnIndx == -1) {
prevValue = (int) posArry.get(posArry.size() - 1);
posArry.remove(posArry.size() - 1);
} else {
posArry.add(returnIndx);
prevValue = -1;
}
}
convert(posArry, prevValue);
}
public static int getNext( List<Integer> posArry, int prevValue) {
int currIndx = posArry.size();
int returnVal = -1;
int value = (int) posArry.get(currIndx - 1);
if (prevValue < num) {
if (prevValue == -1)
returnVal = value + 2;
else if (prevValue - value < 3)
returnVal = prevValue + 1;
else
returnVal = -1;
}
if (returnVal > num)
returnVal = -1;
return returnVal;
}
public static void updateMax(List posArry) {
int sum = 0;
for (int i = 0; i < posArry.size(); i++) {
sum = sum + inputArry[(Integer) posArry.get(i) - 1];
}
if (sum > maxSum) {
maxSum = sum;
outArry = posArry.toArray();
}
}
}
Time complexity: O( number of patterns to be compared)
Another Java Implementation ( runs in linear time )
public class MaxSum {
private static int ofNonConsecutiveElements (int... elements) {
int maxsofar,maxi2,maxi1;
maxi1 = maxsofar = elements[0];
maxi2 = 0;
for (int i = 1; i < elements.length; i++) {
maxsofar = Math.max(maxi2 + elements[i], maxi1);
maxi2 = maxi1;
maxi1 = maxsofar;
}
return maxsofar;
}
public static void main(String[] args) {
System.out.println(ofNonConsecutiveElements(6, 4, 2, 8, 1));
}
}
My solution is O(N) time and O(1) space.
private int largestSumNonConsecutive(int[] a) {
return largestSumNonConsecutive(a, a.length-1)[1];
}
private int[] largestSumNonConsecutive(int[] a, int end) { //returns array largest(end-1),largest(end)
if (end==0) return new int[]{0,a[0]};
int[] largest = largestSumNonConsecutive(a, end-1);
int tmp = largest[1];
largest[1] = Math.max(largest[0] + a[end], largest[1]);
largest[0] = tmp;
return largest;
}
int nonContigousSum(vector<int> a, int n) {
if (n < 0) {
return 0;
}
return std::max(nonContigousSum(a, n - 1), nonContigousSum(a, n - 2) + a[n]);
}
this is the recursive approach with the help of which we can solve this question
(OPTIMAL SUB-STRUCTURE HALLMARK OF DYNAMIC PROGRAMMING.
Here we are considering two cases, in first we exclude a[n] and in the second we include a[n] and return the max of those sub cases found.
We are basically finding all the subsets of the array and returning the length of the non-contiguous array with max sum.
Use tabulation or memoization for avoiding same sub-problems.
A penny from me.
public class Problem {
/**
* Solving by recursion, top down approach. Always try this recursion approach and then go with
* iteration. We have to add dp table to optimize the time complexity.
*/
public static int maxSumRecur(int arr[], int i) {
if(i < 0) return 0;
if(i == 0) return arr[0];
if(i == 1) return Math.max(arr[0], arr[1]);
int includeIthElement = arr[i] + maxSumRecur(arr, i-2);
int excludeIthElement = maxSumRecur(arr, i-1);
return Math.max(includeIthElement, excludeIthElement);
}
/**
* Solving by iteration. Bottom up approach.
*/
public static void maxSumIter(int arr[]) {
System.out.println(Arrays.toString(arr));
int dp[] = new int[arr.length];
dp[0] = arr[0];
dp[1] = Math.max(arr[0], arr[1]);
for(int i=2; i <= arr.length - 1; i++) {
dp[i] = Math.max(arr[i] + dp[i-2], dp[i-1]);
}
System.out.println("Max subsequence sum by Iteration " + dp[arr.length - 1] + "\n");
}
public static void maxSumRecurUtil(int arr[]) {
System.out.println(Arrays.toString(arr));
System.out.println("Max subsequence sum by Recursion " + maxSumRecur(arr, arr.length - 1) +
"\n");
}
public static void main(String[] args) {
maxSumRecurUtil(new int[]{5, 5, 10, 100, 10, 5});
maxSumRecurUtil(new int[]{20, 1, 2, 3});
maxSumIter(new int[]{5, 5, 10, 100, 10, 5});
maxSumIter(new int[]{20, 1, 2, 3});
}
}
Make a list of numbers that is the odd or even sums corresponding to each number so far; e.g. for input of [1,2,4,1,2,3,5,3,1,2,3,4,5,2] the odd-even sums would be [1,2,5,3,7,6,12,9,13,11,16,15,21,17]
Now walk the list backwards greedily summing but skipping those elements whose odd/even sum is less than that of next-to-be-considered element.
src = [1,2,4,1,2,3,5,3,1,2,3,4,5,2]
odd_even_sums = src[:2]
for i in xrange(2,len(src)):
odd_even_sums.append(src[i] + odd_even_sums[i-2])
best = []
for i in xrange(len(src)-1,-1,-1):
if i == 0:
best.append(i)
elif odd_even_sums[i-1] > odd_even_sums[i]:
pass
elif odd_even_sums[i-1] == odd_even_sums[i]:
raise Exception("an exercise for the reader")
else:
best.append(i)
best.reverse()
print "Best:",",".join("%s=%s"%(b,src[b]) for b in best)
print "Scores:",sum(odd_even_sums[b] for b in best)
Outputs:
Best: 0=1,1=2,2=4,4=2,6=5,8=1,10=3,12=5
Scores: 77
public static int findMaxSum(int[] a){
int sum0=0; //will hold the sum till i-2
int sum1=0;//will hold the sum till i-1
for(int k : a){
int x=Math.max(sum0+k, sum1);//max(sum till (i-2)+a[i], sum till (i-1))
sum0=sum1;
sum1=x;
}
return sum1;
}
Below is the crux of algorithm:
max(max sum till (i-2)+a[i], max sum till (i-1))
O(N) time complexity and O(1) space complexity.
A rather naive yet complete implementation.
Recursion equation is T(n) = n^2 + nT(n-3), which if I'm not wrong leads to exponential time. The (n-3) comes from the fact a number cannot add with itself/previous/next numbers.
The program reports the constituent list that makes up the sum (there are multiple, exponentially growing, of these lists, but it just picks one).
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class MaxSumNoAdjacent {
private static class Sum {
int sum;
List<Integer> constituents = new ArrayList<>();
Sum(int sum, List<Integer> constituents) {
this.sum = sum;
this.constituents = constituents;
}
#Override
public String toString() {
return "sum: " + sum + " " + constituents.toString();
}
}
public static Sum maxSum(int[] arr) {
List<Integer> input = new ArrayList<>();
for (int i : arr) {
if (i != Integer.MIN_VALUE) { //Integer.MIN_VALUE indicates unreachability
input.add(i);
}
}
if (input.size() == 0) {
return null;
}
if (input.size() == 1) {
List<Integer> constituents = new ArrayList<>();
constituents.add(input.get(0));
return new Sum(input.get(0), constituents);
}
if (input.size() == 2) {
int max = Math.max(input.get(0), input.get(1));
List<Integer> constituents = new ArrayList<>();
constituents.add(max);
return new Sum(max, constituents);
}
Map<Integer, int[]> numberAndItsReachability = new HashMap<>();
for (int i = 0; i < input.size(); i++) {
int[] neighbours = new int[input.size()];
if (i > 0) {
neighbours[i-1] = Integer.MIN_VALUE; //unreachable to previous
}
if (i < input.size()-1) {
neighbours[i+1] = Integer.MIN_VALUE; //unreachable to next
}
neighbours[i] = Integer.MIN_VALUE; //unreachable to itself
for (int j = 0; j < neighbours.length; j++) {
if (neighbours[j] == 0) {
neighbours[j] = input.get(j); //remember values of reachable neighbours
}
}
numberAndItsReachability.put(input.get(i), neighbours);
}
Sum maxSum = new Sum(Integer.MIN_VALUE, null);
for (Entry<Integer, int[]> pair : numberAndItsReachability.entrySet()) {
Sum sumMinusThisNumber = maxSum(pair.getValue()); //call recursively on its reachable neighbours
if (sumMinusThisNumber != null) {
int candidateSum = sumMinusThisNumber.sum + pair.getKey();
if (maxSum.sum < candidateSum) {
sumMinusThisNumber.constituents.add(pair.getKey());
maxSum = new Sum(candidateSum, sumMinusThisNumber.constituents);
}
}
}
return maxSum;
}
public static void main(String[] args) {
int[] arr1 = {3,2,5,10,7};
int[] arr2 = {3,2,7,10};
int[] arr3 = {5,5,10,40,50,35};
int[] arr4 = {4,4,4,4};
System.out.println(maxSum(arr1).toString());
System.out.println(maxSum(arr2).toString());
System.out.println(maxSum(arr3).toString());
System.out.println(maxSum(arr4).toString());
}
}
Here is a C# version for reference (you may refer to: http://dream-e-r.blogspot.com/2014/07/maximum-sum-of-non-adjacent-subsequence.html):
In-order to solve a problem using dynamic programming there should be a solution which has optimal substructure and overlapping sub problems properties. And the current problem has optimal substructure property.
Say, f(i) is defined as maximum subsequence sum of non adjacent elements for 'i' items, then
f( i) = 0 if i = 0
max (f(i-1), f(i-2) + a[i])
Below is the algorithm for the same (no
te it can solved without the encapsulating data in 'record' - i just preferred it this way) - which should illustrate the above idea:
int FindMaxNonAdjuscentSubsequentSum(int[] a)
{
a.ThrowIfNull("a");
if(a.Length == 0)
{
return 0;
}
Record r = new Record()
{
max_including_item = a[0],
max_excluding_item = 0
};
for (int i = 1; i < a.Length; i++)
{
var t = new Record();
//there will be only two cases
//1. if it includes the current item, max is maximum of non adjuscent sub
//sequence sum so far, excluding the last item
t.max_including_item = r.max_excluding_item + a[i];
//2. if it excludes current item, max is maximum of non adjuscent subsequence sum
t.max_excluding_item = r.Max;
r = t;
}
return r.Max;
}
Unit Tests
[TestMethod]
[TestCategory(Constants.DynamicProgramming)]
public void MaxNonAdjascentSubsequenceSum()
{
int[] a = new int[] { 3, 2, 5, 10, 7};
Assert.IsTrue(15 == this.FindMaxNonAdjuscentSubsequentSum(a));
a = new int[] { 3, 2, 5, 10 };
Assert.IsTrue(13 == this.FindMaxNonAdjuscentSubsequentSum(a));
a = new int[] { 5, 10, 40, 50, 35 };
Assert.IsTrue(80 == this.FindMaxNonAdjuscentSubsequentSum(a));
a = new int[] { 1, -1, 6, -4, 2, 2 };
Assert.IsTrue(9 == this.FindMaxNonAdjuscentSubsequentSum(a));
a = new int[] { 1, 6, 10, 14, -5, -1, 2, -1, 3 };
Assert.IsTrue(25 == this.FindMaxNonAdjuscentSubsequentSum(a));
}
where
public static int Max(int a, int b)
{
return (a > b) ? a : b;
}
class Record
{
public int max_including_item = int.MinValue;
public int max_excluding_item = int.MinValue;
public int Max
{
get
{
return Max(max_including_item, max_excluding_item);
}
}
}
public static int maxSumNoAdj(int[] nums){
int[] dp = new int[nums.length];
dp[0] = Math.max(0, nums[0]); // for dp[0], select the greater value (0,num[0])
dp[1] = Math.max(nums[1], Math.max(0, dp[0]));
int maxSum = Math.max(dp[0], dp[1]);
for(int i = 2; i < nums.length; i++){
int ifSelectCurrent = Math.max(nums[i] + dp[i-2], dp[i-2]);// if select, there are two possible
int ifNotSelectCurrent = Math.max(dp[i-1], dp[i-2]); // if not select, there are two posible
dp[i] = Math.max(ifSelectCurrent, ifNotSelectCurrent); // choose the greater one
maxSum = Math.max(dp[i], maxSum); // update the result
}
return maxSum;
}
public static void main(String[] args) {
int[] nums = {-9, 2, 3, -7, 1, 1};
System.out.println(maxSumNoAdj(nums));
}

Resources