Reputation: 29
I want to check if the input
is equal to any of the options in an array.
How do I do it? Can I do it without using a lot of ||
operators?
//check if any input in herp[] was entered
string input;
string herp[2] = {"Merp", "Derp"}
cin >> input;
if (input == "connect "+herp[0]||"connect "+herp[1]) {
cout << "poopie" << endl;
}
Upvotes: 2
Views: 5200
Reputation: 8357
I came up with a couple approaches,
First, with a custom function,
template<typename ValueType, typename ForwardIterator>
bool is_in(ValueType value, ForwardIterator begin, ForwardIterator end) {
while (begin != end) {
if (value == *(begin ++)) {
return true;
}
}
return false;
}
template<typename ValueType, typename ForwardIterator>
bool is_in(ValueType value, ForwardIterator begin, ForwardIterator end) {
if (begin == end) return false;
return value == *(begin ++) || is_in(value, begin, end);
}
They do basically the same thing, one that does it recursively, another iteratively.
Adding to jrok's answer, this also does the trick, but without lambda.
std::any_of(predicates.begin(), predicates.end(), std::bind(std::equal_to<std::string>(), "dance", std::placeholders::_1));
By using std::bind
we can avoid using an additional lambda.
The last assumes that you have just a few constant predicates,
template<typename Comparable>
bool is_any(Comparable value) {
return false;
}
template<typename ValueType, typename Comparable, typename... Comparables>
bool is_any(ValueType value, Comparable predicate, Comparables... predicates) {
return value == predicate || is_any(value, predicates...);
}
You can just use it like this,
is_any("dance", "apple", "banana", "cat"); // false
Upvotes: 0
Reputation: 825
Solution:
string input;
const int len = 2;
string herp[len] = {"Merp", "Derp"}
cin >> input;
for( int i = 0 ; i < len ; i++){
if(input == herp [i])
cout << "poopie" << endl;
Upvotes: 1
Reputation: 5467
To highlight why jroc's (or Zac's) answer is so powerful, here's how you can use reuse to handle the append, or potentially suffix... Note this is significantly more efficient O(1)
than creating new strings each time by concatenation which render your entire solution down at O(N)
and completely suck.
//this function can either be jroc's first or second variant implementation
bool jroc_find(const std::string& input, std::vector<string> array) { .... };
...
int main(...) {
...
string input, search;
cin >> input;
string prefix("connect _");
if (input.substr(0,prefix.length) != prefix )
return -1; //not found
else
search = input.subst(prefix.length, input.length - prefix.length);
return jroc_find(search, herp);
...
}
Upvotes: 0
Reputation:
Consider replacing your data structure for herp
; use std::set
if you need the strings to be ordered or std::unordered_set
otherwise. Then it's a simple check to see if herp.find(input) != herp.end()
. These data structures will provide you better complexity guarantees for the find operation (logarithmic and constant amortized for std::set
and std::unordered_set
respectively) over using std::find
on an array (linear). However, these details are less important if you don't expect the size of herp
to ever grow beyond 2.
Upvotes: 3
Reputation: 55395
Use std::find
:
#include <algorithm>
if (std::find(std::begin(herp), std::end(herp), input) != std::end(herp)) {
cout << "found it!";
}
Also, in C++11, std::any_of
has been added. You'll need a predicate function, here in a form of a lambda:
if (std::any_of(std::begin(herp), std::end(herp),
[&input](const std::string& str) { return str == input; })) {
cout << "found it!";
}
I'd also suggest that you don't use raw arrays, but std::vector
or std::array
instead. It might not matter if it's in the same function, but when you pass C-arrays around, they decay to pointers and then things quickly get messy.
Upvotes: 12
Reputation: 15872
If you don't need to append anything:
std::string* p = std::find(std::begin(herp), std::end(herp), input);
if (p != std::end(herp))
{
std::cout << *p << std::endl;
}
else
{
std::cout << "Not found" << std::endl;
}
If you do need to append something, there are a lot of different options. One of them:
std::vector<std::string> herps;
std::string myAppend(const std::string& a)
{
return "connect " + a;
}
std::transform(std::begin(herp), std::end(herp), std::back_inserter(herps), myAppend);
std::string* p = std::find(herps.begin(), herps.end(), input);
if (p != herps.end())
{
std::cout << *p << std::endl;
}
else
{
std::cout << "Not found" << std::endl;
}
Upvotes: 2