How can you compare words within a string array? - c++

Basically I want to check a string array to see if any of the words match "and".
Is this possible?
Can you push me in the right direction?
Thanks
I should make it clear that the words are char put together best way to explain is an example
abc defg hijk and lmnop <-- each character is in its own element

I recommend you use std::string and not null-terminated char* strings (maybe you already are -- hard to be sure). And use a standard container rather than an array. Then use std::find (which would work on an array too, but containers are better).

Iterate through the array and use int string::compare ( const string& str ) const; to check for matches.
Break from the loop on first match.

I am guessing you'd like to take care of lower\upper casing and the word appearing in the beginning\end of the string.
std::string data;
std::transform(data.begin(), data.end(), data.begin(), ::tolower);
data.append(' ');
if (data.find("and ") != std::string::npos) ......

Related

Delete recurring characters

For a little something I was trying out in C++, I have accepted a string (say 'a tomato is red') and gotten rid of spaces ('atomatoisred').
Now how would I go about deleting recurring characters only, on condition that the first instance of that character gets to stay (so our example becomes,'atomisred')?
Thanks in advance!
You can use the erase-remove idiom in conjunction with a set keeping track of the duplicate characters:
std::set<char> dupes;
str.erase(
std::remove_if(
str.begin(), str.end(),
[&](char c) { return not dupes.insert(c).second; }),
str.end());
This also uses the fact that the return value of std::set::insert is a pair whose second element is a bool indicating whether the insertion took place.
If you want to implement it yourself (without stl), there are a number of ways.
Through sorting. This works if you don't care about the order of the chars. Sort your string first, then go through it, performing a very simple check on every element:
if( currentElement == elemebtBeforeIt )
deleteCurrentElement
Another way is to have an array dedicated to the unique characters (well, maybe not an array, but you'll get the idea). Go through your string, and for each charcter, check:
foreach Element of the string:
if( arrayOfUniqueElements contains currentElement )
do nothing
else
put currentElement into the arrayOfUniquElements
After this, you will have all unique elements in the dedicated array.

Search string for first char different than "X"

The opposite of str.find('X') -
What is the most efficient way of finding first character in std::string that is different than specific char? If I have a string that consists of mainly X'es, but at some point there is another char - how do I find it quickly?
std::string str = "XXXXXXXXXXXXXXX.XXXXXXXXXXX";
size_t index = str.find_first_not_of('X');
But a plain old for loop will be just as good.
Or, if you want an iterator instead of an index, perhaps like this:
std::string::iterator = std::find_if(str.begin(), str.end(),
[](char c){ return c != 'X'; });
I think the most efficient way would be to iterate through the string and compare each character with 'X', returning the first one that is different.
Without any prior knowledge about the string, I don't see an approach better than O(n), and calling find('X') succesively might be worse than just iterating through the characters.

What is the best and fastest way to extract substring from string?

What is the best and most effective way to extract a string from a string? I will need this operation to be preforms thousands of times.
I have this string and I'd like to extract the URL. The URL is always after the "url=" substring until the end of the string. For example:
http://foo.com/fooimage.php?d=AQA4GxxxpcDPnw&w=130&h=130&url=http00253A00252F00252Fi1.img.com00252Fvi00252FpV4Taseyww00252Fhslt.jpg
and I need to extract the
http00253A00252F00252Fi1.img.com00252Fvi00252FpV4Taseyww00252Fhslt.jpg
I want to avoid using split and such.
If you absolutely need the results as a string, you'll have to measure,
but I doubt that anything will be significantly faster than the most
intuitive:
std::string
getTrailer( std::string const& original, std::string const& key )
{
std::string::const_iterator pivot
= std::search( original.begin(), original.end(), key.begin(), key.end() );
return pivot == original.end()
? std::string() // or some error condition...
: std::string( pivot + key.size(), original.end() );
}
However, the fastest way is probably not to extract the string at all,
but to simply keep it as a pair of iterators. If you need this a lot,
it might be worth defining a Substring class which encapsulates this.
(I've found a mutable variant of this to be very effective when
parsing.) If you go this way, don't forget that the iterators will
become invalid if the original string disappears; be sure to convert
anything you want to keep into a string before this occurs.
std::string inStr;
//this step is necessary
size_t pos = inStr.find("url=");
if(pos != std::string::npos){
char const * url = &inStr[pos + 4];
// it is fine to do any read only operations with url
// if you would apply some modifications to url, please make a copy string
}
you can use std::string::find() :
if its a char* than just move the pointer to the position right after "url="
yourstring = (yourstring + yourstring.find("url=")+4 );
I cant think of anything faster..
You could also look into the boost libraries.
For example boost::split()
I don't know how they actually perform in terms of speed, but it's definitely worth a try.

Selectively populated vectors with substrings extracted from a source string

I have a char array, in which its contents look something like the following:
char buffer[] = "I1 I2 V1 V2 I3 V3 I4 DO V4";
As you may see, it's a typical blank separated character string. I want to put all sub-string(s) starting with a letter "I" into a vector (IVector), and sort its elements in ascending order. At the same time, I'd also want to put all sub-string(s) starting with a letter "V" into another vector (VVector), and sort its elements in ascending order. The other(s) (e.g. "DO" in this example) will be ignored.
I'm not familiar with STL algorithm library. Are there any functions to help me achieve the avove-mentioned job?
Thank you!
You can iterate over all the substrings using an std::istream_iterator<std::string>:
std::stringstream s(buffer);
std::istream_iterator<std::string> begin(s);
std::istream_iterator<std::string> end;
for( ; begin != end; ++begin) {
switch((*begin)[0]) { // switch on first character
// insert into appropriate vector here
}
}
Then you can use std::sort to sort the vectors, as #Billy has already pointed out. You could also consider using an std::set, as that will always keep your items sorted in the first place.
Are there any functions to help me achieve the avove-mentioned job?
Yes. Have a look at std::find and std::sort.

C++: Elegant way to split string and stuff contents into std::vector

I would like to split a string along whitespaces, and I know that the tokens
represent valid integers. I would like to transform the tokens into integers
and populate a vector with them.
I could use boost::split, make a vector of token strings, then use std::transform.
What is your solution? Using boost is acceptable.
Something like this:
std::istringstream iss("42 4711 ");
std::vector<int> results( std::istream_iterator<int>(iss)
, std::istream_iterator<int>() );
?
You can use Boost.Tokenizer. It can easily be wrapped up into an explode_string function that takes a string and the delimiter and returns a vector of tokens.
Using transform on the returned vector is a good idea for the transformation from strings to ints; you can also just pass the Boost.Tokenizer iterator into the transform algorithm.
Use Boost's string algorithm library to split the string into a vector of strings, then std::for_each and either atoi or boost::lexical_cast to turn them into ints. It's likely to be far simpler than other methods, but may not have the greatest performance due to the copy (if someone has a way to improve it and remove that, please comment).
std::vector<int> numbers;
void append(std::string part)
{
numbers.push_back(boost::lexical_cast<int>(part));
}
std::string line = "42 4711"; // borrowed from sbi's answer
std::vector<std::string> parts;
split(parts, line, is_any_of(" ,;"));
std::for_each(parts.being(), parts.end(), append);
Roughly.
http://www.boost.org/doc/libs/1_44_0/doc/html/string_algo.html
http://www.boost.org/doc/libs/1_44_0/libs/conversion/lexical_cast.htm
You could always use strtok or string.find().