2

In c++ I have an array and I am trying to check if there is a certain element in the array. Here is my array:

string choices[3] = {"a", "b", "c"}

I want it so that it prints out true if the user input is present in the array so if the user enters "b" then it will print true and give me the array index. This is like the Python version of in or find. I know I can just use a for loop to go over all the elements, but is there a more efficient way? Thanks.

3
  • 1
    Have a look at std::find. Commented Feb 17, 2014 at 13:33
  • 2
    There's nothing more efficient than a loop (unless the array is sorted or otherwise structured to help searching); but there are algorithms like std::find which might be neater than a loop. Commented Feb 17, 2014 at 13:34
  • I don't think you want to have an array of strings. Because you are getting all the disadvantages of an array without any of the advantages since the strings still need to be copied and runtime constructed. Either use array of const char pointers to get efficiency or vector of strings to get safety and convenience. Commented Feb 17, 2014 at 13:40

4 Answers 4

2

To find index you can use the following code:

int x = std::distance(choices, std::find(choices, choices + 3, "b"));

here, distance and find method can be found in <algorithm> header.

Sign up to request clarification or add additional context in comments.

2 Comments

Template argument deduction will fail for this example because of mismatched types. You need to use choices + 0 instead of choices.
I prefer std::begin(choices) and std::end(choices). Note that if x equals the size of choices, choices does not contain "b"
1

You can use standard algorithm std::find declared in header <algorithm> It resolves two tasks. It can say whether a string is present in a container and it can provide the index of the first found element.

If you need only to determine whether a string is present in a container you can use standard algorithm std::any_of

The both algorithms have linear complexity.

If a container (for example an array) is ordered then you can use standard algorithm std::binary_search to determine whether a string is present in the container.

An example that demonstrates the usage of standard algorithm std::find

#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>
#include <iterator>

int main()
{
   std::string choices[] = { "a", "b", "c" };

   std::cout << "Enter a string: ";

   std::string s;
   std::cin >> s;

   auto it = std::find( std::begin( choices ), std::end( choices ), s );

   bool in_array = it != std::end( choices );

   std::cout << "String "\" << s << "\" is present in the array = " 
             << std::boolalpha << in_array << std::endl;
   if ( in_array ) 
   {
      std::cout << "It is " << std::distance( std::begin( choices ), it ) 
                << " element in the array" << std::endl;
   }
}

If you need a more complex condition searching an element in a container you can use standard algorithm std::find_if that accepts a predicate as an argument.

Comments

0

std::find returns an iterator to the element in the array if it's found or the end iterator otherwise:

auto const last = std::end(choices);
auto const pos = std::find(std::begin(choices), end, "b");
if (last != pos) {
    // Use pos here.
}

If you don't need to do anything with the element then you can use any_of:

if (std::any_of(std::begin(choices), std::end(choices),
                [](std::string const& s) { return "b" == s; })
{
    // "b" is in the array.
}

Both of these functions are just loops internally, they won't be any quicker than a hand written loop. If your array is sorted then you can use std::lower_bound instead of std::find and std::binary_search instead of std::any_of.

Comments

0

There is no more efficient way unless the items are somehow ordered. Consider that the element you want to find could, theoretically, be at any index, including the last index that you would check.

If you want to find it efficiently, use std::set. Then you can use set::count(item) > 0 to decide if item is in the set.

Also, in python, it effectively does a loop over all elements when you test whether an item is in a list item in [itemA, itemB, itemC] or in a tuple item in (itemA, itemB, itemC). It is only when you use python's set and frozenset that this search is very fast.

I would recommend using the function std::find if you don't want to write the O(n) loop yourself, and using the std::set class if you want faster lookup.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.