How to check if string is in array of strings [duplicate] - c++

This question already has answers here:
How to check if a string is in a list of strings?
(8 answers)
Closed 11 months ago.
#include <iostream>
#include <string>
using namespace std;
bool in_array(string value, string *array)
{
int size = (*array).size();
for (int i = 0; i < size; i++)
{
if (value == array[i])
{
return true;
}
}
return false;
}
int main() {
string tab[2] = {"sdasd", "sdsdasd"};
string n;
cin >> n;
if (in_array(n, tab)) {
}
return 0;
}
I want to check in C++ if n string is in tab array, but the code return an error.
What I am doing wrong? Maybe I should use the vectors?

int size = (*array).size();
It will not tell you the size of array, it tells you the length of first string in that array, you should pass the length of array to the function separately. The function should look like:
bool in_array(string value, string *array, int length)
 
But a better choice is using std::vector and std::find:
#include <vector>
#include <algorithm>
bool in_array(const std::string &value, const std::vector<std::string> &array)
{
return std::find(array.begin(), array.end(), value) != array.end();
}
and then, you can use it like:
std::vector<std::string> tab {"sdasd", "sdsdasd"};
if (in_array(n, tab))
{
...
}

When passing an array as an argument to a function which takes only a pointer, you can't query the size of the array within the function (since it got converted to a "stupid" pointer to the first element, nothing more). You typically add a "count" parameter to your signature or an "end" iterator instead.
What you're trying to implement is basically std::find. It takes two iterators (begin and end of the sequence) and the element to be found. Simply use this function.
std::find(std::begin(tab), std::end(tab), n);
will return an iterator to the element if it was found, the end iterator otherwise. Checking for equality with the end iterator will tell you if the element was found in the array.
If you don't like the "iterator interface" of the std algorithms, you can achieve your PHP-like signature by wrapping around std::find by using a template function:
template<class Element, class Container>
bool in_array(const Element & element, const Container & container)
{
return std::find(std::begin(container), std::end(container), element)
!= std::end(container);
}
Please note: This answer assumes C++11. If you use an older compiler, it might not work or it only works if you add -std=c++11 to the compiler flags.

masoud answer is correct but it overly complicated. all you need is this.
bool isInVect=false;
isInVect = std::find(vector.begin(), vector.end(), stringToFind) != vector.end();
if (isInVect == true)
{
cout << "Found string in Vector ..." << endl;
}

Related

C++ Find an int in an array

So I've read other Stack posts about this, and they all suggest that I use find. I'm attempting this, but it doesn't work for me.
bool findInArray(int number, int array[]){
// Finds if the number is in the array
bool exists = find(begin(array), end(array), number) != end(array);
return exists;
}
But I keep getting the following error:
error: no matching function for call to ‘begin(int*&)’
It's even the accepted answer here: How can I check if given int exists in array?
You need a template:
template <std::size_t N>
bool findInArray(int number, const int (&array)[N]) {
// Finds if the number is in the array
return std::find(std::begin(array), std::end(array), number) != std::end(array);
}
You also need to pass the array by lvalue, since you cannot pass arrays by prvalue in C++, and instead the array would decay to a pointer to its first element, thereby losing the size information.
In case you do not know template and looking for an other answer to this question, use STL algorithms.
#include<iostream>
#include<algorithm>
bool findInArray(int number, int array[], int size_array){
int* p = std::find(array, array+size_array, number);
if (p != array+size_array) {
return 1;
} else {
return 0;
}
And from main, you can call :
findInArray(5, a, sizeof(a)/sizeof(a[0]));

Map operator < conditions - invalid comparator

I need to check if two substrings are equal while inserting to a map. Here is the code:
class substring {
public:
substring(string* str, int offset, int length) : str(str), offset(offset), length(length) { }
bool operator < (const substring& val) const {
if (str->compare(offset, length, *val.str, val.offset, val.length) == 0) return false;
else return true;
}
int offset, length;
string* str;
};
This class above is a 'key' in my map. Lengths of both substrings are always same. Some of the conditions are wrong, cause it's still yelling 'invalid comparator'.
your if statement in comparation function code is convoluted way to say:
return str->compare(offset, length, *val.str, val.offset, val.length) != 0;
which is incorrect for comparison function that std::map requires. Remember you are implementing less than operator, not equivalence. If you want your substring to be sorted in ascending order use this:
return str->compare(offset, length, *val.str, val.offset, val.length) < 0;
I would recommend using const reference to std::string in you substring class - that will reflect the fact you do not accept nullptr as pointer and show intent that you do not want to change original string through this class and make your code cleaner.

What is wrong with the following code which calculates a sorted array [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Why doesn't it return any value?
Why doesn't it give me the sorted number list back?
I am inputting a string numbers,and what an output of sorted number but again in string.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class SequenceOfNumbers {
public:
vector<string> rearrange(vector<string> sequence) {
int i;
int size = sizeof(sequence);
vector<int> s1;
for (i = 0; i < size; i++) {
s1[i] = stoi(sequence[i]);
}
sort(s1.begin(), s1.end());
for (i = 0; i < size; i++) {
sequence[i] = to_string(s1[i]);
}
return sequence;
}
};
int size=sizeof(sequence);
You probably meant
int size=sequence.size();
which actually returns the number of elements in the std::vector container.
vector <int> s1;
for(i=0;i<size;i++)
{
s1[i]=stoi(sequence[i]);
}
Here the problem is that the vector s1 is initialized as empty, so that you cannot change the i-th value (because it does not exist). Give the std::vector directly the correct size.
vector <int> s1(size);
for(i=0;i<size;i++)
{
s1[i]=stoi(sequence[i]);
}
Here's one problem:
int size = sizeof(sequence);
That gives you the size of the vector<int> class; not the number of elements in this vector object. You want:
size_t size = sequence.size();
Here's another problem:
s1[i]=stoi(sequence[i]);
s1 is empty, so s1[i] is not valid. Instead, you must either:
initialise the vector with the correct size, vector<int> s1(size);, or
use push_back to grow the vector, s1.push_back(stoi(sequence(i));
If you're using push_back, you might like to do s1.reserve(size) first to avoid unnecessary memory allocations.
One elegant solution would be:
vector<string> rearrange(const vector<string>& sequence)
{
vector<string> result = sequence;
std::sort(result.begin(), result.end(), [](string& lhs, string& rhs)
{
return (std::stoi(lhs) < std::stoi(rhs));
});
return result;
}
As you can see, this solution relies on std::sort. The two first parameters are the begin and end iterators of the vector. This third parameter must be a comparator used to determine the sort order (ascending or descending). Here I used a lambda function, but it could be a functor.
return (std::stoi(lhs) < std::stoi(rhs));
Here you compare the left hand-side operand (aka lhs) with the right hand-side operand (aka rhs).
Instead of a lambda expression, you could have used a functor, which is basically a class that implements:
bool operator()(const string& lhs, const string& rhs).
Depending on how big your vector is going to be, you might want to avoid copying the input vector and instead directly sort this vector in-place (remove the const-ness of 'sequence' and apply std::sort to it).

sizeof an array passed as function argument [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
length of array in function argument
Hi am doing homework and I am completly stumped. We were suppose to get every order of a list an array of integers so I wrote this piece of code, based off of my teacher's pseudocode:
void permute(int v[], int curr,char letters[])
{
if(curr >= sizeof(v)/sizeof(int))
{
checkit(v,letters);
}
for(int i = curr; i < sizeof(v)/sizeof(int); i++)
{
swap(i,curr,v);
permute(v,curr + 1,letters);
swap(v[curr],v[i]);
}//for
}//permu
The only thing I am not sure of is if sizeof(v)/sizeof(int) is the right way to go.
sizeof(v)/sizeof(int) is not the way to go. Your function is exactly equivalent to:
void permute(int *v, int curr, char *letters)
{
...
}
i.e. v is not really an array, it's a pointer. You cannot pass arrays in C or C++.
The solution is one of the following (not exhaustive):
add an extra argument that explicitly describes the length of the array
add an extra argument that points at the last element of the array
use a proper container (e.g. std::vector), which you can call size() on
the template solution that #sehe suggests
One of my pet peeves: you can get C++ to deduce the array size for you
template <size_t N>
void permute(int (&v)[N], int curr,char letters[])
{
if(curr >= N)
{
checkit(v,letters);
}
for(int i = curr; i < N; i++)
{
swap(i,curr,v);
permute(v,curr + 1,letters);
swap(v[curr],v[i]);
}//for
}//permu
In addition to Oli's answer: the typical way in C++ is to pass a pointer to the beginning and a pointer to the end of the sequence that you want to permute. By convention the beginning pointer is inclusive, the ending pointer is exclusive.
void permute(int *v, int *begin, int *end, char *letters) {
if (begin == end) {
checkit(v, end, letters);
} else {
...
permute(v, begin + 1, end, letters);
...
}
}

How do I check if a value is contained in a vector? C++ [duplicate]

This question already has answers here:
How to find out if an item is present in a std::vector?
(18 answers)
Closed 12 months ago.
I have a vector that I am trying to perform a contains function on. I am receiving some sort of casting error and I can't piece together a solution. I am also wanting to know whether or not what I am doing is the appropriate way to check if a vector contains a value.
Here is the code:
#include "stdafx.h"
#include <vector>
static void someFunc(double** Y, int length);
static bool contains(double value, std::vector<double> vec);
int main()
{
double doubleArray[] = { 1, 2, 3, 4, 5 };
double *pDoubleArray = doubleArray;
int size = sizeof doubleArray / sizeof doubleArray[0];
someFunc(&pDoubleArray, size);
return 0;
}
static void someFunc(double** Y, int length)
{
std::vector<double> vec();
for(int i = 0; i < 10; i++)
{
//error: 'contains' : cannot convert parameter 2 from 'std::vector<_Ty> (__cdecl *)(void)' to 'std::vector<_Ty>'
if(contains(*(Y[i]), vec))
{
//do something
}
}
}
static bool contains(double value, std::vector<double> vec)
{
for(int i = 0; i < vec.size(); i++)
{
if(vec[i] == value)
{
return true;
}
}
return false;
}
When you declare a variable with it's default constructor, you don't put () after it (although it's optional when you use new to allocate space on the free store). So this line:
std::vector<double> vec();
should become
std::vector<double> vec;
If you leave it as you did, it thinks that line is a function prototype of a function called vec taking no parameters and returning a std::vector<double>, which is why you're getting a compiler error.
And yes, your code for finding an item will work (it's called a linear search). Also if you want to, you can use std::find:
if (std::find(vec.begin(), vec.end(), value) != vec.end())
// found value in vec
If your vector is in sorted order, you can also use binary_search which is much faster than find, and the usage is the same except binary_search returns a bool instead of an iterator (so you don't need to test it against vec.end()). Make sure you include the algorithm header if you use either of these.
std::vector<double> vec();
Oddly, this does not declare a vector using the default constructor. This declares a function taking no arguments and returning a vector. Try this instead:
std::vector<double> vec;
You can use std::find to check an STL datastructure to contain a certain value.