The following C++ code sorts an array in descending order using qsort:
#include<iostream>
#include<cstdio>
#include <stdlib.h>
using namespace std;
struct player {
double data;
int index;
};
struct player A[] = {{0.690277,0}, {0.517857,1}, {0.780762,2}, {0.0416667,3}, {0.0416667,4}};
int compare (const void * a, const void * b)
{
return ( ((struct player*)b)->data - ((struct player*)a)->data );
}
int main ()
{
int n;
qsort (A, 5, sizeof(struct player), compare);
for (n=0; n<5; n++)
printf ("data=%lf, index=%d\n", A[n].data, A[n].index);
return 0;
}
But I am getting output like this:
data=0.517857, index=1
data=0.780762, index=2
data=0.041667, index=3
data=0.041667, index=4
data=0.690277, index=0
Is there anything wrong in the code?
In compare, you are subtracting two sub-1 doubles and casting them to an int, the result will in most cases be 0. Instead of subtracting you should compare them and return -1/1.
Consider using this compare instead:
int compare (const void * a, const void * b)
{
auto x = reinterpret_cast<const player*>(a);
auto y = reinterpret_cast<const player*>(b);
if(x->data < y->data)
return -1;
if(x->data > y->data)
return 1;
return 0;
}
That said, this style of coding is ancient/deprecated/bad practice.
Consider writing similar to this instead:
#include<iostream>
#include <algorithm>
struct player {
double data;
int index;
bool operator < (const player& p) const
{
return data < p.data;
}
};
auto A = std::vector<player>{
{0.690277,0}, {0.517857,1},
{0.780762,2}, {0.0416667,3}, {0.0416667,4}
};
int main ()
{
std::sort(std::begin(A), std::end(A));
for(const auto& x: A)
std::cout << "data=" << x.data << ", "
<< "index=" << x.index << "\n";
}
Suggested changes:
don't import std names globally
don't mix cstdio and iostreams (only include one of them)
use std::vector or std::array instead of native array
define the sorting order in the interface of the class (bool operator <). (this should also imply that you define the other arithmetic operators - it is good practice and avoids subtle bugs later, but it is not required for this particular implementation to compile and work)
use std::sort instead of qsort
don't use raw pointers (using them like this is a source for bugs)
Related
Disclaimer: this stuff is not my specialty.
I am trying to feed 2 different 3 column 1 row arrays into a linspace function using the NumCPP package, but i'm getting errors such as:
"no instance of function template "nc::linspace" matches the argument list -- argument types are: (float, float, int)" <-- from VSCode intelisense and "error: cannot convert ‘float’ to ‘float**’" when ran in terminal.
the code relating to this error goes as follows:
float** XYZ[3];
float** function(float array_A, float array_B, int C) {
XYZ** = nc::linspace<float**>(array_A, array_B, C);
return XYZ;
};
Towards the end of my code in the main function I define these parameters as:
float array_A [3]= {0,0,0};
float array_B [3]= {0,PI/4,0};
int C = 10000;
I did the same thing with python using numpy's linspace function and has no issues. C++ is tough, so any help is appreciated.
Here is an example of how to do it (without "C" style arrays)
#include <cassert>
#include <iostream>
#include <vector>
#include <NumCpp/Functions/linspace.hpp>
// in C++ std::vector (or std::array) are preferred over manually allocated "C" style arrays.
// this will avoid a lot of issues related to (pointer) type decay in which actual size information
// of arrays is lost, and it will avoid manual memory managment with new/delete.
// pass vector's by const& so they won't be copied
// make number_of_samples a size_t type since it should never be < 0 (which is allowed by int)
auto linspace(const std::vector<double>& arr1, const std::vector<double>& arr2, const std::size_t number_of_samples)
{
std::vector<std::vector<double>> retval;
assert(arr1.size() == arr2.size());
for (std::size_t n = 0; n < arr1.size(); ++n)
{
// linspace documentationhttps://dpilger26.github.io/NumCpp/doxygen/html/namespacenc.html#a672fbcbd2271d5fc58bd1b94750bbdcc
// in C++ linspace only accepts values, not array like stuff.
nc::NdArray<double> sub_result = nc::linspace(arr1[n], arr2[n], static_cast<nc::uint32>(number_of_samples));
// construct a std::vector<double> from nc::NdArray and put it at back of return value
retval.emplace_back(sub_result.begin(), sub_result.end());
}
return retval;
}
int main()
{
// Create two dynamically allocated arrays of doubles
std::vector<double> array_A{ 0.0, 1.0, 2.0 };
std::vector<double> array_B{ 4.0, 5.0, 6.0 };
// do a linspace on them (linespace is what you called function)
const std::size_t number_of_samples = 4;
auto result = linspace(array_A, array_B, number_of_samples);
// and show the output
std::cout << "result of linspace : \n";
for (const auto& arr : result)
{
bool comma = false;
// range based for loop over the result array to display output
for (const auto& value : arr)
{
if (comma) std::cout << ", ";
std::cout << value;
comma = true;
}
std::cout << "\n";
}
return 0;
}
I have a class that stores data and within the class I have an array called 'position' that stores strings of 2 characters. Unfortunately, the amount of 2 character strings it should hold will vary:
class shipStatus
{
public:
char* name;
int x{};
char position[x][2]; // does not work
void setInfo(char name[], int x);
void displayStatus();
};
The setInfo function assigns a numerical value to x, which varies among objects. I would like the value of x to also dictate the length of the character array 'position'.
For example:
if x = 3 then
char position[3][2]; // the length of the second array is always 2
How can I make my code do this? If I try adding a variable as the parameters my code does not compile.
Here is my setInfo function:
void shipStatus::setInfo(char name[], int x)
{
name = name;
x = x;
}
Since this is C++, you should use the C++ facilities that are available to you. In your case, it would be std::string, std::vector, and std::array.
Below is an example using basically what your original shipStatus structure consisted of, and changing it to using the above mentioned constructs:
#include <string>
#include <array>
#include <vector>
#include <iostream>
class shipStatus
{
std::string name; // <-- Replaced char*
std::vector<std::array<char, 2>> position; // <-- A vector of an array that has a size of 2
public:
void setInfo(std::string n, int x);
void displayStatus();
void setPosition(size_t whichItem, char c1, char c2);
size_t getNumPositions() const;
};
void shipStatus::setInfo(std::string n, int x)
{
name = n;
position.resize(x); // <-- All we need to do is resize() to dynamically resize the vector
}
void shipStatus::displayStatus()
{
for (auto& p : position)
std::cout << p[0] << " " << p[1] << "\n";
}
void shipStatus::setPosition(size_t whichItem, char c1, char c2)
{
position[whichItem] = {c1, c2}; // <-- we set one item in the vector, and in
// that item, we set the [0] and [1] characters
}
size_t shipStatus::getNumPositions() const { return position.size(); }
int main()
{
shipStatus sStatus;
sStatus.setInfo("Ship 1", 3);
sStatus.setPosition(0, '4', '2');
sStatus.setPosition(1, 'a', 'b');
sStatus.setPosition(2, 'y', 'z');
std::cout << "Number of positions: " << sStatus.getNumPositions() << "\n";
sStatus.displayStatus();
}
Output:
Number of positions: 3
4 2
a b
y z
Note that we no longer need x as a member, since a std::vector knows its size already by calling the size() member function.
char **position;
position = (char **)malloc(sizeof(char *)*x);
for (int i=0; i<x; ++i)
{
position[i] = (char *)malloc(sizeof(char)*2);
}
This is a classic "C" way of doing it, will work in C++ too.
For a cleaner approach, we should use vectors/lists for this purpose.
So my goal is to read in some data and sort it by population, but I have to use a sort that can accept multiple data types. I was instructed to use a template to do this, but every time I pass the array "results[i].pop" to my bubblesort function I receive the error
no matching function for call to ‘bubblesort(std::string&)’
bubblesort(results[i].pop);"
note: candidate is:
election.cpp:32:3: note: template T bubblesort(T*)
T bubblesort(T ar[])
^
election.cpp:32:3: note: template argument deduction/substitution failed:
election.cpp:106:34: note: cannot convert ‘results[i].election::pop’ (type ‘std::string {aka std::basic_string}’) to type ‘std::basic_string*’
bubblesort(results[i].pop);
Here's the code:
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <fstream>
#include <stdlib.h>
using namespace std;
struct election {
string party;
string state;
string pop;
string reps;
int ratio;
};
template <typename T>
void bubblesort(T ar[])
{
//Bubblesort
int n = 51;
int swaps = 1;
while(swaps)
{
swaps = 0;
for (int i = 0; i < n - 1; i++)
{
if (ar[i] > ar[i + 1])
{
swap(ar[i],ar[i+1]);
swaps = 1;
}
}
}
//End Bubblesort
}
void delete_chars(string & st, string ch)
{
int i = st.find(ch);
while (i > -1)
{
st.replace(i,1,"");
i = st.find(ch);
}
}
int main()
{
int i = 0;
int n = 51;
election results[n];
int population[n];
int electoralVotes[n];
int ratio[n];
string st;
fstream inData;
//Read in Data from Text File
inData.open("electionresults.txt");
//Print Array as is
cout << "Array Printed As is" << endl;
cout << left << setw(10) << "Party" << setw(20) << "State" << setw(20) << "Population" << setw(15) << "Representatives" << endl;
for (int i = 0; i < n; i++)
{
getline(inData,st);
results[i].party = st.substr(0,1);
results[i].state = st.substr(8,14);
results[i].pop = st.substr(24,10);
results[i].reps = st.substr(40,2);
cout << left << setw(10) << results[i].party << setw(20) << results[i].state << setw(20) << results[i].pop << setw(15) << results[i].reps << endl;
}
//Array Sorted by Population
cout << "Array Sorted By Population" << endl;
cout << endl;
cout << endl;
cout << left << setw(10) << "Party" << setw(20) << "State" << setw(20) << "Population" << setw(15) << "Representatives" << endl;
for(int i = 0; i < n; i++){
bubblesort<string>(results[i].pop);
}
For your bubblesort to work, you need to implement the greater than operator(>) for the election struct:
struct election
{
string party;
string state;
string pop;
string reps;
int ratio;
bool operator>( election a)
{
return pop > a.pop;
}
};
Now call the bubblesort by passing the results array:
bubblesort<election>(results);
A side note your function should pass in the size rather than hardcoding the size in the function(void bubblesort(T ar[], int size)). This gives your function much more functionality and adaptability.
The other answer addressed the issue if you only wanted to sort on pop. However, it is a limited solution, and won't address the real issue of sorting on any field (today it's "pop", but what if this isn't the case tomorrow, where you want to sort on "ratio"?). The issue is that you cannot provide more than one operator > to do this and you're basically stuck only sorting on pop.
Another solution is to provide the bubblesort function with an additional template parameter that defines what to do when given two T's, whether one T should be placed before the other T in the sorted array.
#include <functional>
#include <algorithm>
//...
template <typename T, typename cmp>
void bubblesort(T ar[], int n, cmp compare_fn)
{
int swaps = 1;
while (swaps)
{
swaps = 0;
for (int i = 0; i < n - 1; i++)
{
if (!compare_fn(ar[i], ar[i + 1]))
{
std::swap(ar[i], ar[i + 1]);
swaps = 1;
}
}
}
}
// keep our original 2 param bubble sort, but let it call the one above
template <typename T>
void bubblesort(T ar[], int n)
{
// call general version using <
bubblesort(ar, n, std::less<T>());
}
We basically have two functions, where the two parameter bubblesort function calls the general 3 parameter bubblesort version that takes a third parameter, which describes the comparison.
The two parameter version of bubblesort is used when you want to call bubblesort for the "simple" cases, where your items are
In an array and
You can compare T using < and
You want to sort in ascending order (which is why we used < and not > for the general case).
For example, an array of int needs to be sorted, and you simply want to sort it in ascending order:
int someArray[10];
//...
bubblesort<int>(someArray, 10); // sort ascending
However, we don't want to do a "simple" sort on int, or even std::string. We want to sort on election, and not only that, on election.pop.
If you look at the first bubblesort function above, note that we replaced the comparison using > with a call to a function compare_fn. Note that the parameter is defaulted to the std::less function object. This is why the second bubblesort function works for simple types, since std::less uses < to compare.
However, if you tried to call the bubblesort using only two parameters using election, you come across another compiler error, basically stating that election has no operator < to compare with. The solution to that is either
1) to provide such an operator < (similar to the other answer given) to the election struct or
2) Write a custom comparison function.
So let's go over each of these solutions.
Solution 1:
If we use 1), the election struct will look like this:
struct election
{
std::string party;
std::string state;
std::string pop;
std::string reps;
int ratio;
bool operator <(const election& e) const { return pop < e.pop; }
};
int main()
{
//...
bubblesort<election>(results, n);
}
This will now sort on results using pop as the item to sort on due to the operator < defined in election being used by std::less<>.
Here is an example using overloaded < in election
However, this solution has the same issues as the other answer, in that you can only define one operator < that takes a const election& as a parameter. If you wanted to sort on ratio, for example, you're out of luck, or if you want to sort pop in descending order, you're out of luck. This is where option 2) above will be used.
Solution 2:
We can define what we want to sort on, the sort order, etc. by providing a custom comparison function, function object, or lambda function that returns true if the first T should come before the second T that's passed into the comparison function, false otherwise.
Let's try a function:
bool compare_pop(const election& e1, const election& e2)
{
return e1.pop < e2.pop; // if e1.pop comes before e2.pop, return true, else false
}
int main()
{
//...
bubblesort<election>(results, n, compare_pop);
}
What will happen now is that this will call the first version of bubblesort that takes a comparison function as a parameter. The bubblesort template function will now call compare_pop to determine if the items are out of order. If compare_pop returns false the bubblesort function will swap the items, otherwise it will leave them alone.
Here is a live example with an array of 3 elections, sorted on pop
If you wanted to use a lambda function instead of writing another compare function, that will work too:
int main()
{
//...
bubblesort<election>(results, n, [&](const element& e1, const element& e2) { return e1.pop < e2.pop; });
}
The above will do the same thing as the function example, except that you no longer need to write a separate function as the lambda syntax is used as the function.
Example using lambda syntax
So now, what if we want to sort on pop, but descending and not ascending? Simple -- call bubblesort with a different function or lambda:
bool compare_pop_up(const election& e1, const election& e2)
{
return e1.pop > e2.pop; // if e1.pop comes after e2.pop, return true, else false
}
int main()
{
//...
bubblesort<election>(results, n, compare_pop_up);
}
or using lambda:
int main()
{
//...
bubblesort<election>(results, n,
[&](const element&e1, const element& e2)
{ return e1.pop > e2.pop;});
}
and magically, the bubblesort does the job, sorting on pop in descending order.
Here is a live example with an array of 3 elections, sorted on pop, descending
What if you want to sort on ratio? Same thing -- provide a different function or lambda:
bool compare_ratio(const election& e1, const election& e2)
{
return e1.ratio < e2.ratio;
}
int main()
{
//...
bubblesort<election>(results, n, compare_ratio);
}
or using lambda:
int main()
{
//...
bubblesort<election>(results, n,
[&](const element&e1, const element& e2)
{ return e1.ratio < e2.ratio;});
}
This will sort on ratio in ascending order of the ratio.
The other issue with your code is that you are using non-standard C++ syntax in defining your arrays. You're doing this:
election results[n];
This is not standard C++ syntax, as C++ only allows arrays to be created using a compile-time expression to denote the number of items. You're using something called Variable Length Arrays, which is not standard.
Instead, you can use std::vector, which is standard C++.
#include <vector>
//...
std::vector<election> results(n);
//...
bubblesort<election>(results.data(), results.size(), compare_pop)
Consider the following sample code (I actually work with longer binary strings but this is enough to explain the problem):
void enumerateAllSubsets(unsigned char d) {
unsigned char n = 0;
do {
cout<<binaryPrint(n)<<",";
} while ( n = (n - d) & d );
}
The function (due to Knuth) effectively loops through all subsets of a binary string;
For example :
33 = '00100001' in binary and enumerateAllSubsets(33) would produce:
00000000, 00100000, 00000001, 00100001.
I need to write a #define which would make
macroEnumerate(n,33)
cout<<binaryPrint(n)<<",";
behave in a way equivalent to enumerateAllSubsets(33). (well, the order might be rearranged)
Basically i need the ability to perform various operations on subsets of a set.
Doing something similar with for-loops is trivial:
for(int i=0;i < a.size();i++)
foo(a[i]);
can be replaced with:
#define foreach(index,container) for(int index=0;index < container.size();index++)
...
foreach(i,a)
foo(a[i]);
The problem with enumerateAllSubsets() is that the loop body needs to be executed once unconditionally and as a result the do-while cannot be rewritten as for.
I know that the problem can be solved by STL-style templated function and a lambda passed to it (similar to STL for_each function), but some badass #define macro seems like a cleaner solution.
Assuming C++11, define a range object:
#include <iostream>
#include <iterator>
#include <cstdlib>
template <typename T>
class Subsets {
public:
Subsets(T d, T n = 0) : d_(d), n_(n) { }
Subsets begin() const { return *this; }
Subsets end() const { return {0, 0}; }
bool operator!=(Subsets const & i) const { return d_ != i.d_ || n_ != i.n_; }
Subsets & operator++() {
if (!(n_ = (n_ - d_) & d_)) d_ = 0;
return *this;
}
T operator*() const { return n_; }
private:
T d_, n_;
};
template <typename T>
inline Subsets<T> make_subsets(T t) { return Subsets<T>(t); }
int main(int /*argc*/, char * argv[]) {
int d = atoi(argv[1]);
for (auto i : make_subsets(d))
std::cout << i << "\n";
}
I've made it quite general in case you want to work with, e.g., uint64_t.
One option would be to use a for loop that always runs at least once, such as this:
for (bool once = true; once? (once = false, true) : (n = (n - d) & d); )
// loop body
On the first iteration, the once variable gets cleared and the expression evaluates to true, so the loop executes. From that point forward, the actual test-and-step logic controls the loop.
From here, rewriting this to a macro should be a lot easier.
Hope this helps!
You can do a multiline macro that uses an expression, like this:
#define macroenum(n, d, expr ) \
n = 0; \
do { \
(expr); \
} while (n = (n -d) & d) \
; \
int main(int argc, const char* argv[])
{
enumerateAllSubsets(33);
int n;
macroenum(n, 33, cout << n << ",");
}
As others have mentioned this will not be considered very clean by many - amongst other things, it relies on the variable 'n' existing in scope. You may need to wrap expr in another set of parens, but I tested it with g++ and got the same output as enumerateAllSubsets.
It seems like your goal is to be able to do something like enumerateAllSubsets but change the action performed for each iteration.
In C++ you can do this with a function in the header file:
template<typename Func>
inline void enumerateAllSubsets(unsigned char d, Func f)
{
unsigned char n = 0;
do { f(n); } while ( n = (n - d) & d );
}
Sample usage:
enumerateAllSubsets(33, [](auto n) { cout << binaryPrint(n) << ','; } );
I have the following Python snippet that I would like to reproduce using C++:
from itertools import count, imap
source = count(1)
pipe1 = imap(lambda x: 2 * x, source)
pipe2 = imap(lambda x: x + 1, pipe1)
sink = imap(lambda x: 3 * x, pipe2)
for i in sink:
print i
I've heard of Boost Phoenix, but I couldn't find an example of a lazy transform behaving in the same way as Python's imap.
Edit: to clarify my question, the idea is not only to apply functions in sequence using a for, but rather to be able to use algorithms like std::transform on infinite generators. The way the functions are composed (in a more functional language like dialect) is also important, as the next step is function composition.
Update: thanks bradgonesurfing, David Brown, and Xeo for the amazing answers! I chose Xeo's because it's the most concise and it gets me right where I wanted to be, but David's was very important into getting the concepts through. Also, bradgonesurfing's tipped Boost::Range :).
Employing Boost.Range:
int main(){
auto map = boost::adaptors::transformed; // shorten the name
auto sink = generate(1) | map([](int x){ return 2*x; })
| map([](int x){ return x+1; })
| map([](int x){ return 3*x; });
for(auto i : sink)
std::cout << i << "\n";
}
Live example including the generate function.
I think the most idiomatic way to do this in C++ is with iterators. Here is a basic iterator class that takes an iterator and applies a function to its result:
template<class Iterator, class Function>
class LazyIterMap
{
private:
Iterator i;
Function f;
public:
LazyIterMap(Iterator i, Function f) : i(i), f(f) {}
decltype(f(*i)) operator* () { return f(*i); }
void operator++ () { ++i; }
};
template<class Iterator, class Function>
LazyIterMap<Iterator, Function> makeLazyIterMap(Iterator i, Function f)
{
return LazyIterMap<Iterator, Function>(i, f);
}
This is just a basic example and is still incomplete as it has no way to check if you've reached the end of the iterable sequence.
Here's a recreation of your example python code (also defining a simple infinite counter class).
#include <iostream>
class Counter
{
public:
Counter (int start) : value(start) {}
int operator* () { return value; }
void operator++ () { ++value; }
private:
int value;
};
int main(int argc, char const *argv[])
{
Counter source(0);
auto pipe1 = makeLazyIterMap(source, [](int n) { return 2 * n; });
auto pipe2 = makeLazyIterMap(pipe1, [](int n) { return n + 1; });
auto sink = makeLazyIterMap(pipe2, [](int n) { return 3 * n; });
for (int i = 0; i < 10; ++i, ++sink)
{
std::cout << *sink << std::endl;
}
}
Apart from the class definitions (which are just reproducing what the python library functions do), the code is about as long as the python version.
I think the boost::rangex library is what you are looking for. It should work nicely with the new c++lambda syntax.
int pipe1(int val) {
return 2*val;
}
int pipe2(int val) {
return val+1;
}
int sink(int val) {
return val*3;
}
for(int i=0; i < SOME_MAX; ++i)
{
cout << sink(pipe2(pipe1(i))) << endl;
}
I know, it's not quite what you were expecting, but it certainly evaluates at the time you want it to, although not with an iterator iterface. A very related article is this:
Component programming in D
Edit 6/Nov/12:
An alternative, still sticking to bare C++, is to use function pointers and construct your own piping for the above functions (vector of function pointers from SO q: How can I store function pointer in vector?):
typedef std::vector<int (*)(int)> funcVec;
int runPipe(funcVec funcs, int sinkVal) {
int running = sinkVal;
for(funcVec::iterator it = funcs.begin(); it != funcs.end(); ++it) {
running = (*(*it))(running); // not sure of the braces and asterisks here
}
return running;
}
This is intended to run through all the functions in a vector of such and return the resulting value. Then you can:
funcVec funcs;
funcs.pushback(&pipe1);
funcs.pushback(&pipe2);
funcs.pushback(&sink);
for(int i=0; i < SOME_MAX; ++i)
{
cout << runPipe(funcs, i) << endl;
}
Of course you could also construct a wrapper for that via a struct (I would use a closure if C++ did them...):
struct pipeWork {
funcVec funcs;
int run(int i);
};
int pipeWork::run(int i) {
//... guts as runPipe, or keep it separate and call:
return runPipe(funcs, i);
}
// later...
pipeWork kitchen;
kitchen.funcs = someFuncs;
int (*foo) = &kitchen.run();
cout << foo(5) << endl;
Or something like that. Caveat: No idea what this will do if the pointers are passed between threads.
Extra caveat: If you want to do this with varying function interfaces, you will end up having to have a load of void *(void *)(void *) functions so that they can take whatever and emit whatever, or lots of templating to fix the kind of pipe you have. I suppose ideally you'd construct different kinds of pipe for different interfaces between functions, so that a | b | c works even when they are passing different types between them. But I'm going to guess that that's largely what the Boost stuff is doing.
Depending on the simplicity of the functions :
#define pipe1(x) 2*x
#define pipe2(x) pipe1(x)+1
#define sink(x) pipe2(x)*3
int j = 1
while( ++j > 0 )
{
std::cout << sink(j) << std::endl;
}