1

I would like to know how (if it is even possible) to search from the beginning of a vector up to a specified index if a character exists.

Pseudocode:

vector<char> a{a, b, c, d, e, f, /*...*/};

if (from a.begin() to a[2] b exists) {
... }

What is the most efficient way to do it?

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
iaminsensible
  • 123
  • 1
  • 8
  • 1
    the above does not appear to be valid c++ code, so it will be difficult for anybody to offer assistance – tinkertime Mar 03 '19 at 15:36
  • [this](https://stackoverflow.com/questions/571394/how-to-find-out-if-an-item-is-present-in-a-stdvector) could be of some use to you. – asendjasni Mar 03 '19 at 15:40
  • "Fastest and easiest" rarely go together well. Do you know of any (not fastest or easiest) way of doing this? Perhaps even a way that isn't quite working? If so, add it to the question. For some reason, people are more willing to respond to "fix my code" requests than to "write code for me" requests. – n. m. could be an AI Mar 03 '19 at 15:43
  • I have no idea how to do it, and it doesn't seem like Google has any answers to my question either. That's why I asked here. Also, I removed easiest, as I am not interested in learning the easiest way to write code, but the most efficient. – iaminsensible Mar 03 '19 at 15:44

5 Answers5

5

Algorithms from standard take iterators, not container, so you can use them:

auto it = std::find(a.begin(), a.begin() + 2, 'b');
if (it != a.begin() + 2) {
    // found.
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • I haven't thought about that, at all! I will try to implement it in my code and reply if it doesn't work. – iaminsensible Mar 03 '19 at 15:48
  • 2
    As long as we stick to `std::vector`, `std::any_of` would have same efficiency and be more explicit – R2RT Mar 03 '19 at 15:57
1

With these definitions:

vector<char> a = {'a', 'b', 'c', 'd', 'e', 'f' /*...*/};
char ch = 'x';  

You can easily go for the following, starting after the first char (+1) and ending ignoring the two last elements (-2):

if (any_of(a.cbegin()+1, a.cend()-2, [&ch](auto &x){return x==ch; }))
    cout << "found !"<<endl; 
else cout << "not found! "<<endl; 

You can also use the more classical std::find() in the <algorithm> library:

if (std::find(a.cbegin(), a.cend(), ch) !=a.cend()) 
   ...

If you want to start at a given offset or end ignoring some trailing elements, you can go iterator math on the start or end iterator:

if (std::find(a.cbegin()+3, a.cend(), ch) != a.cend()) 
    ...

If you do this often, and you're not intereste where in the vector the element is found, you could consider the following function:

template <class U, class W> 
bool myfind (const  U &v, size_t starto, size_t endo, const W& x) {
    if (starto>=endo || endo>=v.size())
        return false; 
    return std::find(v.begin()+starto, v.begin()+endo, x) != v.begin()+endo;
}

If you can go for std::string rather than std::vector, you could use the member function find() which can take an offset as argument.

Christophe
  • 68,716
  • 7
  • 72
  • 138
0
#include<vector>
#include<iostream>
using namespace std;
int main(){
     vector<char> A;
     //initialize your vector here
     unsigned i;
     unsigned start, stop;
     //initialize the start and stop here
     for(i=start; i<stop; i++){
         if(A[i]=='b'){
             cout<<"character found!"<<endl;
             break;
         }
     }
}
0

As long as you operate on non-sorted container (std::vector is one) I'd go for std::any_of to express your intention. It will have same efficiency as std::find

#include <vector>
#include <algorithm>

int main()
{
    std::vector<char> a{'a', 'b', 'c', 'd', 'e', 'f'};
    // Checks range between 'b'...'d'
    if (std::any_of(a.begin() + 1, a.end() - 2, [](char c){return c == 'b';})) {
      // do stuff
    }
    return 0;
}
R2RT
  • 2,061
  • 15
  • 25
  • OP wanted _0⇒2_, not _0⇒(n-2)_ – Lightness Races in Orbit Mar 03 '19 at 16:13
  • 1
    What's the `return 10` about? – Lightness Races in Orbit Mar 03 '19 at 16:14
  • Ehm, does it really matter? This is just example usage of `any_of`. I believe OP can adjust it to his needs. – R2RT Mar 03 '19 at 16:43
  • Well, yes, it matters. You're teaching. Why put things in a teaching example that don't make any sense, or that are wrong? – Lightness Races in Orbit Mar 03 '19 at 16:43
  • `contains a specific character within specified indices` - this is what is question about. Not any specific use case read from pseudocode. PS. I've used `return 10` out of curiosity to check whenever gcc will optimize whole call, it does. – R2RT Mar 03 '19 at 16:47
  • Ad. `You're teaching.` added in edit: I am teaching, but I don't have to give him a fish, a rod should be enough. Why wouldn't I provide more generic example to trigger OP to think about iteration calculations, that you can do both `begin() +1` and `end() - 2`, not just exact case which he asked? – R2RT Mar 03 '19 at 16:51
  • All I'm asking is why you gave the wrong solution (2 from end, rather than 2 from beginning) and threw in the highly unusual `return 10` without explaining it. You can fix that quite easily. This has nothing to do with "teach a man to fish", it's more "don't throw a man to the sharks" – Lightness Races in Orbit Mar 03 '19 at 16:54
  • Revenge-downvoting my answer doesn't help either – Lightness Races in Orbit Mar 03 '19 at 16:56
  • I am afraid I am not the downvoter. I don't agree doing `begin() + 1` and `end() - 2` is wrong solution, neither the "shark". I've removed `return 10` if it bothers you so much. – R2RT Mar 03 '19 at 17:00
  • I just wanted you to explain it. Oh well. – Lightness Races in Orbit Mar 03 '19 at 17:00
  • Explanation about "compiler can inline optimize the code I've provided into single assembler call" would be more like shark ;) SO complains already about long discussion, I think we should stop here. – R2RT Mar 03 '19 at 17:02
-1

The others are right that, since algorithms take iterators, you have plenty of flexibility here.

Here's my variant.

I'm sticking with std::find because std::any_of adds complexity without adding clarity.

std::vector<char> a{'a', 'b', 'c', 'd', 'e', 'f', /*...*/};

assert(a.size() >= 2);
const auto start  = a.cbegin();
const auto end    = a.cbegin() + 2;

const char search = 'b';

if (auto it = std::find(start, end, search); it != end)
{
   std::cout << "Found '" << search << "'!\n";
}

(Here's more on the new if construction; fall back on old-school syntax if you're pre-C++17.)

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055