Related
I have a vector of vector of vector
std::vector<std::vector<std::vector<double>>> mountain_table
and I would like to find the coordinates i, j, k of this vector for which it is the highest. I know that I should use max_element but I don't know how to use it in a 3d vector.
How should I get those coordinates?
I'd suggest to linearize your data in order to be able to use standard algorithms. The idea is to provide a couple of functions to get an index from 3D coords and vice et versa:
template<class T>
class Matrix3D // minimal
{
public:
using value_type = T;
using iterator = std::vector<value_type>::iterator;
private:
std::vector<value_type> _data;
size_t _sizex, _sizey, _sizez;
size_t index_from_coords(size_t x, size_t y, size_t z) const
{
return x*_sizex*_sizey + y*_sizey + z;
}
std::tuple<size_t, size_t, size_t> coords_from_index(size_t index) const
{
const size_t x = index / (_sizex * _sizey);
index = index % x;
const size_t y = index / _sizey;
const size_t z = index % _sizey;
return make_tuple(x, y, z);
}
public:
Matrix3D(size_t sizex, sizey, sizez) : _sizex(sizex), ... {}
T& operator()(size_t x, size_t y, size_t z) // add const version
{
return _data[index_from_coords(x, y, z)];
}
std::tuple<size_t, size_t, size_t> coords(iterator it)
{
size_t index = std::distance(begin(_data), it);
return coords_from_index(index);
}
iterator begin() { return begin(_data); }
iterator end() { return end(_data); }
}
Usage:
Matrix3D<double> m(3, 3, 3);
auto it = std::max_element(m.begin(), m.end()); // or min, or whatever from http://en.cppreference.com/w/cpp/header/algorithm
auto coords = m.coords(it);
std::cout << "x=" << coords.get<0>() << ... << "\n";
This is untested and incomplete code to give you a kickstart into better data design. i'd be happy to answer further questions about this idea in the comment below ;)
Here is how I would do it, by looping over the matrix, checking for highest values, and recording its indexes.
size_t highestI = 0;
size_t highestJ = 0;
size_t highestK = 0;
double highestValue = -std::numeric_limits<double>::infinity(); // Default value (Include <limits>)
for (size_t i = 0; i < mountain_table.size(); ++i)
{
for (size_t j = 0; j < mountain_table[i].size(); ++j)
{
for (size_t k = 0; k < mountain_table[i][j].size(); ++k)
{
if (mountain_table[i][j][k] > highestValue)
{
highestValue = mountain_table[i][j][k]; // Highest
// value needed to figure out highest indexes
// Stores the current highest indexes
highestI = i;
highestJ = j;
highestK = k;
}
}
}
}
This may not be the most efficient algorithm, but it gets the job done in an understandable way.
Since the max_element function is pretty short and easy to implement, I would suggest to write something similar yourself to fit your exact scenario.
// For types like this I would suggest using a type alias
using Vector3d = std::vector<std::vector<std::vector<double>>>;
std::array<size_t, 3> max_element(const Vector3d& vector) {
std::std::array<size_t, 3> indexes;
double biggest = vector[0][0][0];
for (unsigned i = 0; i < vector.size(); ++i)
for (unsigned j = 0; j < vector[i].size(); ++j)
for (unsigned k = 0; k < vector[i][j].size(); ++k)
if (value > biggest) {
biggest = value;
indexes = { i, j, k };
}
return indexes;
}
One other suggestion I could give you is to write your custom class Vector3d, with convenient functions like operator()(int x, int y, int z) etc. and save the data internally in simple vector<double> of size width * height * depth.
std::size_t rv[3] = {0};
std::size_t i = 0;
double max_value = mountain_table[0][0][0];
for (const auto& x : mountain_table) {
std::size_t j = 0;
for (const auto& y : x) {
auto it = std::max_element(y.begin(), y.end());
if (*it > max_value) {
rv[0] = i; rv[1] = j; rv[2] = it - y.begin();
max_value = *it;
}
++j;
}
++i;
}
I do not think you can use std::max_element for such data. You can use std::accumulate():
using dvect = std::vector<double>;
using ddvect = std::vector<dvect>;
using dddvect = std::vector<ddvect>;
dddvect mx = { { { 1, 2, 3 }, { -1, 3 }, { 8,-2, 3 } },
{ {}, { -1, 25, 3 }, { 7, 3, 3 } },
{ { -1, -2, -3 }, {}, { 33 } } };
struct max_value {
size_t i = 0;
size_t j = 0;
size_t k = 0;
double value = -std::numeric_limits<double>::infinity();
max_value() = default;
max_value( size_t i, size_t j, size_t k, double v ) : i( i ), j( j ), k( k ), value( v ) {}
max_value operator<<( const max_value &v ) const
{
return value > v.value ? *this : v;
}
};
auto max = std::accumulate( mx.begin(), mx.end(), max_value{}, [&mx]( const max_value &val, const ddvect &ddv ) {
auto i = std::distance( &*mx.cbegin(), &ddv );
return std::accumulate( ddv.begin(), ddv.end(), val, [i,&ddv]( const max_value &val, const dvect &dv ) {
auto j = std::distance( &*ddv.cbegin(), &dv );
return std::accumulate( dv.begin(), dv.end(), val, [i,j,&dv]( const max_value &val, const double &d ) {
auto k = std::distance( &*dv.cbegin(), &d );
return val << max_value( i, j, k, d );
} );
} );
} );
live example. Code could be simplified if C++14 or later allowed but I am not sure that it would worse the effort and data reorganization most probably would work better (you would be able to use std::max_element() on singe vector for example). On another side this layout supports jagged matrix as shown on example (different size subarrays)
You should use "for" loop , because you don't have 3d vector.
for (size_t i = 0; i <mountain_table.size(); ++i)
{
for (size_t j = 0; j < mountain_table[i].size() ++j)
{
// find max element index k here and check if it is maximum.
// If yes save i, j, k and update max val
}
}
How to I reduce a chain of if statements in C++?
if(x == 3) {
a = 9876543;
}
if(x == 4) {
a = 987654;
}
if(x == 5) {
a = 98765;
}
if(x == 6) {
a = 9876;
}
if(x == 7) {
a = 987;
}
if(x == 8) {
a = 98;
}
if(x == 9) {
a = 9;
}
This is the example code.
You can generate this value mathematically, by using integer division:
long long orig = 9876543000;
long long a = orig / ((long) pow (10, x));
EDIT:
As #LogicStuff noted in the comments, it would be much more elegant to subtract 3 from x, instead of just multiplying orig by another 1000:
long orig = 9876543;
long a = orig / ((long) pow (10, x - 3));
With an array, you may do:
if (3 <= x && x <= 9) {
const int v[] = {9876543, 987654, 98765, 9876, 987, 98, 9};
a = v[x - 3];
}
Something like:
#include <iostream>
#include <string>
int main() {
int x = 4;
int a = 0;
std::string total;
for(int i = 9; i > 0 ; --i)
{
if(x <= i)
total += std::to_string(i);
}
a = std::stoi(total, nullptr);
std::cout << a << std::endl;
return 0;
}
http://ideone.com/2Cdve1
If the data can be derived, I'd recommend using one of the other answers.
If you realize their are some edge cases that end up making the derivation more complicated, consider a simple look-up table.
#include <iostream>
#include <unordered_map>
static const std::unordered_multimap<int,int> TABLE
{{3,9876543}
,{4,987654}
,{5,98765}
,{6,9876}
,{7,987}
,{8,98}
,{9,9}};
int XtoA(int x){
int a{0};
auto found = TABLE.find(x);
if (found != TABLE.end()){
a = found->second;
}
return a;
}
int main(){
std::cout << XtoA(6) << '\n'; //prints: 9876
}
I have a decimal string like this (length < 5000):
std::string decimalString = "555";
Is there a standard way to convert this string to binary representation? Like this:
std::string binaryString = "1000101011";
Update.
This post helps me.
As the number is very large, you can use a big integer library (boost, maybe?), or write the necessary functions yourself.
If you decide to implement the functions yourself, one way is to implement the old pencil-and-paper long division method in your code, where you'll need to divide the decimal number repeatedly by 2 and accumulate the remainders in another string. May be a little cumbersome, but division by 2 should not be so hard.
Since 10 is not a power of two (or the other way round), you're out of luck. You will have to implement arithmetics in base-10. You need the following two operations:
Integer division by 2
Checking the remainder after division by 2
Both can be computed by the same algorithm.
Alternatively, you can use one of the various big integer libraries for C++, such as GNU MP or Boost.Multiprecision.
I tried to do it.. I don't think my answer is right but here is the IDEA behind what I was trying to do..
Lets say we have 2 decimals:
100 and 200..
To concatenate these, we can use the formula:
a * CalcPower(b) + b where CalcPower is defined below..
Knowing this, I tried to split the very long decimal string into chunks of 4. I convert each string to binary and store them in a vector..
Finally, I go through each string and apply the formula above to concatenate each binary string into one massive one..
I didn't get it working but here is the code.. maybe someone else see where I went wrong.. BinaryAdd, BinaryMulDec, CalcPower works perfectly fine.. the problem is actually in ToBinary
#include <iostream>
#include <bitset>
#include <limits>
#include <algorithm>
std::string BinaryAdd(std::string First, std::string Second)
{
int Carry = 0;
std::string Result;
while(Second.size() > First.size())
First.insert(0, "0");
while(First.size() > Second.size())
Second.insert(0, "0");
for (int I = First.size() - 1; I >= 0; --I)
{
int FirstBit = First[I] - 0x30;
int SecondBit = Second[I] - 0x30;
Result += static_cast<char>((FirstBit ^ SecondBit ^ Carry) + 0x30);
Carry = (FirstBit & SecondBit) | (SecondBit & Carry) | (FirstBit & Carry);
}
if (Carry)
Result += 0x31;
std::reverse(Result.begin(), Result.end());
return Result;
}
std::string BinaryMulDec(std::string value, int amount)
{
if (amount == 0)
{
for (auto &s : value)
{
s = 0x30;
}
return value;
}
std::string result = value;
for (int I = 0; I < amount - 1; ++I)
result = BinaryAdd(result, value);
return result;
}
std::int64_t CalcPowers(std::int64_t value)
{
std::int64_t t = 1;
while(t < value)
t *= 10;
return t;
}
std::string ToBinary(const std::string &value)
{
std::vector<std::string> sets;
std::vector<int> multipliers;
int Len = 0;
int Rem = value.size() % 4;
for (auto it = value.end(), jt = value.end(); it != value.begin() - 1; --it)
{
if (Len++ == 4)
{
std::string t = std::string(it, jt);
sets.push_back(std::bitset<16>(std::stoull(t)).to_string());
multipliers.push_back(CalcPowers(std::stoull(t)));
jt = it;
Len = 1;
}
}
if (Rem != 0 && Rem != value.size())
{
sets.push_back(std::bitset<16>(std::stoull(std::string(value.begin(), value.begin() + Rem))).to_string());
}
auto formula = [](std::string a, std::string b, int mul) -> std::string
{
return BinaryAdd(BinaryMulDec(a, mul), b);
};
std::reverse(sets.begin(), sets.end());
std::reverse(multipliers.begin(), multipliers.end());
std::string result = sets[0];
for (std::size_t i = 1; i < sets.size(); ++i)
{
result = formula(result, sets[i], multipliers[i]);
}
return result;
}
void ConcatenateDecimals(std::int64_t* arr, int size)
{
auto formula = [](std::int64_t a, std::int64_t b) -> std::int64_t
{
return (a * CalcPowers(b)) + b;
};
std::int64_t val = arr[0];
for (int i = 1; i < size; ++i)
{
val = formula(val, arr[i]);
}
std::cout<<val;
}
int main()
{
std::string decimal = "64497387062899840145";
//6449738706289984014 = 0101100110000010000100110010111001100010100000001000001000001110
/*
std::int64_t arr[] = {644, 9738, 7062, 8998, 4014};
ConcatenateDecimals(arr, 5);*/
std::cout<<ToBinary(decimal);
return 0;
}
I found my old code that solve sport programming task:
ai -> aj
2 <= i,j <= 36; 0 <= a <= 10^1000
time limit: 1sec
Execution time was ~0,039 in worst case. Multiplication, addition and division algorithms is very fast because of using 10^9 as numeration system, but implementation can be optimized very well I think.
source link
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#define sz(x) (int((x).size()))
typedef vector<int> vi;
typedef long long llong;
int DigToNumber(char c) {
if( c <= '9' && c >= '0' )
return c-'0';
return c-'A'+10;
}
char NumberToDig(int n) {
if( n < 10 )
return '0'+n;
return n-10+'A';
}
const int base = 1000*1000*1000;
void mulint(vi& a, int b) { //a*= b
for(int i = 0, carry = 0; i < sz(a) || carry; i++) {
if( i == sz(a) )
a.push_back(0);
llong cur = carry + a[i] * 1LL * b;
a[i] = int(cur%base);
carry = int(cur/base);
}
while( sz(a) > 1 && a.back() == 0 )
a.pop_back();
}
int divint(vi& a, int d) { // carry = a%d; a /= d; return carry;
int carry = 0;
for(int i = sz(a)-1; i >= 0; i--) {
llong cur = a[i] + carry * 1LL * base;
a[i] = int(cur/d);
carry = int(cur%d);
}
while( sz(a) > 1 && a.back() == 0 )
a.pop_back();
return carry;
}
void add(vi& a, vi& b) { // a += b
for(int i = 0, c = 0, l = max(sz(a),sz(b)); i < l || c; i++) {
if( i == sz(a) )
a.push_back(0);
a[i] += ((i<sz(b))?b[i]:0) + c;
c = a[i] >= base;
if( c ) a[i] -= base;
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int from, to; cin >> from >> to;
string s; cin >> s;
vi res(1,0); vi m(1,1); vi tmp;
for(int i = sz(s)-1; i >= 0; i--) {
tmp.assign(m.begin(), m.end());
mulint(tmp,DigToNumber(s[i]));
add(res,tmp); mulint(m,from);
}
vi ans;
while( sz(res) > 1 || res.back() != 0 )
ans.push_back(divint(res,to));
if( sz(ans) == 0 )
ans.push_back(0);
for(int i = sz(ans)-1; i >= 0; i--)
cout << NumberToDig(ans[i]);
cout << "\n";
return 0;
}
How "from -> to" works for string "s":
accumulate Big Number (vector< int >) "res" with s[i]*from^(|s|-i-1), i = |s|-1..0
compute digits by dividing "res" by "to" until res > 0 and save them to another vector
send it to output digit-by-digit (you can use ostringstream instead)
PS I've noted that nickname of thread starter is Denis. And I think this link may be useful too.
I am trying to a C++ implementation of this knapsack problem using branch and bounding. There is a Java version on this website here: Implementing branch and bound for knapsack
I'm trying to make my C++ version print out the 90 that it should, however it's not doing that, instead, it's printing out 5.
Does anyone know where and what the problem may be?
#include <queue>
#include <iostream>
using namespace std;
struct node
{
int level;
int profit;
int weight;
int bound;
};
int bound(node u, int n, int W, vector<int> pVa, vector<int> wVa)
{
int j = 0, k = 0;
int totweight = 0;
int result = 0;
if (u.weight >= W)
{
return 0;
}
else
{
result = u.profit;
j = u.level + 1;
totweight = u.weight;
while ((j < n) && (totweight + wVa[j] <= W))
{
totweight = totweight + wVa[j];
result = result + pVa[j];
j++;
}
k = j;
if (k < n)
{
result = result + (W - totweight) * pVa[k]/wVa[k];
}
return result;
}
}
int knapsack(int n, int p[], int w[], int W)
{
queue<node> Q;
node u, v;
vector<int> pV;
vector<int> wV;
Q.empty();
for (int i = 0; i < n; i++)
{
pV.push_back(p[i]);
wV.push_back(w[i]);
}
v.level = -1;
v.profit = 0;
v.weight = 0;
int maxProfit = 0;
//v.bound = bound(v, n, W, pV, wV);
Q.push(v);
while (!Q.empty())
{
v = Q.front();
Q.pop();
if (v.level == -1)
{
u.level = 0;
}
else if (v.level != (n - 1))
{
u.level = v.level + 1;
}
u.weight = v.weight + w[u.level];
u.profit = v.profit + p[u.level];
u.bound = bound(u, n, W, pV, wV);
if (u.weight <= W && u.profit > maxProfit)
{
maxProfit = u.profit;
}
if (u.bound > maxProfit)
{
Q.push(u);
}
u.weight = v.weight;
u.profit = v.profit;
u.bound = bound(u, n, W, pV, wV);
if (u.bound > maxProfit)
{
Q.push(u);
}
}
return maxProfit;
}
int main()
{
int maxProfit;
int n = 4;
int W = 16;
int p[4] = {2, 5, 10, 5};
int w[4] = {40, 30, 50, 10};
cout << knapsack(n, p, w, W) << endl;
system("PAUSE");
}
I think you have put the profit and weight values in the wrong vectors. Change:
int p[4] = {2, 5, 10, 5};
int w[4] = {40, 30, 50, 10};
to:
int w[4] = {2, 5, 10, 5};
int p[4] = {40, 30, 50, 10};
and your program will output 90.
I believe what you are implementing is not a branch & bound algorithm exactly. It is more like an estimation based backtracking if I have to match it with something.
The problem in your algorithm is the data structure that you are using. What you are doing is to simply first push all the first levels, and then to push all second levels, and then to push all third levels to the queue and get them back in their order of insertion. You will get your result but this is simply searching the whole search space.
Instead of poping the elements with their insertion order what you need to do is to branch always on the node which has the highest estimated bound. In other words you are always branching on every node in your way regardless of their estimated bounds. Branch & bound technique gets its speed benefit from branching on only one single node each time which is most probable to lead to the result (has the highest estimated value).
Example : In your first iteration assume that you have found 2 nodes with estimated values
node1: 110
node2: 80
You are pushing them both to your queue. Your queue became "n2-n1-head" In the second iteration you are pushing two more nodes after branching on node1:
node3: 100
node4: 95
and you are adding them to you queue as well("n4-n3-n2-head". There comes the error. In the next iteration what you are going to get will be node2 but instead it should be node3 which has the highest estimated value.
So if I don't miss something in your code both your implementation and the java implementation are wrong. You should rather use a priority queue (heap) to implement a real branch & bound.
You are setting the W to 16, so the result is 5. The only item you can take into the knapsack is item 3 with profit 5 and weight 10.
#include <bits/stdc++.h>
using namespace std;
struct Item
{
float weight;
int value;
};
struct Node
{
int level, profit, bound;
float weight;
};
bool cmp(Item a, Item b)
{
double r1 = (double)a.value / a.weight;
double r2 = (double)b.value / b.weight;
return r1 > r2;
}
int bound(Node u, int n, int W, Item arr[])
{
if (u.weight >= W)
return 0;
int profit_bound = u.profit;
int j = u.level + 1;
int totweight = u.weight;
while ((j < n) && (totweight + arr[j].weight <= W))
{
totweight = totweight + arr[j].weight;
profit_bound = profit_bound + arr[j].value;
j++;
}
if (j < n)
profit_bound = profit_bound + (W - totweight) * arr[j].value /
arr[j].weight;
return profit_bound;
}
int knapsack(int W, Item arr[], int n)
{
sort(arr, arr + n, cmp);
queue<Node> Q;
Node u, v;
u.level = -1;
u.profit = u.weight = 0;
Q.push(u);
int maxProfit = 0;
while (!Q.empty())
{
u = Q.front();
Q.pop();
if (u.level == -1)
v.level = 0;
if (u.level == n-1)
continue;
v.level = u.level + 1;
v.weight = u.weight + arr[v.level].weight;
v.profit = u.profit + arr[v.level].value;
if (v.weight <= W && v.profit > maxProfit)
maxProfit = v.profit;
v.bound = bound(v, n, W, arr);
if (v.bound > maxProfit)
Q.push(v);
v.weight = u.weight;
v.profit = u.profit;
v.bound = bound(v, n, W, arr);
if (v.bound > maxProfit)
Q.push(v);
}
return maxProfit;
}
int main()
{
int W = 55; // Weight of knapsack
Item arr[] = {{10, 60}, {20, 100}, {30, 120}};
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Maximum possible profit = "
<< knapsack(W, arr, n);
return 0;
}
**SEE IF THIS HELPS**
I'm trying to implement Closest pair of points in C++ according to Cormen book and wikipedia article, I think that algorithm is correct, but it does work only for a very small data. Code is below:
#include <cstdio>
#include <algorithm>
#include <cmath>
#define REP(i,n) for(int i=0;i<n;i++)
using namespace std;
struct point
{
long long x, y;
};
struct dist
{
long long x_1,y_1,x_2,y_2, distance;
} dis;
inline bool OrdX(const point &a, const point &b)
{
if(a.x==b.x)
{
return a.y<b.y;
}
return a.x<b.x;
}
inline int OrdY(const point &a, const point &b)
{
if(a.y==b.y)
{
return a.x<b.x;
}
return a.y<b.y;
}
// is - function that check is a an element of X_L array
inline bool is(const point &a, point *X_L, int p, int k)
{
if(p<=k)
{
int center = (p+k)/2;
if(X_L[center].x == a.x)
{
return true;
}
if(X_L[center].x > a.x)
{
return is(a, X_L, p, center-1);
}
else
{
return is(a, X_L, center+1, k);
}
}
return false;
}
// odl - function takes two points and return distance between them ^2
inline long long odl(const point &a, const point &b)
{
return ((a.x-b.x)*(a.x-b.x))+((a.y-b.y)*(a.y-b.y));
}
int tmp;
// fun - function that returns the pair of closest points using divide & conquer
struct dist fun(int n, point *X, point *Y)
{
// if there are less that 4 points - it checks it using bruteforce
if(n<4)
{
if(odl(X[0], X[1]) < dis.distance)
{
dis.distance = odl(X[0],X[1]);
dis.x_1 = X[0].x;
dis.y_1 = X[0].y;
dis.x_2 = X[1].x;
dis.y_2 = X[1].y;
}
if(n==3)
{
if(odl(X[0], X[2]) < dis.distance)
{
dis.distance = odl(X[0],X[2]);
dis.x_1 = X[0].x;
dis.y_1 = X[0].y;
dis.x_2 = X[2].x;
dis.y_2 = X[2].y;
}
if(odl(X[1], X[2]) < dis.distance)
{
dis.distance = odl(X[1],X[2]);
dis.x_1 = X[1].x;
dis.y_1 = X[1].y;
dis.x_2 = X[2].x;
dis.y_2 = X[2].y;
}
}
}
// otherwise it divides points into two arrays and runs fun
// recursively foreach part
else
{
int p=n/2;
int PPP = (X[p].x + X[p-1].x)/2;
point *X_L = new point[p];
point *X_R = new point[n-p];
point *Y_L = new point[p];
point *Y_R = new point[n-p];
REP(i,p)
X_L[i] = X[i];
for(int r=p; r<n; r++)
{
X_R[r-p] = X[r];
}
int length_Y_L = 0;
int length_Y_R = 0;
REP(i,n)
{
if(is(Y[i], X_L, 0, p))
{
Y_L[length_Y_L++] = Y[i];
}
else
{
Y_R[length_Y_R++] = Y[i];
}
}
dist D_L = fun(p, X_L, Y_L);
dist D_R = fun(n-p, X_R, Y_R);
dist D;
if(D_L.distance < D_R.distance)
{
D = D_L;
}
else
{
D = D_R;
}
tmp = 0;
point *Y2 = new point[n];
double from = sqrt((double)D.distance);
for(int r=0; r<n; r++)
{
if(Y[r].x > (long long)PPP-from && Y[r].x < (long long)PPP + from)
{
Y2[tmp++] = Y[r];
}
}
//--tmp;
//int xxx = min(7, tmp-r);
int r = 0;
for(int j=1; j<min(7, tmp-r); j++)
{
if(odl(Y2[r], Y2[r+j]) < D.distance)
{
D.distance = odl(Y2[r], Y2[r+j]);
D.x_1 = Y2[r].x;
D.y_1 = Y2[r].y;
D.x_2 = Y2[r+j].x;
D.y_2 = Y2[r+j].y;
}
r++;
}
dis = D;
}
return dis;
}
int main()
{
int n;
n = 7;
point *X = new point[n];
point *Y = new point[n];
for(int i=0; i< 7; i++)
{
X[i].x = 0;
X[i].y = 10*i;
}
/*
REP(i,n)
{
scanf("%lld %lld", &X[i].x, &X[i].y);
}
*/
sort(X, X+n, OrdX);
REP(i,n)
Y[i] = X[i];
sort(Y, Y+n, OrdY);
dis.distance = odl(X[0], X[1]);
dis.x_1 = X[0].x;
dis.y_1 = X[0].y;
dis.x_2 = X[1].x;
dis.y_2 = X[1].y;
dist wynik = fun(n, X, Y);
printf(" %lld %lld\n %lld %lld\n", wynik.x_1, wynik.y_1, wynik.x_2, wynik.y_2);
return 0;
}
and I get this error:
malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char
*) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct
malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size)
>= (unsigned long)((((__builtin_offsetof (struct malloc_chunk,
fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t)))
- 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end &
pagemask) == 0)' failed.
I've tried loooking for explanation of this error but can't find anything clear for me :/.
Can You please help me to solve this ? Thanks
The message means you've done something bad with dynamically allocated memory. Perhaps you freed an object twice, or wrote into memory beyond the beginning or end of an array-like dynamically allocated object.
On Linux, the tool valgrind may help pin-point the first place in your program's execution where it made a boo-boo.
By the way, your macro:
#define REP(i,n) for(int i=0;i<n;i++)
is poorly defined. The substitution of n should be parenthesized, because n could be an expression which has the wrong precedence with respect to the < operator. For instance: REP(i, k < m ? z : w). You want:
#define REP(var,n) for(int var=0;var<(n);var++)
The var reminds the programmer that this argument is a variable name, and not an arbitrary expression.
Your function is is redundant; that's just std::binary_search. That would help a lot with #sbi's problem of readability.
There's also quite a bit of redundancy in blocks like
dis.distance = odl(X[0],X[1]);
dis.x_1 = X[0].x;
dis.y_1 = X[0].y;
dis.x_2 = X[1].x;
dis.y_2 = X[1].y;
You can write a simple function dist calcDist(point,point) for this. You should probably move all the point definitions and associated functions to a separate header "point.h", again to keep things readable.
As for the memory issue: first, the arrays X_L and X_R are not really necessary. They contain the same data as X, so you can make them pointers to &(X[0]) and &(X[p) respectively. Y_L and Y_R are shuffled versions, so you do need to the arrays to copy data to. However, if you allocate them with new[], you are responsible for cleanup with delete[]. It looks like you can just use a std::vector<point> Y_L instead. No need to do bookkeeping, vector does that for you. Just call Y_L.push_back(Y[i]).