How to say if something is in something else c++ - c++

I was wondering if there is an easy way to write this if statement in c++.
string c="B";
if(c=="B"||c=="X"||c=="I")
{
//stuff
}
for example,
string c="B";
if(c in {"b","X","I"})
{
//stuff
}

You can use the std:: find function to search your array.Suppose your array is arr=["C","X","I"] :
tofind string c="C"
For example your statement will change to:-
if(find(arr.begin(),arr.end(),c)!=arr.end())
{
//found do something
}
There is no "in" in C++

There is no direct support in language for this, but you can emulate it using function. For example, let us define a function that accept a string and a vector of strings to be compared:
bool in(const std::string& s, std::vector<std::string> v)
{
for (auto&& i : v)
if ( s == i)
return true;
return false;
}
now you can use this function directly in you if statement, using an initilizer list:
int main()
{
std::string c = "B";
if ( in(c, {"C","X","I", "B"}) )
std::cout << "found\n";
else
std::cout << "not found\n";
}

If doing multiple searches, std::set or std::unordered_map (C++11 hash table) will be better performance-wise than linear search through an array with std::find.
std::set<std::string> data_set{"B","X","I"};
//...somewhere else
bool has_c = data_set.count(c)>0;
Both std::set and std::unordered_maphave a count function that makes testing for a value pretty clean looking, i.e. avoiding iterators.
Program
Here's a full working program,
#include <string>
#include <set>
#include <iostream>
using namespace std;
int main()
{
set<string> data_set{"C","X","I"}
//...somewhere else
string c="B";
if( data_set.count(c)>0 )
{
cout << "here\n";
}
else
{
cout << "not\n";
}
}
Don't forget to set C++11 standard when you compile, e.g. g++ -std=c++11 main.cc.

Related

I don't understand why my sort on a string breaks everything

I have the following code:
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
using namespace std;
vector<vector<string>> findAnagrams(vector<string> wordlist) {
vector<vector<string>> result;
unordered_map<string, vector<string>*> indexes;
for (const string& word : wordlist) {
string wordSorted = word;
sort(wordSorted.begin(), wordSorted.end()); // <= This line break everything
auto index = indexes.find(wordSorted);
if (index == indexes.end()) {
vector<string> vec = { word };
result.push_back(vec);
indexes[wordSorted] = &vec;
} else {
index->second->push_back(word);
}
}
return result;
}
int main()
{
vector<string> wordlist = {"eat", "tea", "tan", "ate", "nat", "bat", "test", "estt"};
auto result = findAnagrams(wordlist);
for (const auto& vec : result) {
for (const auto& word : vec) {
cout << word << " ";
}
cout << endl;
}
return 0;
}
This code detects all anagrams in a list of given words.
As my comment says, when I sort wordSorted using std::sort, it breaks everything and my code ends with a bad_alloc. As if the std::sort manipulates the memory outside of wordSorted. If I remove this specific line, the code "works" (the result is obviously wrong, but it does what it should do).
How it is possible? What am I missing?
I'm guessing these lines are the main cause of your problem:
{
vector<string> vec = { word };
result.push_back(vec);
indexes[wordSorted] = &vec;
}
Here you store a pointer to the local variable vec in the indexes map. When the block ends at } the life-time of vec also ends, and the pointer you just stored will become invalid.
Any use of this pointer will lead to undefined behavior.
It seems to me that the solution is to simply not store pointers to the vector (pointers to containers are seldom, if ever, needed), and instead store a copy.

Assign numbers to characters C++

I need a way to assign numbers to letters in C++, for example, '$' would represent the number 1. I obviously need to be able to obtain the number from the character with something like a function, e.g. getNumFromChar('$') would return 1 and getNumFromChar('#') would return 2. Is there an easy and fast way to do this in C++?
The fastest way is to write a 256 entry lookup table, containing the mapped values in the character's ASCII index. This is similar to how isdigit and tolower work, for example:
int getNumFromChar(char c)
{
static const int table[256] = {/* table entries */};
return table[c & 0xff];
}
If you would like to assign the values yourself use a map and store your key to letter combinations. If you are ok with preassigned unique values mapped to each letter, and are only using ASCII characters, then type cast them to integers... ex) std::static_cast< int >('$');
Create a vector std::vector<int> v(256,0); which is indexed by your characters and initially all of their numbers are zeros that you could treat as invalid numbers. Finally assign for each 'numbered' character some number e.g. v['$'] = 1; v['#'] = 2; using a fact that characters are actually integers from 0 to 255.
As pointed out in the comments, you can use a std::map in the following way:
#include <iostream>
#include <map>
#include <cstring>
struct myComp
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}
};
int main()
{
std::map<const char*, int, myComp> test;
test["$"] = 1;
test["#"] = 2;
std::cout << "$ -> " << test["$"] <<"\n";
std::cout << "# -> " << test["#"] <<"\n";
return 0;
}
Live demo here.
Majority of the other answers will work only if you have a maximum of 256 values to be stored. However, using Maps, you can store just any number of elements.
A lot of people are suggesting std::map<char,int>, which is fine and works, but a faster (?) way of doing this with no dependencies is to just use a massive switch statement
int getNumFromChar(char c){
switch(c){
case '$':
return 1;
case '#':
return 2;
//etc
}
return -1; //just in case of error, for style points
}
Depending on how much you care about performance/memory usage and how many case statements you'd have to write, this may or may not be a viable way to do what you want. Just thought I'd throw it out there since at the time of this writing I don't believe anyone has.
EDIT: Also, depending on the frequency of use of each individual character, and if you know the entire mapping before using this function or if you ever change the mapping, a std::map is way better, but I believe this is faster otherwise.
You could do something like this:
#include <map>
#include <iostream>
#include <exception>
typedef std::map<char, int> easymap_type;
class EasyMap {
public:
EasyMap() {}
virtual ~EasyMap() {}
void assign_int_to_char(const int& i, const char& c)
{
_map[c] = i;
}
int get_int_from_char(const char& c) const
{
easymap_type::const_iterator it = _map.find(c);
if (it == _map.end())
{
std::cerr << "EasyMap Error: uninitialized key - '" << c << "'" << std::endl;
throw std::exception();
}
return it->second;
}
private:
easymap_type _map;
};
int main()
{
EasyMap ezmap;
ezmap.assign_int_to_char(42, 'a');
std::cout << "EasyMap[a] = " << ezmap.get_int_from_char('a') << std::endl;
std::cout << "EasyMap[b] = " << ezmap.get_int_from_char('b') << std::endl;
return 0;
}
I handled an uninitizialized key by throwing an exception, but you could do it different ways.
If your compiler support c++11 feature,you can use std::unordered_map as container to store char and double like std::unordered_map<char,double>.
Unordered map is an associative container that contains key-value pairs with unique keys. Search, insertion, and removal of elements have average constant-time complexity.In your problem char is the key and double is your value,char-double must be the key-value stored in container.
There are already a lot of reasonable answers... I prefer the static_cast<int>('#')
And there always has to be the most stupid useless compile time template idea about how to solve a problem.
I know it's stupid, and I'm not good at this kind of things, but here is my shot at it in c++11. Don't take me seriously. I just had to do something dumb.
#include <string>
#include <array>
#include <utility>
#include <iostream>
constexpr uint kNbChars {3};
constexpr std::array<std::pair<char, int>, kNbChars> kCharToInt {
std::make_pair('$', 1)
, std::make_pair('#', 2)
, std::make_pair('#', 3)
};
template <char c>
int getInt()
{
for (auto pair : kCharToInt)
{
if (pair.first == c)
{ return pair.second; }
}
return -1;
}
int main()
{
std::cout << getInt<'#'>() << std::endl;
std::cout << getInt<'g'>() << std::endl;
}
I think you can make getInt() constexpr too in c++14, but I may be wrong and cannot check it right now.
Of course it really is useless since you have to know the letter at compile time, but you could work around that by, well, just not making getInt a template function...

Best way to store mapping from strings to ints, and the other way around at the same time?

Best way to store mapping from strings to ints, and the other way around at the same time?
For example, I have a vector called columnNames, and I would like to
be able to get a column name given its index, that is its position, but then
also given its position I would like to get its name. One way to do this
is to use a map and store column names in order, and this way
I will be able to do what I want, but I wonder if there is a better way?
Depends what you mean by "better". Boost.MultiIndex is a very flexible way do this and other things like it, while Boost.Bimap is more specialized.
For this specific case, you could use a map<string,int> together with a vector<const string*> for the lookup from index to string (because indexes by nature form a contiguous sequence). The pointers in the vector point to keys in the map. This is easiest if you don't modify the columns once they're set up, but even if you do it's possible to update the vector to match.
Not aware of something in C++11 but this might work:
http://www.boost.org/doc/libs/1_46_1/libs/bimap/doc/html/index.html
Boost.Bimap is a bidirectional maps library for C++. With Boost.Bimap
you can create associative containers in which both types can be used
as key. A bimap can be thought of as a combination of a
std::map and a std::map. The learning curve of bimap is
almost flat if you know how to use standard containers. A great deal
of effort has been put into mapping the naming scheme of the STL in
Boost.Bimap. The library is designed to match the common STL
containers.
A (probably worse, O(n) ) solution with lambdas:
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <algorithm>
using namespace std;
map<string, int> m = {{"hello", 1}, {"world", 2}};
int main() {
int findVal = 2;
auto it = find_if(m.begin(), m.end(), [findVal](const pair<string,int> & p) {
return p.second == findVal;
});
if(it != m.end())
cout << it->second << "->" << it->first << "\n";
string findStr = "hello";
auto itStr = find_if(m.begin(), m.end(), [findStr](const pair<string,int> & p) {
return p.first.compare(findStr) == 0;
});
if(itStr != m.end())
cout << itStr->second << "->" << itStr->first << "\n";
return 0;
}
If you're searching for something horribly simple (and probably terribly inefficient too), use this:
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <algorithm>
using namespace std;
map<string, int> m = {{"hello", 1}, {"world", 2}};
class notFound
{ };
string findFromInt(const int& val)
{
map<string,int>::iterator it = m.begin();
while(it != m.end())
{
if(it->second == val)
return it->first;
it++;
}
throw new notFound();
}
int findFromString(const string& str)
{
map<string,int>::iterator it = m.begin();
while(it != m.end())
{
if(it->first.compare(str) == 0)
return it->second;
it++;
}
throw new notFound();
}
int main() {
int findVal = 2;
try {
string str = findFromInt(findVal);
cout << "found: " << str;
} catch(notFound *obj) {
cout << "Value not found";
}
string findStr = "hgggllo";
try {
int val = findFromString(findStr);
cout << "found: " << val;
} catch(notFound *obj) {
cout << "Value not found";
}
return 0;
}
http://ideone.com/2FP64h
In your usecase, I would prefer the method you mention (map + vector) over bi-maps.
Your usecase is special in a way that your ints start at zero and are consecutive.
Your proposed solution is simple, highly efficient (especially hashmap, aka. unordered_map + vector) and does not require any outside library.
You may use a biderectional map, like this one:
boost bimap

Is this a reasonable way to make use of range based for loops?

I was wondering recently what the requirements were for range based for loops in c++11, as I had only ever seen examples of intended usage:
for (auto person : people)
{
cout << person.name << endl;
}
But given that a container need only have begin and end methods, but need not contain anything at all, would the below be considered 'bad practice' in any way? If nothing else, it is a fresh answer if someone asks you for a Fibonacci sequence in an interview!
#include <string>
#include <iostream>
#include <Windows.h>
using namespace std;
struct FibItr
{
FibItr(int cur = 1, int prev = 0) : mCur(cur), mPrev(prev) {}
FibItr & operator++()
{
mCur += mPrev;
mPrev = mCur - mPrev;
return *this;
}
int operator*(){ return mCur; }
bool operator!=(const FibItr & _rhs)
{
return mCur != _rhs.mCur || mPrev != _rhs.mPrev;
}
unsigned int mCur, mPrev;
};
struct Fib
{
FibItr begin() { return FibItr(); }
FibItr end() { return FibItr(0, 0); }
};
int main( int argc, char* argv[] )
{
for (auto num : Fib())
{
cout << num << endl;
Sleep(500);
}
return 0;
}
The question is not really about the auto for-loop but if it is reasonable to implement stranger kind of iterators. While there are corner-cases you can make a perfect good argument for implementing some operations as iterators (memoized fibonacci being a good example).
There are whole libraries devoted to turning iterators in something more, so some other people also think it is a good idea.
As an aside: Implementing an iterator is tricky business, which is why methods like this should be used with care. Boost.Iterator is a good set of helpers that can make that easier.

C++ equivalent of this Python code for dictionaries/lists?

In my Python code I have an issue that I need clarified before I start translating to c++: how to make proper dictionaries/lists that I can use the equivalent of "if var in _" in.
arbitrary example that needs translation:
CONFIRMATION = ('yes', 'yeah', 'yep', 'yesh', 'sure', 'yeppers', 'yup')
DECLINATION = ('no', 'nope', 'too bad', 'nothing')
varResponse = str(input('yes or no question'))
if varResponse in CONFIRMATION:
doSomething()
elif varResponse in DECLINATION:
doSomethingElse()
else:
doAnotherThing()
It's fairly easy to do similar tasks using arrays, like:
if (userDogName == name[0])
execute something;
but what I need is something like:
if (userDogName is one of a population of dog names in a dictionary)
execute something;
You can use the STL container class set. It uses balanced binary trees:
#include <iostream>
#include <set>
#include <string>
int main(int argc, char* argv[])
{
std::set<std::string> set;
std::set<std::string>::const_iterator iter;
set.insert("yes");
set.insert("yeah");
iter = set.find("yess");
if (iter != set.end( ))
{
std::cout << "Found:" << *iter;
}
else
{
std::cout << "Not found!";
}
return 0;
}
C++11 permits a solutions that's very similar to the Python code:
#include <iostream>
#include <set>
#include <string>
using namespace std;
set<string> CONFIRMATION = {"yes", "yeah", "yep", "yesh", "sure", "yeppers", "yup"};
set<string> DECLINATION = {"no", "nope", "too bad", "nothing"};
int main() {
cout << "yes or no question";
string varResponse;
getline(cin, varResponse);
if (CONFIRMATION.find(varResponse) != CONFIRMATION.end()) {
doSomething();
} else if (DECLINATION.find(varResponse) != DECLINATION.end()) {
doSomethingElse();
} else {
doAnotherThing();
}
}
Well, C++ isn't well suited for small throw-off programs, because it doesn't provide much infra-structure. You're meant to create your own infra-structure (such as, well, even just plain sets!) on top of the standard library. Or use some 3rd-party libraries, i.e. your choice.
So while Python comes with batteries included, with C++ there is no strong pressure to accept the particular provided batteries (because there are none), but you have to at least choose batteries.
For just the basic code, the Python snippet
CONFIRMATIONS = ("yes", "yeah", "yep", "yesh", "sure", "yeppers", "yup")
DECLINATIONS = ("no", "nope", "too bad", "nothing")
response = raw_input( "yes or no? " )
if response in CONFIRMATIONS:
pass # doSomething()
elif response in DECLINATIONS:
pass # doSomethingElse()
else:
pass #doAnotherThing()
can look like this in C++:
typedef Set< wstring > Strings;
Strings const confirmations = temp( Strings() )
<< L"yes" << L"yeah" << L"yep" << L"yesh" << L"sure" << L"yeppers" << L"yup";
Strings const declinations = temp( Strings() )
<< L"no" << L"nope" << L"too bad" << L"nothing";
wstring const response = lineFromUser( L"yes or no? " );
if( isIn( confirmations, response ) )
{
// doSomething()
}
else if( isIn( declinations, response ) )
{
// doSomethingElse()
}
else
{
// doAnotherThing()
}
But then, it relies on some infra-structure having been defined, like the Set class:
template< class TpElem >
class Set
{
public:
typedef TpElem Elem;
private:
set<Elem> elems_;
public:
Set& add( Elem const& e )
{
elems_.insert( e );
return *this;
}
friend Set& operator<<( Set& s, Elem const& e )
{
return s.add( e );
}
bool contains( Elem const& e ) const
{
return (elems_.find( e ) != elems_.end());
}
};
template< class Elem >
bool isIn( Set< Elem > const& s, Elem const& e )
{
return s.contains( e );
}
I used an operator<< because still as of 2012 Visual C++ does not support C++11 curly braces list initialization.
Here set is std::set from the standard library.
And, hm, the temp thingy:
template< class T >
T& temp( T&& o ) { return o; }
And, more infra-structure, the lineFromUser function:
wstring lineFromUser( wstring const& prompt )
{
wcout << prompt;
wstring result;
getline( wcin, result )
|| throwX( "lineFromUser: std::getline failed" );
return result;
}
Which, relies on a throwX function:
bool throwX( string const& s ) { throw runtime_error( s ); }
But that's about all, except that you have to put the C++ code I showed first, into some function, say, call that cppMain, and invoke that from your main function (even more infra-structure to define!):
int main()
{
try
{
cppMain();
return EXIT_SUCCESS;
}
catch( exception const& x )
{
wcerr << "!" << x.what() << endl;
}
return EXIT_FAILURE;
}
So, to do things even half-way properly in C++, there is some steep overhead.
C++ is mainly for larger programs, and Python (which I often use) for smallish programs.
And yes, I know that some students may or will react to that statement, either they feel that it's a slur on C++ to say that it's no good for small programs (hey, I make those all the time!) and/or it's a slur on Python to say that it's no good for large systems (hey, haven't you heard of YouTube, you dumb incompetent person?), but, that's the way that it is. Sometimes it can be more convenient to use the hammer one has to fasten a screw, so sometimes I, for example, use C++ to do some small task. But generally that's because it would be too much hassle to install Python on the machine at hand, and in general, to do a task X, it's best to use tools that have been designed for X-like work.
This can be solved using std::find on any Standard Template Library container.
std::vector<std::string> answers;
std::string input;
...
if(std::find(answers.begin(), answers.end(), input) != answers.end()) {
/* input was found in answers */
} else {
/* input was not found in answers */
}
For larger lists, it may be better to store your lists in a std::set object instead, as Tilo suggested. std::find will work the same.