How to think in Python after working in C++? - c++

I'm brand new to Python and trying to learn it by replicating the following C++ function into python
// determines which words in a vector consist of the same letters
// outputs the words with the same letters on the same line
void equivalentWords(vector <string> words, ofstream & outFile) {
outFile << "Equivalent words\n";
// checkedWord is parallel to the words vector. It is
// used to make sure each word is only displayed once.
vector <bool> checkedWord (words.size(), false);
for(int i = 0; i < words.size(); i++) {
if (!checkedWord[i]){
outFile << " ";
for(int j = i; j < words.size(); j++){
if(equivalentWords(words[i], words[j], outFile)) {
outFile << words[j] << " ";
checkedWord[j] = true;
}
}
outFile << "\n";
}
}
}
In my python code (below), rather than having a second vector, I have a list ("words") of lists of a string, a sorted list of the chars in the former string (because strings are immutable), and a bool (that tells if the word has been checked yet). However, I can't figure out how to change a value as you iterate through a list.
for word, s_word, checked in words:
if not checked:
for word1, s_word1, checked1 in words:
if s_word1 == s_word:
checked1 = True # this doesn't work
print word1,
print ""
Any help on doing this or thinking more "Pythony" is appreciated.

Keeping things simple, this is O(N) complexity and should be sufficient if you don't have GBs of word data. Note that set() and dict() basically is a hashed index (free and builtin!).
index = {}
for word, s_word in words:
index[s_word] = index.get(s_word, []) + [word]
for similar_words in index.values():
print ' '.join(similar_words)
Don't know what you are using it for, but it might be of interest to you that in python 2.7 a Counter class was introduced in the collections module.
If you really want to keep your algorithm and update a boolean list (which you don't because that algorithm would do inefficient double loops), you would do it like this:
checked = [False] * len(words)
for i, (word, word_s) in enumerate(words):
if checked[i]:
continue
for j, (other, other_s) in enumerate(words[i:]):
if word_s == other_s:
print other,
checked[i+j] = True
print

I think the word you're looking for is Pythonic, here's a pythonic code sample for what you're tying to do, determine words that are equivalent, where equivalence is determined by having the same set of letters
import collections
def print_equivalent_words(words):
eq_words = defaultdict(list)
for word in words:
eq_words["".join(sorted(set(word)))].append(word)
for k,v in eq_words.items():
print(v)

I generally like catchmeifyoutry's answer, but I would personally tighten it up a bit further as
for word in set(words):
print word
Edit: My answer is a shorter but functionally equivalent form of catchmeifyoutry's original, pre-edited answer.

This is not the best algorithm to solve this problem (it's O(N^2) instead of O(N)), but here's a pythonic version of it. The method I've used is to replace your array of bits with a set that contains words you've already seen.
checked = set()
for i, word in enumerate(words):
if word in checked:
continue
to_output = [word]
for word2 in words[i + 1:]:
if equivalentWords(word, word2):
to_output.append(word2)
checked.add(word2)
print ' '.join(to_output)

Make words a list of objects:
class Word(object):
def __init__(self, word, s_word, checked=False):
self.word = word
self.s_word = s_word
self.checked = checked
....
for word1 in words:
if word1.s_word == word.s_word:
word1.checked = True
print word1.word
print

Based on the comment:
// determines which words in a vector consist of the same letters
// outputs the words with the same letters on the same line
I'm not quite sure that the original code works, and even if it does, I can't say I like it much. First of all, based on the loop nesting, it looks like the complexity is O(N2). Second, I can't figure out what it's doing well enough to be sure it really does what's stated above (it uses a three-parameter overload of equivalentWords, which seems to be missing, which makes it hard to say though).
Some of the Python solutions are a lot shorter and simpler -- to the point that I feel reasonably certain they simply don't work. A couple seem to simply print out unique words, which (at least as I interpret it) is not the intent at all.
Here's a version in C++ that does what I interpret the requirements to be:
#include <string>
#include <set>
#include <vector>
#include <algorithm>
#include <iostream>
#include <map>
std::string
sort_word(std::string word) {
std::sort(word.begin(), word.end());
return word;
}
namespace std {
std::ostream &
operator<<(std::ostream &os,
std::pair<std::string, std::set<std::string> >const &words)
{
std::copy(words.second.begin(), words.second.end(),
std::ostream_iterator<std::string>(os, "\t"));
return os;
}
}
void
equivalentWords(std::vector<std::string> const &words, std::ostream &os) {
typedef std::map<std::string, std::set<std::string> > word_list_t;
word_list_t word_list;
for (int i=0; i<words.size(); i++)
word_list[sort_word(words[i])].insert(words[i]);
std::copy(word_list.begin(), word_list.end(),
std::ostream_iterator<word_list_t::value_type>(os, "\n"));
}
int
main() {
std::vector<std::string> input;
std::copy(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::back_inserter(input));
equivalentWords(input, std::cout);
return 0;
}
I think using that as a starting point for a Python version is more likely to produce a clean, working result.

I wouldn't say this is pythonic, but I'm quite proud of it.
import itertools
for _, to_output in itertools.groupby(sorted(words, key=sorted), sorted):
print ' '.join(to_output)

Related

C++ - checking a string for all values in an array

I have some parsed text from the Vision API, and I'm filtering it using keywords, like so:
if (finalTextRaw.find("File") != finalTextRaw.npos)
{
LogMsg("Found Menubar");
}
E.g., if the keyword "File" is found anywhere within the string finalTextRaw, then the function is interrupted and a log message is printed.
This method is very reliable. But I've inefficiently just made a bunch of if-else-if statements in this fashion, and as I'm finding more words that need filtering, I'd rather be a little more efficient. Instead, I'm now getting a string from a config file, and then parsing that string into an array:
string filterWords = GetApp()->GetFilter();
std::replace(filterWords.begin(), filterWords.end(), ',', ' '); ///replace ',' with ' '
vector<int> array;
stringstream ss(filterWords);
int temp;
while (ss >> temp)
array.push_back(temp); ///create an array of filtered words
And I'd like to have just one if statement for checking that string against the array, instead of many of them for checking the string against each keyword I'm having to manually specify in the code. Something like this:
if (finalTextRaw.find(array) != finalTextRaw.npos)
{
LogMsg("Found filtered word");
}
Of course, that syntax doesn't work, and it's surely more complicated than that, but hopefully you get the idea: if any words from my array appear anywhere in that string, that string should be ignored and a log message printed instead.
Any ideas how I might fashion such a function? I'm guessing it's going to necessitate some kind of loop.
Borrowing from Thomas's answer, a ranged for loop offers a neat solution:
for (const auto &word : words)
{
if (finalTextRaw.find(word) != std::string::npos)
{
// word is found.
// do stuff here or call a function.
break; // stop the loop.
}
}
As pointed out by Thomas, the most efficient way is to split both texts into a list of words. Then use std::set_intersection to find occurrences in both lists. You can use std::vector as long it is sorted. You end up with O(n*log(n)) (with n = max words), rather than O(n*m).
Split sentences to words:
auto split(std::string_view sentence) {
auto result = std::vector<std::string>{};
auto stream = std::istringstream{sentence.data()};
std::copy(std::istream_iterator<std::string>(stream),
std::istream_iterator<std::string>(), std::back_inserter(result));
return result;
}
Find words existing in both lists. This only works for sorted lists (like sets or manually sorted vectors).
auto intersect(std::vector<std::string> a, std::vector<std::string> b) {
std::sort(a.begin(), a.end());
std::sort(b.begin(), b.end());
auto result = std::vector<std::string>{};
std::set_intersection(std::move_iterator{a.begin()},
std::move_iterator{a.end()},
b.cbegin(), b.cend(),
std::back_inserter(result));
return result;
}
Example of how to use.
int main() {
const auto result = intersect(split("hello my name is mister raw"),
split("this is the final raw text"));
for (const auto& word: result) {
// do something with word
}
}
Note that this makes sense when working with large or undefined number of words. If you know the limits, you might want to use easier solutions (provided by other answers).
You could use a fundamental, brute force, loop:
unsigned int quantity_words = array.size();
for (unsigned int i = 0; i < quantity_words; ++i)
{
std::string word = array[i];
if (finalTextRaw.find(word) != std::string::npos)
{
// word is found.
// do stuff here or call a function.
break; // stop the loop.
}
}
The above loop takes each word in the array and searches the finalTextRaw for the word.
There are better methods using some std algorithms. I'll leave that for other answers.
Edit 1: maps and association
The above code is bothering me because there are too many passes through the finalTextRaw string.
Here's another idea:
Create a std::set using the words in finalTextRaw.
For each word in your array, check for existence in the set.
This reduces the quantity of searches (it's like searching a tree).
You should also investigate creating a set of the words in array and finding the intersection between the two sets.

Replacing N-level for loops with recursion in C++

I have been trying for some time now to come up with a way to compute all the various combinations of strings of words for some time now. Unlike most methods for combining on the web though, the algorithm must produce every combination, including those in which all the combined elements aren't in a single combination. ie, if I am combining 'Hello', 'New' and 'World', the combinations I am looking for are:
HelloNewWorld
HelloNew
HelloWorld
Hello
NewWorld
New
World
A professor from my college did come up with a quick and dirty solution for doing just that, but it is using nested for loops.
#include <iostream>
#include <vector>
#include <array>
#include <string>
int main()
{
std::vector<std::array<std::string, 2>> vec(3);
vec[0] = {"Hello", ""};
vec[1] = {"New", ""};
vec[2] = {"World", ""};
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
for (int k = 0; k < 2; k++)
std::cout << vec[0][i] + vec[1][j] + vec[2][k] << std::endl;
}
As you might imagine, I desired a way to make this actually somewhat usable and portable. I know that this is possible with recursion, I just don't know how to implement it. Optimally, I would like to make this tail-recursive if at all possible, as the plan is to compute very large combinations. What would be the best way to do this recursively, and would it be easy to make tail-recursive?
At each level it recurses both with and without the current word printing the result when it gets to the end of all the words:
#include <iostream>
#include <string>
#include <vector>
void recurse(std::vector<std::string> &values,size_t level,std::string str) {
if (level<values.size()) {
recurse(values,level+1,str+values[level]);
recurse(values,level+1,str);
} else {
std::cout<<str<<"\n";
}
}
int main(int argc, char*argv[]) {
if (argc<2)
std::cout<<argv[0]<<" <word> [<word> [...]]\n";
else {
std::vector<std::string> values;
for(int i=1;i<argc;++i) {
values.push_back(argv[i]);
}
recurse(values,0,"");
}
return 0;
}
Which, when run with ./a.out Hello New World produces:
HelloNewWorld
HelloNew
HelloWorld
Hello
NewWorld
New
World
You can do this pretty efficiently by using all combinations from k=1 to k=N for a vector of N elements. Using Howard Hinnant's library available here, you can use it fairly effectively. In my case, I've named the library sampling.h, which is the only external dependency and can be viewed in it's entirety here.
#include "sampling.h"
#include <iostream>
#include <vector>
/**
* This function can take any container that has a bidirectional
* iterator (std::list, std::deque, std::vector) that contains elements
* of type std::string or similar, that must implement an `operator+`
* and `operator<<` for printing.
*/
template <typename BiDirStringContainer>
void print_combinations(BiDirStringContainer& container)
{
auto first = container.begin();
auto last = container.end();
for (size_t i = 1; i <= container.size(); ++i) {
auto mid = first + i;
for_each_combination(first, mid, last, [](auto f, auto l) {
std::string w;
for (; f != l; ++f) {
w += *f;
}
std::cout << w << std::endl;
return false;
});
}
}
int main(void)
{
std::vector<std::string> words = {
"Hello",
"New",
"World",
};
print_combinations(words);
return 0;
}
Compiling this with the C++14 standard and running it outputs:
Hello
New
World
HelloNew
HelloWorld
NewWorld
HelloNewWorld
This is exactly what your post described. Since the lambda is a custom functor, and can store state, you can do whatever you would like with the combinations: store a copy, print them, etc.
This is dramatically faster than anything you can get in the standard library without major work, or from suggestions made for the standard library. For example, std::next_combination and std::next_permutation (the former was not included, but was suggested here). I highly suggest reading Howard Hinnant's entirely blog post: it is enlightening. The time complexity on his implementations, and brute speed beats most other suggestions. If you need high performance combinations or permutations, he's already done the work for you.
If i understand this correctly you want to generate all combinations of a string. in that case you can use a BFS along with a set and a queue to generate the combinations, I will try to explain.
Say your string is ABCD. You have a queue to which you add ABCD and a set to which you add ABCD now
while the queue is not empty
1) you pop the top element
2) you generate substrings of that popped element
a) if that substring is not in the set add it to the queue
to generate substrings in step 2 you do the following
for(int i =0;i<string.length();i++)
{
string substr1 = string.substr(0,i);
string substr2 = string.substr(i,string.length()-1);
string substring = substr1+substr2;
}
doing this on ABCD(the input string) will generate BCD,ACD and ABD and ABC. now add those 3 to the set and the queue
now, you add BCD,ACD and ABD to the set. Lets say BCD is queue.front(). You pop that and generate CD,BD and BC and add them to the set and queue. when you pop ACD next, you generate CD,AD and AC but now you wont add CD to the queue because it is in the set.
EDIT:
I see your issue, my answer works for a string but you can use the same principle on a vector<string> to generate all combinations ABCD would just beHello(A)World(B)...
If the only possibilities is for a word to appear or not appear, that makes two possibilities. So for n words you have 2^n combinations. So you just count through the 2^n numbers from 0 (including) to 2^n-1 (including) and map each bit to one word.
No recursion needed, just one counting for loop.

How to cut off parts of a string, which every string in a collection has

My currently problem is the following:
I have a std::vector of full path names to files.
Now i want to cut off the common prefix of all string.
Example
If I have these 3 strings in the vector:
/home/user/foo.txt
/home/user/bar.txt
/home/baz.txt
I would like to cut off /home/ from every string in the vector.
Question
Is there any method to achieve this in general?
I want an algorithm that drops the common prefix of all string.
I currently only have an idea which solves this problem in O(n m) with n strings and m is the longest string length, by just going through every string with every other string char by char.
Is there a faster or more elegant way solving this?
This can be done entirely with std:: algorithms.
synopsis:
sort the input range if not already sorted. The first and last paths in the sorted range
will be the most dissimilar. Best case is O(N), worst case O(N + N.logN)
use std::mismatch to determine the larges common sequence between the
two most dissimilar paths [insignificant]
run through each path erasing the first COUNT characters where COUNT is the number of characters in the longest common sequence. O (N)
Best case time complexity: O(2N), worst case O(2N + N.logN) (can someone check that?)
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
std::string common_substring(const std::string& l, const std::string& r)
{
return std::string(l.begin(),
std::mismatch(l.begin(), l.end(),
r.begin(), r.end()).first);
}
std::string mutating_common_substring(std::vector<std::string>& range)
{
if (range.empty())
return std::string();
else
{
if (not std::is_sorted(range.begin(), range.end()))
std::sort(range.begin(), range.end());
return common_substring(range.front(), range.back());
}
}
std::vector<std::string> chop(std::vector<std::string> samples)
{
auto str = mutating_common_substring(samples);
for (auto& s : samples)
{
s.erase(s.begin(), std::next(s.begin(), str.size()));
}
return samples;
}
int main()
{
std::vector<std::string> samples = {
"/home/user/foo.txt",
"/home/user/bar.txt",
"/home/baz.txt"
};
samples = chop(std::move(samples));
for (auto& s : samples)
{
std::cout << s << std::endl;
}
}
expected:
baz.txt
user/bar.txt
user/foo.txt
Here's an alternate `common_substring' which does not require a sort. time complexity is in theory O(N) but whether it's faster in practice you'd have to check:
std::string common_substring(const std::vector<std::string>& range)
{
if (range.empty())
{
return {};
}
return std::accumulate(std::next(range.begin(), 1), range.end(), range.front(),
[](auto const& best, const auto& sample)
{
return common_substring(best, sample);
});
}
update:
Elegance aside, this is probably the fastest way since it avoids any memory allocations, performing all transformations in-place. For most architectures and sample sizes, this will matter more than any other performance consideration.
#include <iostream>
#include <vector>
#include <string>
void reduce_to_common(std::string& best, const std::string& sample)
{
best.erase(std::mismatch(best.begin(), best.end(),
sample.begin(), sample.end()).first,
best.end());
}
void remove_common_prefix(std::vector<std::string>& range)
{
if (range.size())
{
auto iter = range.begin();
auto best = *iter;
for ( ; ++iter != range.end() ; )
{
reduce_to_common(best, *iter);
}
auto prefix_length = best.size();
for (auto& s : range)
{
s.erase(s.begin(), std::next(s.begin(), prefix_length));
}
}
}
int main()
{
std::vector<std::string> samples = {
"/home/user/foo.txt",
"/home/user/bar.txt",
"/home/baz.txt"
};
remove_common_prefix(samples);
for (auto& s : samples)
{
std::cout << s << std::endl;
}
}
You have to search every string in the list. However you don't need to compare all the characters in every string. The common prefix can only get shorter, so you only need to compare with "the common prefix so far". I don't think this changes the big-O complexity - but it will make quite a difference to the actual speed.
Also, these look like file names. Are they sorted (bearing in mind that many filesystems tend to return things in sorted order)? If so, you only need to consider the first and last elements. If they are probably pr mostly ordered, then consider the common prefix of the first and last, and then iterate through all the other strings shortening the prefix further as necessary.
You just have to iterate over every string. You can only avoid iterating over the full length of strings needlessly by exploiting the fact, that the prefix can only shorten:
#include <iostream>
#include <string>
#include <vector>
std::string common_prefix(const std::vector<std::string> &ss) {
if (ss.empty())
// no prefix
return "";
std::string prefix = ss[0];
for (size_t i = 1; i < ss.size(); i++) {
size_t c = 0; // index after which the string differ
for (; c < prefix.length(); c++) {
if (prefix[c] != ss[i][c]) {
// strings differ from character c on
break;
}
}
if (c == 0)
// no common prefix
return "";
// the prefix is only up to character c-1, so resize prefix
prefix.resize(c);
}
return prefix;
}
void strip_common_prefix(std::vector<std::string> &ss) {
std::string prefix = common_prefix(ss);
if (prefix.empty())
// no common prefix, nothing to do
return;
// drop the common part, which are always the first prefix.length() characters
for (std::string &s: ss) {
s = s.substr(prefix.length());
}
}
int main()
{
std::vector<std::string> ss { "/home/user/foo.txt", "/home/user/bar.txt", "/home/baz.txt"};
strip_common_prefix(ss);
for (std::string &s: ss)
std::cout << s << "\n";
}
Drawing from the hints of Martin Bonner's answer, you may implement a more efficient algorithm if you have more prior knowledge on your input.
In particular, if you know your input is sorted, it suffices to compare the first and last strings (see Richard's answer).
i - Find the file which has the least folder depth (i.e. baz.txt) - it's root path is home
ii - Then go through the other strings to see if they start with that root.
iii - If so then remove root from all the strings.
Start with std::size_t index=0;. Scan the list to see if characters at that index match (note: past the end does not match). If it does, advance index and repeat.
When done, index will have the value of the length of the prefix.
At this point, I'd advise you to write or find a string_view type. If you do, simply create a string_view for each of your strings str with start/end of index, str.size().
Overall cost: O(|prefix|*N+N), which is also the cost to confirm that your answer is correct.
If you don't want to write a string_view, simply call str.erase(str.begin(), str.begin()+index) on each str in your vector.
Overall cost is O(|total string length|+N). The prefix has to be visited in order to confirm it, then the tail of the string has to be rewritten.
Now the cost of the breadth-first is locality, as you are touching memory all over the place. It will probably be more efficient in practice to do it in chunks, where you scan the first K strings up to length Q and find the common prefix, then chain that common prefix plus the next block. This won't change the O-notation, but will improve locality of memory reference.
for(vector<string>::iterator itr=V.begin(); itr!=V.end(); ++itr)
itr->erase(0,6);

My program that is supposed to get rid of characters that are not numbers doesn't fully work, any ideas on what I'm doing wrong? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I tried to make a program that is supposed to take user input and then go through the input and remove all of the characters in the string that are not numbers and then print the string after the characters have been removed. I believe that my code is correct, but it doesn't seem to completely do the job, mainly the last character in the string. I think my problem is in the code that checks each character, as it seems to be leaving some characters out. Here's my code:
#include <string>
#include <iostream>
using namespace std;
string separate(string inString){
string numbers = "1234567890";
string oString = "";
int k;
for(k=0; k<inString.size()-1; k++){
if ((numbers.find(inString[k]) == string::npos) && (numbers.find(inString[k+1]) != string::npos) && !isspace(inString[k+1])){
oString += inString.substr(k,1) = "";
}
else if ((numbers.find(inString[k]) != string::npos) && (numbers.find(inString[k+1]) == string::npos) && !isspace(inString[k+1])){
oString += inString.substr(k,1);
}
else if (isspace(inString[k+1])){
oString += inString.substr(k,1) = "";
oString += inString.substr(k,1);
}
else oString += inString.substr(k,1);
}
oString += inString.substr(k,1);
return oString;
}
int main(){
string mystr;
cin >> mystr;
cout << separate(mystr) << endl;
}
Thanks for any help that you guys could give me. I'm new to C++, so any help is good.
You tagged this as C++, so let's use it. The std::string class has an erase method. Using that and the std::remove_if algorithm is all you need. This is known as the remove / erase idiom.
#include <algorithm>
#include <cctype>
#include <string>
//...
string separate(string inString)
{
// move all the erased items to end of the string, and point to where
// the erased items are.
auto iterToErasedItems = std::remove_if(inString.begin(), inString.end(), [] (char ch) { return !::isdigit(ch); });
// now erase them.
inString.erase(iterToErasedItems, inString.end());
// return the string.
return inString;
}
Live Example
The std::remove_if is an algorithm function that goes through the sequence and "removes" the item that matches the criteria given in the third argument. The criteria happens to be everything that is not a digit (the ::isdigit helps us here).
Note that the items are not physically removed, just placed at the tail end of the sequence. The remove_if returns the iterator to where the removed items start, so we need to do some clean up work by calling string::erase() to physically remove the characters. Done.
The other good thing about this approach is that this is 99% boilerplate code to erase any character from a string that matches a certain criteria. All you need to do is change the third argument to remove_if to either a function pointer, functor, or a lambda that returns true if the character is to be erased, false otherwise.
For example:
#include <algorithm>
#include <cctype>
#include <string>
//...
string separate(string inString)
{
// remove any 'a' characters from the string
auto iterToErasedItems = std::remove_if(inString.begin(), inString.end(),
[](char ch) { return ch == 'a'; });
// now erase them.
inString.erase(iterToErasedItems, inString.end());
// return the string.
return inString;
}
Edit: Your post wanted to remove everything that is not a number, so the requisite changes have been made.
Well, I think you can use recursion rather than for loops.
Recursion is a method that is extensively used in functional language like Haskell.
I have written a solution in Haskell:
delete [] x = []
delete (y:ys) x = if x == y
then delete ys x
else y:delete ys x
-- from Set Theory e.g. A \ B
difference xs [] = xs
difference xs (y:ys) = difference (delete y xs) ys
main = do putStrLn (difference "a1b2b3" "123456789")
The code in c++ is more complex.
Also, just as in functional programming, try to use functions whenever possible to make your code more neat.
This line
for(k=0; k<inString.size()-1; k++){
Should be:
for(k=0; k<inString.size(); k++){
Let's say your string is "14u3j".
The size of this string is 5.
with inString.size() - 1 you would iterate the first 4 characters in the string (0, 1, 2, 3) and would not iterate through the last one.
This is a common mistake in programming referred to as off-by-one-error, where you accidentally iterate a loop one extra time or, as in your case, one time less.
Edit
As pointed out by #Alex, this will give you an error in this part of the code.
numbers.find(inString[k+1]
I suggest you check #nshtc's answer for a more comprehensive algorithm.
I'll leave this answer here just because of the explanation about why, in your algorithm, the last character is not being iterated.

how to search for a string in a string array in c++

say i have the following:
string myArray[] = { "adam", "aaron", "brad", "brandon" };
cout << "Please type a name: ";
i want it so when a user types "bra" and hits enter, the program returns
brad
brandon
if the user types "a", the program returns
adam
aaron
if the user types "adam", the program returns
adam
I have tried strstr, mystring.compare(str), mystring.compare(x, n, str) - i can't find anything that is working.
what function would be the best way of handling this operation?
This is a great time for lambdas and std::copy_if. Assuming the string you want to find is named to_find:
std::copy_if(std::begin(myArray), std::end(myArray),
std::ostream_iterator<std::string>(std::cout, "\n"),
[&](const std::string& s){
return s.find(to_find) == 0;
});
Specifically, the way to test if some string a contains another string b, we can do:
a.find(b) == 0
std::string::find returns the index at which b is found, or npos if it's not found. We want 0, since you only want prefixes. We then wrap that in a lambda and pass it into copy_if, which will copy every element which passes our predicate and writes it to the output iterator we provide - in this case an ostream_iterator<std::string> which writes to std::cout and uses \n' as a delimeter.
To write out the same without C+11 would look something like:
const size_t size = sizeof(myArray) / sizeof(*myArray);
for (size_t i = 0; i < size; ++i) {
if (myArray[i].find(to_find) == 0) {
std::cout << myArray[i] << std::endl;
}
}
Depending on how big your list of names is going to be, it can quickly become very slow to scan through the whole thing. You might want to look into implementing your own prefix tree (aka trie).