Digits, not numbers. The any_of() looks at single characters in the string. So does find_first_of() too:
1 2 3 4 5 6 7 8 9 10 11
int main () {
std::string foo( "There are 42 numbers." );
if ( std::any_of( foo.begin(), foo.end(), [](char x){return ('2'==x) || ('3'==x);}) )
std::cout << "The string contains at least one 2 or 3.\n";
if ( std::string::npos != foo.find_first_of("23") )
std::cout << "The string contains at least one 2 or 3.\n";
return 0;
}
andy1992,
Do I really need to create struct/class for this purpose?
keskiverto,
Thank you.
Is there any way to modify this function to check if there is at least one 2 and at least one 3?
so that when you run the above lambda it will expand to form a class object similar to my struct /class at runtime, in other words lambdas are class whose implementation is concealed.
andy1992,
Got it. Thank you.
Another question: How could I find how many times one string is contained in another?
keskiverto,
I meant using any_of. I suppose this is wrong: return ('2' == x) && ('3' == x)
bool isitmagic(const string& temp)
{
//check if string contains all the special digits
if (string::npos != temp.find('0') && string::npos != temp.find('4') && string::npos != temp.find('9'))
{
//run a for loop to check if the string contains only the special digits
//(maybe there is an easier way to do this?)
for (int i = 0; i < temp.length(); i++)
{
if (temp[i] != '0' && temp[i] != '4' && temp[i] != '9')
{
returnfalse;
}
}
returntrue;
}
elsereturnfalse;
}
int main()
{
vector<longlong>numbers;
int counter = 0;
for (int i = 70; counter<=25; i++)
{
longlong tempint = i;
tempint *= tempint;
string temp = to_string(tempint);
if (isitmagic(temp))
{
numbers.push_back(i);
counter++;
}
}
This example works, though a bit slowly. It is supposed to be working with for (int i = 70; counter<=250; i++)
I guess it does but I'm not passionate enough to wait it.
You could check it with
1 2 3 4
for (int i = 0; i < numbers.size(); i++)
{
cout << numbers[i] << " ";
}
Note: your checkprint loop does use numbers.size(), but in your search you have an additional "counter". Do you realize that the counter is always equal to numbers.size() and therefore unnecessary?
Another notes:
* The i starts from 70. No two-digit number can contain three digits, which is the requirement for magic.
* All numbers in range [100..999] must have exactly one of each (0,4,9) and the first digit cannot be 0.
* You don't need to convert to a string. An integer can be dissected with / and % too.
Note: your checkprint loop does use numbers.size(), but in your search you have an additional "counter". Do you realize that the counter is always equal to numbers.size() and therefore unnecessary?
So: for (int i = 70; numbers.size()<=25; i++)
Right?
* The i starts from 70. No two-digit number can contain three digits, which is the requirement for magic.
Nope. It starts from 70 because I know 70 is the 1st one. 70^2 is supposed to be the magic.
Look: tempint *= tempint;
Here:
#include <cmath>
#include <vector>
#include <string>
#include <iostream>
#include <chrono>
using std::string;
usingnamespace std::chrono;
bool isitmagic( const string& temp )
{
if ( string::npos != temp.find('0') &&
string::npos != temp.find('4') &&
string::npos != temp.find('9') )
{
return ( string::npos == temp.find_first_not_of( "049" ) );
}
elsereturnfalse;
}
void span( const size_t n, const steady_clock::time_point & t1 )
{
const steady_clock::time_point t2 = steady_clock::now();
const duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
std::cout << "First " << n << " took " << time_span.count() << " seconds.\n";
}
int main()
{
constexprunsignedlonglong up = sqrt( std::numeric_limits<unsignedlonglong>::max() );
const steady_clock::time_point t1 = steady_clock::now();
constexpr size_t N { 43 };
std::vector<unsignedlonglong> numbers;
numbers.reserve( N );
for ( size_t num = 70; numbers.size() < N; ++num )
{
if ( up < num ) break; // ULL cannot store the square
constunsignedlonglong square = num * num;
if ( isitmagic( std::to_string( square ) ) )
{
numbers.push_back( num );
// std::cout << "num " << num << " square " << square << '\n';
if ( 0 == numbers.size() % 10 )
{
span( numbers.size(), t1 );
}
}
}
/*
for ( auto x : numbers )
{
std::cout << x << ' ';
}
std::cout << '\n';
*/
span( numbers.size(), t1 );
return 0;
}
First 10 took 0.00337088 seconds.
First 20 took 0.0607799 seconds.
First 30 took 0.404953 seconds.
First 40 took 1.83948 seconds.
First 43 took 3.8895 seconds.
The timings are quite consistent on repeated runs, but the cpp.sh will not give output, when 43 < N. (Probably an ulimit on process CPU-time.)
As you can see, the time goes up very quickly. You should time a non-string method to find out whether it is faster/slower.