Find maximum sum rectangle - c++

I write this code for Maximum sum rectangle in a 2D matrix problem. But it return false answer. For example for this instance return 0 while the correct answer is 15. User first give size of array then enter elements. What is my mistake?
Example
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
Code
int kadane(int* arr, int* start, int* finish, int n)
{
int sum = 0, maxSum = INT_MIN, i;
*finish = -1;
int local_start = 0;
for (i = 0; i < n; ++i)
{
sum += arr[i];
if (sum < 0)
{
sum = 0;
local_start = i+1;
}
else if (sum > maxSum)
{
maxSum = sum;
*start = local_start;
*finish = i;
}
}
if (*finish != -1)
return maxSum;
maxSum = arr[0];
*start = *finish = 0;
for (i = 1; i < n; i++)
{
if (arr[i] > maxSum)
{
maxSum = arr[i];
*start = *finish = i;
}
}
return maxSum;
}
void findMaxSum(int** M,int n)
{
int maxSum = INT_MIN, finalLeft, finalRight, finalTop, finalBottom;
int left, right, i;
int* temp=new int[n];
int sum, start, finish;
for (left = 0; left <n; ++left)
{
memset(temp, 0, sizeof(temp));
for (right = left; right < n; ++right)
{
for (i = 0; i < n; ++i)
temp[i] += M[i][right];
sum = kadane(temp, &start, &finish, n);
if (sum > maxSum)
{
maxSum = sum;
finalLeft = left;
finalRight = right;
finalTop = start;
finalBottom = finish;
}
}
}
printf("(Top, Left) (%d, %d)\n", finalTop, finalLeft);
printf("(Bottom, Right) (%d, %d)\n", finalBottom, finalRight);
printf("Max sum is: %d\n", maxSum);
}
int _tmain(int argc, _TCHAR* argv[])
{
int N;
cout<<"enter size of 2d array"<<endl;
cin>>N;
int** M;
M=new int*[N];
for(int i=0;i<N;i++)
{
M[i]=new int [N];
}
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
cin>>M[i][j];
}
}
findMaxSum(M,N);
/*for(int i=0;i<N;i++)
{
delete []M[i];
M[i]=0;
}
delete []M;*/
return 0;
}

memset(temp, 0, sizeof(temp));
doesn't do what you expect it to do since sizef(temp) evaluates to just the size of a pointer.
Replace that line with:
memset(temp, 0, sizeof(int)*n);
With that change, things work OK in my tests.
You can also use:
memset(temp, 0, sizeof(*temp)*n);

Related

Sort Count in C++. how can I skip a part of the sorting?

so I had the following sorting example (Count Sort), It's kind of weird actually, but it works, so it's fine :
#include<iostream>
using namespace std;
int getMx(int* arr,int n)
{
int max = arr[0];
for (int i = 1; i < n; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
}
void CountSort(int* arr, int n) {
int* output = new int[n];
int max = getMx(arr, n);
int* count = new int[max + 1];
for(int i = 0; i < max + 1; i++) {
count[i] = 0;
}
for(int i = 0; i < n; i++) {
count[arr[i]]++;
}
for(int i = 1; i <= max; i++) {
count[i] += count[i - 1];
}
for(int i = n - 1; i >= 0; i--) {
output[count[arr[i]] - 1] = arr[i];
count[arr[i]]--;
}
for(int i = 0; i < n; i++) {
arr[i] = output[i];
}
delete[] output;
delete[] count;
}
int main () {
int arr[] = { 100, 5, 2, 0, 125 };
int n = sizeof(arr) / sizeof(arr[0]);
CountSort(arr, n);
for (int i = 0; i < n; i++) {
cout << arr[i] << endl;
}
return 0;
}
So the main idea is just to get rid of the part when I sum the numbers stored in each index on Count[i]. And just get the output after the second cycle.
Example
int arr = [3, 2, 5, 4, 1, 0]
int count=[1,1,1,1,1,1]
and from there I should get
int output= [0, 1, 2, 3, 4, 5]
So I couldn't figue this out ((
You are probably thinking of something like this:
void CountSort(int* arr, int n) {
int max = getMx(arr, n);
int* count = new int[max + 1]{};
for(int i = 0; i < n; i++) {
count[arr[i]]++;
}
int k = 0;
for(int i = 0; i <= max; i++) {
while (count[i]--) {
arr[k++] = i;
}
}
delete[] count;
}
Demo

/bin/run.sh: line 4: 18 Segmentation fault (core dumped) ./exe

#include <bits/stdc++.h>
using namespace std;
int solve(int A, vector<int> &B) {
vector<int> pre(A);
vector<int> suff(A);
vector<int> p;
vector<int> s;
int sum = 0;
int ans = 0;
for (int i = 0; i < A; i++) {
sum = sum + B[i];
}
if (sum % 3 != 0)
return 0;
sum = sum / 3;
for (int i = 0; i < A; i++) {
if (i == 0) {
pre[i] = B[i];
if (pre[i] == sum) {
p.push_back(i);
}
continue;
}
pre[i] = B[i] + pre[i - 1];
if (pre[i] == sum) {
p.push_back(i);
}
}
for (int i = A - 1; i >= 0; i--) {
if (i == A - 1) {
suff[A - 1] = B[A - 1];
if (suff[i] == sum) {
s.push_back(i);
}
continue;
}
suff[i] = B[i] + pre[i + 1];
if (suff[i] == sum) {
s.push_back(i);
}
}
for (int i = 0; i < p.size(); i++) {
for (int j = s.size(); j >= 0; j++) {
if (s[j] > p[i] + 1) {
ans++;
}
}
}
return ans;
}
int main() {
int A = 5;
vector<int> B = {1, 2, 3, 0, 3};
cout << solve(5, B);
return 0;
}
The code keeps getting dumped at pre[i]=B[i]. The code is very simple for counting the number of ways to split all the elements of the array into 3 contiguous parts so that the sum of elements in each part is the same.
I just made a prefix and suffix sum array.

Find minimum and maximum value from two dimensional array

My question is how to find minimum and maximum value from array of random numbers? I have tried a lot with different logic and I have gone through these links mentioned below but couldn't get the result, Any guidance would be appreciated.
https://www.youtube.com/watch?v=yes0HMZWxUo&t=447s
Put a multidimensional array into a one-dimensional array
#include<iostream>
#include<cstdlib>
#include<conio.h>
void populateArray();
void displayArray();
void findMaxMinNumber(int[5][5]);
main(){
system("cls");
int rows,columns = 5;
displayArray();
}
void populateArray(){
int randomNumber;
int minMax[5][5];
for(int rowCount = 0; rowCount < 5; rowCount++){
for(int columnCount = 0; columnCount < 5; columnCount++){
randomNumber = rand() % 100 + 1;
cout<<randomNumber;
minMax[rowCount][columnCount] = randomNumber;
if(randomNumber < 10){
cout<<" ";
}
else if(randomNumber >= 10){
cout<<" ";
}
}
cout<<endl;
}
findMaxMinNumber(minMax);
}
void displayArray(){
cout<<"Displaying array's data..."<<endl;
cout<<"------------------------------"<<endl;
populateArray();
}
void findMaxMinNumber(int arr[5][5]){
int rowMax = 0;
int colMax = 1;
int rowMin = 0;
int colMin = 1;
cout<<endl;
for(int i = 0; i < 5; i++){
rowMax++;
rowMin++;
for(int j = 0; j < 5; j++){
if(arr[i][j] < arr[rowMax][colMax]){
//cout<<endl<<arr[i][j];
rowMax = i;
colMax = j;
}
if(arr[i][j] > arr[rowMin][colMin]){
rowMin = i;
colMin = j;
}
colMax++;
colMin++;
}
}
cout<<endl<<"The max is :"<<arr[rowMax][colMax];
cout<<endl<<"The min is :"<<arr[rowMin][colMin];
}
void fillUpArray(int newArray[5][5])
{
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 5; ++j)
{
int randomNumber = rand() % 100 + 1;
printf("Random number[%d][%d]: %d\n", i, j, randomNumber);
newArray[i][j] = randomNumber;
}
}
}
void printMinimumMaximum(int myArray[5][5])
{
int minimum = myArray[0][0];
int maximum = myArray[0][0];
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 5; ++j)
{
if (myArray[i][j] < minimum)
{
minimum = myArray[i][j];
}
if (myArray[i][j] > maximum)
{
maximum = myArray[i][j];
}
}
}
printf("Minimum: %d\n", minimum);
printf("Maximum: %d\n", maximum);
}
int main()
{
int minMax[5][5];
fillUpArray(minMax);
printMinimumMaximum(minMax);
return 0;
}
void findMaxMinNumber(int arr[5][5]){
int* start = &arr[0][0];
cout<<endl<<"The max is :" << *std::max_element(start, start + 5*5);
cout<<endl<<"The min is :" << *std::min_element(start, start + 5*5);
}

Segmentation fault:11 MergeSort

I try to implement the merge sort algorithm and I get a segmentation fault. Why? The error seems to be in the MergeSort function. The merge sort function (on the 2nd call) when should check only an array of 4 numbers (the length should be 4) shows the length = 27. Why? (tested on an array with 8 elements)
#include<iostream>
using namespace std;
int n, A[1000];
void citire(int lungime) {
for (int i = 0; i < lungime; i++) cin >> A[i];
}
void afisare(int lungime) {
for (int i = 0; i < lungime; i++)
cout << A[i] << " ";
cout << '\n';
}
int lungime(int A[]) {
int i = 0;
while (A[i]) i++;
return i;
}
void Merge(int L[], int R[], int A[]) {
int nL = lungime(L);
int nR = lungime(R);
int i = 0, j = 0, k = 0;
while (i < nL && j < nR) {
if (L[i] <= R[j]) {
A[k] = L[i];
i++;
}
else {
A[k] = R[j];
j++;
}
k++;
}
while (i < nL) {
A[k] = L[i];
i++;
k++;
}
while (j < nR) {
A[k] = R[j];
j++;
k++;
}
}
void MergeSort(int A[]) {
int n1 = lungime(A);
if (n1 < 2) return;
else
{
int mid = (int)n1 / 2;
int L[mid];
int R[n - mid];
for (int i = 0; i < mid; i++)
L[i] = A[i];
for (int i = mid; i < n; i++)
R[i - mid] = A[i];
MergeSort(L);
MergeSort(R);
Merge(L, R, A);
}
}
int main() {
cin >> n;
citire(n);
MergeSort(A);
afisare(n);
return 0;
}
Changes made in this example. A[], L[], R[] are allocated using new. A[] is passed as a parameter. L[] and R[] are allocated in Merge(). Size and/or indices passed as parameters, and lungime() is no longer used to get size. Other changes noted in comments.
#include<iostream>
using namespace std;
void citire(int A[], int lungime) { // A is parameter
for (int i = 0; i < lungime; i++) cin >> A[i];
}
void afisare(int A[], int lungime) { // A is parameter
for (int i = 0; i < lungime; i++)
cout << A[i] << " ";
cout << '\n';
}
// A, low, mid, end are parameters
// L and R allocated here
void Merge(int A[], int low, int mid, int end) {
int sizeL = mid-low;
int sizeR = end-mid;
int *L = new int[sizeL];
int *R = new int[sizeR];
for(int i = 0; i < sizeL; i++)
L[i] = A[low+i]; // A[low+i]
for(int i = 0; i < sizeR; i++)
R[i] = A[mid+i]; // A[mid+i]
int i = 0, j = 0, k = low; // k = low
while (i < sizeL && j < sizeR) {
if (L[i] <= R[j]) {
A[k] = L[i];
i++;
}
else {
A[k] = R[j];
j++;
}
k++;
}
while (i < sizeL) {
A[k] = L[i];
i++;
k++;
}
while (j < sizeR) {
A[k] = R[j];
j++;
k++;
}
delete[] R;
delete[] L;
}
// A, low, end are parameters
void MergeSort(int A[], int low, int end) {
int sizeA = end - low;
if(sizeA < 2)
return;
int mid = low + (sizeA / 2); // mid = low + ...
MergeSort(A, low, mid);
MergeSort(A, mid, end);
Merge(A, low, mid, end);
}
int main() {
int n;
cin >> n;
int *A = new int[n]; // A is allocated
citire(A, n); // A, n are parameters
MergeSort(A, 0, n); // A, 0, n are parameters
afisare(A, n); // A, n are parameters
delete[] A;
return 0;
}
"The lungime function is the length of the string and this function works good. I've tested it on different arrays".
Well, this is purely accidental; uninitialized memory can contain zeros, and provide the array terminator by accident.
If you want to keep the current design, you should:
initialize A to zeros
make sure that there are no more than 999 elements in the input stream,
that no element has the value zero, as zero is reserved, and used as terminator, and
define L and R (in MergeSort) one element longer, and initialize the last element to zero.
Unless there are overwhelming reasons for a "roll your own" sort solution, you might have a look at prefab sort support. The vector class in C++ offers just that.

C++ Knapsack Algorithm Implementation

My algorithm for the best-first, branch and bound knapsack problem is giving me a max profit of 80 when it should be 90. I'm wondering where I went wrong... my thinking is the priority queue is a bit off.
Given input:
4,16 // 4 items to follow , 16 capacity knapsack
2,40 // item1.. weighs 2, costs 40
5,30 // item2.. weighs 5, costs 30
10,50 // item3.. weighs 10, costs 50
5,10 // item4.. weighs 5, costs 10
Code:
#include <iostream>
#include <string>
#include <queue>
#include <utility>
typedef struct node{
int level;
int profit;
int weight;
int bound;
} node;
struct node_cmp{
bool operator()(const node& a, const node& b) const{
return a.bound < b.bound;
}
};
int KWF2(int i, int weight, int profit, int *w, int *p, int C, int n){
int weight1 = weight;
int bound = profit;
int j;
float x[n+1];
for(j = i; j <= n; j++){
x[j] = 0;
}
while(weight1 < C && (i <= n)){
if(weight1 + w[i] <= C){
x[i] = 1;
weight1 += w[i];
bound += p[i];
}
else{
x[i] = ((float)C-(float)weight1)/(float)w[i];
weight1 = C;
bound = bound + p[i] * x[i];
}
i++;
}
return bound;
}
void knapsack(int *w, int *p, int C, int maxprofit, int n){
int maxp = maxprofit;
std::priority_queue<node,std::vector<node>,node_cmp> PQ;
node u,v;
v.level = 0;
v.profit = 0;
v.weight = 0;
v.bound = KWF2(v.level+1,v.weight,v.profit,w,p,C,n);
PQ.push(v);
while(!PQ.empty()){
v = PQ.top();
PQ.pop();
if(v.bound > maxp){
u.level = v.level + 1;
//yes child
u.weight = v.weight + w[u.level];
u.profit = v.profit + p[u.level];
if((u.weight <= C) && (u.profit > maxp)){
maxp = u.profit;
}
if(KWF2(u.level+1,u.weight,u.profit,w,p,C,n) > maxp){
PQ.push(u);
}
//no child
u.weight = v.weight;
u.profit = v.profit;
u.bound = KWF2(u.level+1,u.weight,u.profit,w,p,C,n);
if(u.bound > maxp){
PQ.push(u);
}
}
}
printf("%d\n",maxp);
}
int main(int argc, char **argv){
int n,C;
FILE *in = fopen(argv[1],"r");
fscanf(in,"%d,%d",&n,&C);
int w[n+1];
int p[n+1];
float ratio[n+1];
for(int i = 0; i < n; i++){
fscanf(in,"%d,%d",&w[i+1],&p[i+1]);
ratio[i+1] = (float)p[i+1]/(float)w[i+1];
}
int temp_w,temp_p;
float temp_r;
for(int i = 1; i <= n; i++){
for(int j = i + 1; j <= n; j++){
if(ratio[i] < ratio[j]){
temp_w = w[i];
temp_p = p[i];
temp_r = ratio[i];
w[i] = w[j];
p[i] = p[j];
ratio[i] = ratio[j];
w[j] = temp_w;
p[j] = temp_p;
ratio[j] = ratio[i];
}
}
}
int maxprofit = 0;
knapsack(w,p,C,maxprofit,n);
fclose(in);
return 0;
}