I have a set of points (x,y,z). I want to sort these data using first column and 2nd and 3rd columns should be rearranged according to the sorting 1st column. is it possible to do this in c++, if so could you pls help me.
Herewith I am attaching codes of my implementation but I got a error message “invalid conversion from ‘const’ vod*’ to ‘const int [*][3]’ “ in line 31 and 32. I tried this using several methods but my effort was not success yet. I used here ‘qsort’ for this, are there any other methods or can I use ‘sort’ in to do this. Since I have a very big data set I wish to use a fast method.
So what I need at the end the data set which is sorted using only 1st column like following example:
before sort
34 12 12
12 34 15
24 20 34
13 11 10
40 23 32
after sort
12 34 15
13 11 10
24 20 34
34 12 12
40 23 32
if any good methods help me to write codes …thanks
#include <iostream>
#include <cstdlib>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
class Point
{
private:
double x;
double y;
double z;
public:
Point(){};
~Point(){};
Point(double X, double Y, double Z){
x=X;y=Y;z=Z; }
double X(){return x;}
double Y(){return y;}
double Z(){return z;}
};
int cmp ( const void *pa, const void *pb ) {
const int (*a)[3] = pa;
const int (*b)[3] = pb;
if ( (*a)[1] < (*b)[1] ) return -1;
if ( (*a)[1] > (*b)[1] ) return +1;
return 0;
}
int main ( ) {
vector<Point> points;
int input_x,input_y,input_z;
int i=0;
while(i<6){//data set,it is a example, actual data come from a file
cout<<"x: ";cin>>input_x;
cout<<"y: ";cin>>input_y;
cout<<"z: ";cin>>input_z;
Point point(input_x,input_y,input_z);
points.push_back(point);
i++;
}
for (int i=0;i<points.size();i++){//before sort
cout<<points[i].X()<<" "<<points[i].Y()<<" "<<points[i].Z()<<endl;
}
qsort( points, 6, sizeof points[0], cmp );
for (int i=0;i<points.size();i++){//after sort
cout<<points[i].X()<<" "<<points[i].Y()<<" "<<points[i].Z()<<endl;
}
system("PAUSE");
return 0;
}
It's almost certainly easiest to use std::sort instead of qsort:
class Point {
int x, y, z;
public:
Point(int x, int y, int z) : x(x), y(y), z(z) {}
bool operator<(Point const &other) {
return x < other.x;
}
// skipping the reading and other stuff for now...
};
int main() {
std::vector<Point> points;
// add some Points to `points` here.
// sort using order defined in Point::operator<:
std::sort(points.begin(), points.end());
return 0;
}
Edit: to keep the comparison separate from the items being compared, you use a separate function or functor to do the comparison, and pass that to std::sort. There are a few things about your class that you really want to change in any case though -- at the very least, since your Point::X(), Point::Y() and Point::Z() don't modify the Point object, you want to make them const member functions. Once you've done that, the sorting is fairly trivial:
#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
class Point {
double x, y, z;
public:
double X() const { return x; }
double Y() const { return y; }
double Z() const { return z; }
Point(double x=0.0, double y=0.0, double z=0.0) : x(x), y(y), z(z) {}
};
namespace std {
ostream &operator<<(ostream &os, Point const &p) {
return os << "(" << p.X() << ", " << p.Y() << ", " << p.Z() << ")";
}
}
struct byX {
bool operator()(Point const &a, Point const &b) {
return a.X() < b.X();
}
};
int main(){
std::vector<Point> points;
for (int i=0; i<10; i++)
points.push_back(Point(rand(), i, i));
std::cout << "Unsorted:\n";
std::copy(points.begin(), points.end(),
std::ostream_iterator<Point>(std::cout, "\n"));
std::sort(points.begin(), points.end(), byX());
std::cout << "\nSorted:\n";
std::copy(points.begin(), points.end(),
std::ostream_iterator<Point>(std::cout, "\n"));
return 0;
}
Technically, I suppose I should add one more minor detail: if the x value in any of your points is a NaN, this won't work correctly. A NaN isn't equal to anything (not even itself) which violates the strict weak ordering required for std::sort.
The arguments of the cmp function are actually const Point *px in your case. You may not be able to declare them as arguments this way, but you can surely cast the void pointers later.
Further reference here.
Related
I implented a contructor for my matrix class to do brace-enclosed initialization using nested std::initializer_list. The constructor works fine for primary type: `int`, `double`; but renders error-reading for `complex`. How to fix this error reading?
The matrix class
template <typename T> class xxx
{
public:
T *ptr;
int col, row, size;
xxx() = delete;
xxx(const int i, const int j):row(i), col(j), size(i*j)
{
ptr = new T [this->size] ;
}
xxx(const std::initializer_list< std::initializer_list<T> > s):xxx(s.size(), s.begin()->size())
{
int j = 0;
for (const auto& i : s) { std::copy (i.begin(), i.end(), ptr + j*col); ++j ; }
}
~xxx() {delete [] this->ptr;}
T operator()(const int i, const int j) const { return ptr[i*col+j]; }
};
A typical ouput overload is added here for complete.
template <typename X> std::ostream& operator<<(std::ostream&p, const xxx<X>&a)
{
for (int i=0; i<a.row; i++) {
for (int j=0; j <a.col; j++) p << std::setw(6) << a(i, j);
p << std::endl;
}
return p;
}
The first test main() with type `double` works well.
#include <iostream>
#include <initializer_list>
#include <iomanip>
#include <complex>
int main()
{
xxx<double> x = {{1, 2,3,4} , {3, 4,5,6}, {5, 6,7,8} };
std::cout << x << std::endl;
}
It prints what is expected:
$ ./a.exe
1 2 3 4
3 4 5 6
5 6 7 8
Then, I try with another type of my interested, `complex`:
int main()
{
xxx< std::complex<double> > z = { {(1,2), (3,4)}, {(5,6), (7,8)} };
std::cout << z << std::endl;
}
The outpur is wrong as follows:
$ ./a.exe
(2,0) (4,0)
(6,0) (8,0)
The imaginery part is missing, and the real parts are taking values of the counter imaginery part. Any idea or suggestion will be highly appreciated.
Your problem is not related to the initializer list. The problem is that this code
#include <iostream>
#include <complex>
int main()
{
std::complex<double> x = (1,2);
std::cout << x;
}
Is not doing what you expect it to do. Output is
(2,0)
Because (1,2) is the comma operator at work. std::complex<double> x = (1,2); is the same as std::complex<double> x = 2;.
You need to use curly braces for initialization:
#include <iostream>
#include <complex>
int main()
{
std::complex<double> x = {1,2};
std::cout << x;
}
Output
(1,2)
PS I would strongly advise you to use a std::vector<T> to hold the data rather than a T*. Currently copying a xxx will cause undefined behavior, due to not following the rule of 3/5.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I need a struct that can hold 3 coordinates as separate variables, but I also need a way to iterate through them. For now, I am doing it like this:
struct Vector3
{
float coords[3];
float& x = coords[0];
float& y = coords[1];
float& z = coords[2];
};
This way I can access each individual variable as well as iterate through all of them using the coords array. Problem is: this is very unefficient, both in memory usage and in performance cost. Is there a better solution?
As suggest (by underscore_d) in a comment the preferred way is to provide accessor functions.
On any realistic compiler they'll be optimised away so no space or performance issue.
struct Vector3 {
float coords[3];
float& x() { return coords[0]; }
float& y() { return coords[1]; }
float& z() { return coords[2]; }
float x() const { return coords[0]; }
float y() const { return coords[1]; }
float z() const { return coords[2]; }
};
Here's a little program that gives it a run out.
#include <iostream>
struct Vector3 {
float coords[3];
float& x() { return coords[0]; }
float& y() { return coords[1]; }
float& z() { return coords[2]; }
float x() const { return coords[0]; }
float y() const { return coords[1]; }
float z() const { return coords[2]; }
};
void dump(const std::string& title,const Vector3& v3){
std::cout << title << '\n';
std::cout << "{ " << v3.coords[0] << " , " << v3.coords[1] << " , " << v3.coords[2] << " }\n";
std::cout << "x=" << v3.x() << " y=" << v3.y() << " z=" << v3.z() << '\n' << std::endl;
}
int main() {
Vector3 v3{};
dump("v3 0:",v3);
v3.x()=7.0f;
v3.y()=3.141f;
v3.z()=276.0f;
dump("v3 1:", v3);
Vector3 v3c{};
dump("v3 c 0:", v3c);
v3c=v3;
dump("v3 c 1:",v3c);
return 0;
}
Don't overlook that the assignment v3c=v3 now works 'out of the box'. Bonus!
The references broke the default assignment operator. References can't be assigned to be references to other things (in this case the coordinate in the other object - as C++ sees it).
I've provided two sets of getters - const and non-const - you may not be managing const-ness.
You mention iteration. If you this to the structure definition:
const float * begin() const { return coords;}
const float * end() const { return coords + 3; /* Yes 3 */}
float * begin() { return coords;}
float * end() { return coords + 3; /* Yes 3 */}
You can use C++ ranged-for loops : for(auto curr : vec ) as well.
This snippet sets all the coords of v3 to 7.0.
for(auto& curr : v3){
curr=7.0f;
}
I also recommend adding a constructor: Vector3():coords{} {} to the struct to initialise all the coordinates to zero. It has a tiny overhead but experience shows its usually the best to avoid 'weird' bugs down the line.
The modern recommendation is to prefer double over float unless you have good reason. I at least recommend creating a master typedef float float_type; and using that consistently in your code. It won't save you any re-engineering but it will reduce the rework if you change take. Also observe "almost always auto".
constexpr float_type zero{0}; may also help.
Expected program output:
v3 0:
{ 0 , 0 , 0 }
x=0 y=0 z=0
v3 1:
{ 7 , 3.141 , 276 }
x=7 y=3.141 z=276
v3 c 0:
{ 0 , 0 , 0 }
x=0 y=0 z=0
v3 c 1:
{ 7 , 3.141 , 276 }
Iterate through variables in a struct c++
There is no standard way to do this.
You could for example implement a custom iterator to do this. However, for random access, an array is likely to produce efficient code.
This way I can access each individual variable as well as iterate through all of them using the coords array. Problem is: this is very unefficient
You don't need the references to access individual elements. This works just fine:
struct Vector3
{
float coords[3];
} v;
v.coords[0] = 42; // access first element
I have made a class called Point which simply contains a tuple of x y coordinates. I also made a vector of the Type Point and added the point (3,4). Now i want to search this vector for the point with binary search, and if it return true then i want to print "yes", to confirm that the point exists in the vector. Unfortunately, the find function doesnt work on a vector of type Point, how can fix this?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Point {
private:
double xval, yval;
public:
// Constructor uses default arguments to allow calling with zero, one,
// or two values.
Point(double x = 0.0, double y = 0.0) {
xval = x;
yval = y;
}
// Extractors.
double x() { return xval; }
double y() { return yval; }
};
int main()
{
vector<Point> points;
points.push_back(Point(3,4));
if (binary_search(points.begin(),points.end(),Point(3,4)))
{cout<<"The point exists"<<endl;}
return 0;
}
Since you have a custom type array, you must define a comparing function in order to tell which criteria should be followed to consider an element greater than the other. There is an example in C++ Reference:
// binary_search example
#include <iostream> // std::cout
#include <algorithm> // std::binary_search, std::sort
#include <vector> // std::vector
bool myfunction (int i,int j) { return (i<j); }
int main () {
int myints[] = {1,2,3,4,5,4,3,2,1};
std::vector<int> v(myints,myints+9); // 1 2 3 4 5 4 3 2 1
// using default comparison:
std::sort (v.begin(), v.end());
std::cout << "looking for a 3... ";
if (std::binary_search (v.begin(), v.end(), 3))
std::cout << "found!\n"; else std::cout << "not found.\n";
// using myfunction as comp:
std::sort (v.begin(), v.end(), myfunction);
std::cout << "looking for a 6... ";
if (std::binary_search (v.begin(), v.end(), 6, myfunction))
std::cout << "found!\n"; else std::cout << "not found.\n";
return 0;
}
The vector should be sorted, and you should provide same comparer to std::binary_search.
either provide
bool operator < (const Point& lhs, const Point& rhs)
{
return std::tuple(lhs.x(), lhs.y()) < std::tuple(rhs.x(), rhs.y());
}
or custom comparer
auto comp = [](const Point& lhs, const Point& rhs){
return std::tuple(lhs.x(), lhs.y()) < std::tuple(rhs.x(), rhs.y());
};
if (binary_search(points.begin(), points.end(), Point(3,4), comp)) {/**/}
The essence of what I want to do is to take two instances of Vector2D and create a third vector that is to be returned and made into the third instance. The problem I am facing is that I am not entirely sure on how to go ahead in doing so. I have tried to find the syntax for sending in instances, if there is such a one, but I have not managed to find anything useful in any of my books.
#include<iostream>
#include<string>
#include<array>
using namespace std;
class vector2D
{
public:
array<float, 2> get()
{
return xy_coord;
}
void set(float x, float y)
{
xy_coord[0] = x;
xy_coord[1] = y;
}
array<float, 2> vectorAdd(a, b)
{
array<float, 2> c;
for (int i = 0; i < 2; i++)
{
c[i] = a[i] + b[i];
}
return c;
}
private:
array<float, 2> xy_coord;
};
int main()
{
string y;
vector2D a, b, c;
array<float, 2> temp;
a.set(2.0, 3.0);
b.set(4.0, 5.0);
temp = c.vectorAdd(a, b);
c.set(temp[0], temp[1]);
getline(cin, y);
}
The idea is to send in the instances a and b to vectorAdd and sum them up and then set c equal to the returned value (I am sure there is a better way to write the code in the main(), but I am not sure how). In short, what would a and b need to be defined as to make this work, assuming it can work at all.
Maybe you could do something like this instead, so you don't have to pass array around:
#include <iostream>
class Vector2D
{
private:
double _x;
double _y;
public:
Vector2D() = delete;
Vector2D(double x, double y) : _x(x), _y(y) {}
double X() const { return _x; }
double Y() const { return _y; }
Vector2D operator+(Vector2D const &v) const
{
return Vector2D(X() + v.X(), Y() + v.Y());
}
};
int main()
{
Vector2D v1(10.0, 20.0);
Vector2D v2(100.0, 200.0);
Vector2D v3 = v1 + v2;
std::cout << v3.X() << " " << v3.Y();
return 0;
}
Prints:
110 220
Do you need to use array<float, 2>? Have you thought of using pair<float, float>?
A lot (all?) of the operations that you have in your Vector2D class come for free with Pair<>.
Then you just create operator+ as others have suggested.
#include <iostream>
#include <utility>
using namespace std;
using Coord = pair<float, float>;
template <typename L, typename R>
Coord operator+(const L& x, const R& y) { return std::make_pair(x.first + y.first, x.second + y.second); }
int main()
{
Coord a { 5.0f, 6.0f };
Coord b { 7.0f, 9.0f };
Coord c = a + b;
std::cout.precision(5);
std::cout << "c= (" << std::fixed << c.first << ", " << c.second << ")" << std::endl;
return 0;
}
Given a vector of coordinates corresponding to city locations on a grid, how can I generate every permutation of these point objects? I suspect there is a problem with using a user-defined class (Point, in my case) with the predefined function next_permutation.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Point
{
public:
double x, y;
Point(int x, int y);
friend ostream& operator<< (ostream &out, const Point &p);
};
Point::Point(int xCoord, int yCoord)
{
x = xCoord;
y = yCoord;
}
ostream& operator<< (ostream &out, const Point &p)
{
out << "(" << p.x << ", " << p.y << ")";
return out;
}
int main()
{
vector<Point> points = { {3,5}, {10,1}, {2,6} };
do
{
for (Point pt : points)
{
cout << pt << " ";
}
cout << endl;
} while (next_permutation(points.begin(), points.end()));
}
A couple of things,
first to use next_permutations the container must be sorted.
second to compare two custom objects for sort and next_permutations, you need to overload the < operator.
something like this should work:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
class Coords
{
public:
int x = 0;
int y = 0;
//This uses a simple lexicographical ordering, modify to suit your needs.
bool operator <( const Coords& rhs )
{
if ( x == rhs.x )
{
return y < rhs.y;
}
else
{
return x < rhs.x;
}
}
};
vector<vector<Coords>> GetPermutaions( vector<Coords>& vec )
{
vector < vector<Coords>> outVal ;
//if you can guarantee vec will be sorted this can be omitted
sort( vec.begin() , vec.end() );
do
{
outVal.emplace_back( vec );
} while ( next_permutation( vec.begin() , vec.end() ) );
return outVal;
}
One thing to remember, this function will leave vec in a sorted state. If you need the original state, create a copy of vec to do the permutations.
Ex snippet:
#include<iostream>
#include<vector>
#include<algorithm>
int main()
{
typedef std::vector<int> V; //<or_any_class>
V v;
for(int i=1;i<=5;++i)
v.push_back(i*10);
do{
std::cout<<v[0]<<" "<<v[1]<<" "<<v[2]<<" "<<v[3]<<" "<<v[4]<<std::endl;
}while(std::next_permutation(v.begin(),v.end()));
return 0;
}