This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I check whether multiple variables are equal to the same value?
Is there a way to write this:
if ((var1==var2) && (var2==var3) && (var3==var4) ...)
into something like this
if (var1==var2==var3==var4 ...)
?
In C++11, you could write a set of functions like this:
template<typename T>
bool all_equal(T const &)
{
return true;
}
template<typename T, typename U, typename... Args>
bool all_equal(T const & a, U const & b, Args const&... c)
{
return a==b && all_equal(b,c...);
}
int main()
{
std::cout << all_equal(1,2,3) << '\n';
std::cout << all_equal(1,1,1) << '\n';
}
Edit: I guess Steve Jessop had this same idea on the linked duplicate here
Not in a way that's clearer than that, no. You can insert the values in a set for example and check the if size == 1, but what you have now is the way to go.
Essentially, no.
If you have a collection, rather than just sporadic variables, it is possible to apply algorithms to check if they are all equal, which are O(N) if they are all indeed equal (as your long statement is) and will break immediately when it finds one that is not.
Related
Let's assume I have N random access containers (std::vector and std::array for example) of different types, and that all containers have the same length. I want to write to write a function that prints them in a column-ordered fashion, i.e.:
#include <vector>
#include <iostream>
#include <array>
#include <complex>
constexpr int nr=100;
void print(const std::vector<double>& d1, const std::array<std::complex<double>,nr>& b1, const std::vector<int>& b2, const std::array<double,nr>& d2)
{
for(int i=0; i<nr; ++i)
std::cout<<b1[i]<<" "<<d1[i]<<" "<<b2[i]<<" "<<d2[i]<<"\n";
}
Now assuming that all the containers contain the standard numeric types I could write a variadic template function that would look like this:
template<typename... T>
void vprint(T... cs)
{
constexpr int nc=sizeof...(T);
std::vector<std::vector<std::complex<long double>>> v(nr, std::vector<std::complex<long double>>(nc));
//then fill v recursively with all the cs and print it
}
where I used std::complex<long double> since it would contain any possible number.
However this solution is unsatisfactory since I am allocating extra memory, I am converting some integers spoiling the output (and possibly precision), and, finally, the solution does not work if any of the containers contains a printable type that does not convert trivially to a numeric type.
Any idea on how to write a more general solution?
You don't need to create any temporaries. Here's an implementation that requires at least one container to be present, but you can remove that requirement by adding an empty overload:
// Handles empty parameters by doing nothing
void vprint() {}
// Handle non-empty parameters
template<typename T, typename... Ts>
void vprint(const T& front, const Ts&... cs) {
for (int i = 0; i < front.size(); ++i) {
std::cout << front[i];
((std::cout << ' ' << cs[i]), ...);
std::cout << '\n';
}
}
This makes use of C++17 fold expressions to print the ith element of each container, after printing the first one manually. Handling the first one explicitly also ensures we don't print an extra space at the end (or beginning) of each line without branches.
If you don't have access to C++17, it can still be implemented but it'll be a lot uglier than this.
As per Louis' comment, you could also add an assert before the for loop to make sure all the containers have at least front.size() elements in them for safety:
assert(((cs.size() >= front.size()) && ...));
Change the >= to == for strict equality.
Usage:
int main() {
std::array<int, 4> a{1,2,3,4};
std::vector<int> b{5,6,7,8};
vprint(a, b);
}
Prints
1 5
2 6
3 7
4 8
https://godbolt.org/z/z6s34TaT9
This question already has answers here:
Most efficient way to compare a variable to multiple values?
(7 answers)
Closed 2 years ago.
In c++, is there a way to see if a variable is equal to one of the values?
Right now I have to do
if (fExt == "zip" | fExt == "7z" | fExt == "gz" | fExt == "tar")
{
//do something
}
However, is there a more efficient way?
Example with a set:
if (std::set<std::string>{"zip", "7z", "gz", "tar"}.count(fExt)) {
std::cerr << "yes" << std::endl;
}
Note that std::set::count() returns 0 or 1 and provides effectively the same functionality as std::set::contains() which unfortunately is only introduced in C++20.
This is not too bad as it may skip a few comparisons. It will still not be more efficient, given the extra work to setup and teardown the set.
But if your code is called more often, it gets better by re-using the set:
static const std::set<std::string> extensions{"zip", "7z", "gz", "tar"};
if (extensions.count(fExt)) {
std::cerr << "yes" << std::endl;
}
Debatable whether it will be more efficient then doing the four string comparisons but it will probably also not be worse; and it might be easier to maintain.
You could also use an unordered_set, but for a low number of elements like in your case, it will do more unnecessary computation.
If you can use c++17, I would suggest a fold-expression:
template<typename T, typename ...Opts>
bool any_of(T val, Opts ...opts)
{
return (... || (val == opts));
}
which you can then use like this:
if (any_of(fExt, "zip", "7z", "gz", "tar"))
{
// ...
}
You should put this function into your own namespace to avoid any possible confusion with std::any_of from the <algorithm> header.
I want to do an if statement to compare two strings to see if they match.
So:
if (TypedAnswerOne == CorrectAnswerOne)
The code works if the correct answer is typed EXACTLY as it is in the CorrectAnswerOne string value.
No problems at all.
However ... if the answer is typed slightly different as one word in stead of two words for example then it shows that the answer is wrong.
So I was wondering how do I can I do an "OR" with strings?
So:
if (TypedAnswerOne == CorrectAnswerOne or "dirtballs" or "Dirt Balls" or "dirt balls")
How can I define "or" in CPP with strings?
TY :-)
Many programming languages today (C, C++, Swift, C#, Java, JavaScript, PHP) share C's curly-brace syntax and operator syntax.
The syntax for a short-circuited logical OR is a double-pipe: ||.
The syntax for a non-short-circuited logical OR is a single-pipe: | (this is also used for bitwise OR operations).
Also, use && for a short-circuited logical AND and & for non-short-circuited logical AND or bitwise AND.
^ is XOR (and not to-the-power-of).
C++, like these other languages, does not have a built-in feature to let you compare a single left-hand value with multiple right-hand values, so you need to repeat the left-hand value.
Like so:
if( TypedAnswerOne == "dirtballs" || TypedAnswerOne == "Dirt Balls" || TypedAnswerOne
== "dirt balls" )
C and C++ do not support strings in switch statements unlike Java, C#, Swift and PHP, btw.
BTW, you should use a case-insensitive string comparison instead of defining all possible values yourself.
You have to define the OR between cases, not between strings. So, for example:
if (x == "dirtbag" || x == "dirt bag")
You can have as many ORs as you want, but it starts to get messy. When that happens, you might prefer a switch case:
switch(x) {
case "dirtbag" : ...; // do something
case "dirt bag" : ...; // do something
}
If you're open to using pre-existing libraries and don't want to handle all of the cases (it sounds like there could be a lot!) you could always find one that suits your needs and maybe handles the string before comparing (setting it to lowercase, removing whitespace, etc). Good luck!
If you don't care about upper or lower case, or extra whitespace, then you want to first remove all white space and then compare strings on a case-insensitive basis.
You can remove whitespace like this.
Then case-insensitive string compare like this.
In general, the strategy to solving programming problems is to google it. For example:
Google: "c++ remove whitespace from string"
Google: "c++ string compare case insensitive"
For more than a couple of possible values, I tend to put them in a container and use an algorithm:
#include <algorithm>
#include <iterator>
#include <array>
#include <string>
#include <iostream>
template <typename T, std::size_t N, typename U>
bool includes(const std::array<T, N>& arr, const U& value)
{
return std::find(std::cbegin(arr), std::cend(arr), value) != std::cend(arr);
}
struct in_tag {} in;
template <typename U>
struct in_op_temporary { const U& value; };
template <typename U>
in_op_temporary<U> operator<(const U& lhs, in_tag rhs) { return {lhs}; }
template <typename U, typename T, std::size_t N>
bool operator>(in_op_temporary<U> lhs, const std::array<T, N> rhs)
{
return includes(rhs, lhs.value);
}
int main()
{
const std::array<std::string, 3> answers {
"dirtballs", "Dirt Balls", "dirt balls"
};
if ("Dirt Balls" <in> answers)
std::cout << "success!" << std::endl;
if (not ("DirtBalls" <in> answers))
std::cout << "success!" << std::endl;
}
Live On Coliru
But for this particular problem, I'd suggest finding a more general way of accounting for errors in the string.
Not entirely a question, although just something I have been pondering on how to write such code more elegantly by style and at the same time fully making use of the new c++ standard etc. Here is the example
Returning Fibonacci sequence to a container upto N values (for those not mathematically inclined, this is just adding the previous two values with the first two values equal to 1. i.e. 1,1,2,3,5,8,13, ...)
example run from main:
std::vector<double> vec;
running_fibonacci_seq(vec,30000000);
1)
template <typename T, typename INT_TYPE>
void running_fibonacci_seq(T& coll, const INT_TYPE& N)
{
coll.resize(N);
coll[0] = 1;
if (N>1) {
coll[1] = 1;
for (auto pos = coll.begin()+2;
pos != coll.end();
++pos)
{
*pos = *(pos-1) + *(pos-2);
}
}
}
2) the same but using rvalue && instead of & 1.e.
void running_fibonacci_seq(T&& coll, const INT_TYPE& N)
EDIT: as noticed by the users who commented below, the rvalue and lvalue play no role in timing - the speeds were actually the same for reasons discussed in the comments
results for N = 30,000,000
Time taken for &:919.053ms
Time taken for &&: 800.046ms
Firstly I know this really isn't a question as such, but which of these or which is best modern c++ code? with the rvalue reference (&&) it appears that move semantics are in place and no unnecessary copies are being made which makes a small improvement on time (important for me due to future real-time application development). some specific ''questions'' are
a) passing a container (which was vector in my example) to a function as a parameter is NOT an elegant solution on how rvalue should really be used. is this fact true? if so how would rvalue really show it's light in the above example?
b) coll.resize(N); call and the N=1 case, is there a way to avoid these calls so the user is given a simple interface to only use the function without creating size of vector dynamically. Can template metaprogramming be of use here so the vector is allocated with a particular size at compile time? (i.e. running_fibonacci_seq<30000000>) since the numbers can be large is there any need to use template metaprogramming if so can we use this (link) also
c) Is there an even more elegant method? I have a feeling std::transform function could be used by using lambdas e.g.
void running_fibonacci_seq(T&& coll, const INT_TYPE& N)
{
coll.resize(N);
coll[0] = 1;
coll[1] = 1;
std::transform (coll.begin()+2,
coll.end(), // source
coll.begin(), // destination
[????](????) { // lambda as function object
return ????????;
});
}
[1] http://cpptruths.blogspot.co.uk/2011/07/want-speed-use-constexpr-meta.html
Due to "reference collapsing" this code does NOT use an rvalue reference, or move anything:
template <typename T, typename INT_TYPE>
void running_fibonacci_seq(T&& coll, const INT_TYPE& N);
running_fibonacci_seq(vec,30000000);
All of your questions (and the existing comments) become quite meaningless when you recognize this.
Obvious answer:
std::vector<double> running_fibonacci_seq(uint32_t N);
Why ?
Because of const-ness:
std::vector<double> const result = running_fibonacci_seq(....);
Because of easier invariants:
void running_fibonacci_seq(std::vector<double>& t, uint32_t N) {
// Oh, forgot to clear "t"!
t.push_back(1);
...
}
But what of speed ?
There is an optimization called Return Value Optimization that allows the compiler to omit the copy (and build the result directly in the caller's variable) in a number of cases. It is specifically allowed by the C++ Standard even when the copy/move constructors have side effects.
So, why passing "out" parameters ?
you can only have one return value (sigh)
you may wish the reuse the allocated resources (here the memory buffer of t)
Profile this:
#include <vector>
#include <cstddef>
#include <type_traits>
template <typename Container>
Container generate_fibbonacci_sequence(std::size_t N)
{
Container coll;
coll.resize(N);
coll[0] = 1;
if (N>1) {
coll[1] = 1;
for (auto pos = coll.begin()+2;
pos != coll.end();
++pos)
{
*pos = *(pos-1) + *(pos-2);
}
}
return coll;
}
struct fibbo_maker {
std::size_t N;
fibbo_maker(std::size_t n):N(n) {}
template<typename Container>
operator Container() const {
typedef typename std::remove_reference<Container>::type NRContainer;
typedef typename std::decay<NRContainer>::type VContainer;
return generate_fibbonacci_sequence<VContainer>(N);
}
};
fibbo_maker make_fibbonacci_sequence( std::size_t N ) {
return fibbo_maker(N);
}
int main() {
std::vector<double> tmp = make_fibbonacci_sequence(30000000);
}
the fibbo_maker stuff is just me being clever. But it lets me deduce the type of fibbo sequence you want without you having to repeat it.
From time to time I am feeling the need for a certain kind of iterator (for which I can't make up a good name except the one prefixed to the title of this question).
Suppose we have a function (or function object) that maps an integer to type T. That is, we have a definition of a mathematical sequence, but we don't actually have it stored in memory. I want to make an iterator out of it. The iterator class would look something like this:
template <class F, class T>
class sequence_iterator : public std::iterator<...>
{
int i;
F f;
public:
sequence_iterator (F f, int i = 0):f(f), i(i){}
//operators ==, ++, +, -, etc. will compare, increment, etc. the value of i.
T operator*() const
{
return f(i);
}
};
template <class T, class F>
sequence_iterator<F, T> make_sequence_iterator(F f, int i)
{
return sequence_iterator<F, T>(f, i);
}
Maybe I am being naive, but I personally feel that this iterator would be very useful. For example, suppose I have a function that checks whether a number is prime or not. And I want to count the number of primes in the interval [a,b]. I'd do this;
int identity(int i)
{
return i;
}
count_if(make_sequence_iterator<int>(identity, a), make_sequence_iterator<int>(identity, b), isPrime);
Since I have discovered something that would be useful (at least IMHO) I am definitely positive that it exists in boost or the standard library. I just can't find it. So, is there anything like this in boost?. In the very unlikely event that there actually isn't, then I am going to write one - and in this case I'd like to know your opinion whether or not should I make the iterator_category random_access_iterator_tag. My concern is that this isn't a real RAI, because operator* doesn't return a reference.
Thanks in advance for any help.
boost::counting_iterator and boost::transform_iterator should do the trick:
template <typename I, typename F>
boost::transform_iterator<
F,
boost::counting_iterator<I>>
make_sequence_iterator(I i, F f)
{
return boost::make_transform_iterator(
boost::counting_iterator<I>(i), f);
}
Usage:
std::copy(make_sequence_iterator(0, f), make_sequence_iterator(n, f), out);
I would call this an integer mapping iterator, since it maps a function over a subsequence of the integers. And no, I've never encountered this in Boost or in the STL. I'm not sure why that is, since your idea is very similar to the concept of stream iterators, which also generate elements by calling functions.
Whether you want random access iteration is up to you. I'd try building a forward or bidirectional iterator first, since (e.g.) repeated binary searches over a sequence of integers may be faster if they're generated and stored in one go.
Does the boost::transform_iterator fills your needs? there are several useful iterator adaptors in boost, the doc is here.
I think boost::counting_iterator is what you are looking for, or atleast comes the closest. Is there something you are looking for it doesn't provide? One could do, for example:
std::count_if(boost::counting_iterator<int>(0),
boost::counting_iterator<int>(10),
is_prime); // or whatever ...
In short, it is an iterator over a lazy sequence of consecutive values.
Boost.Utility contains a generator iterator adaptor. An example from the documentation:
#include <iostream>
#include <boost/generator_iterator.hpp>
class my_generator
{
public:
typedef int result_type;
my_generator() : state(0) { }
int operator()() { return ++state; }
private:
int state;
};
int main()
{
my_generator gen;
boost::generator_iterator_generator<my_generator>::type it =
boost::make_generator_iterator(gen);
for (int i = 0; i < 10; ++i, ++it)
std::cout << *it << std::endl;
}