They all do the same thing: they replace each empty string in
a with "EMPTY". (Stylistically, I'd choose the
replace_if version, because the name of the algorithm
communicates most specifically what we're doing: replacing values if some
predicate holds.)
double distance_from_origin(double p[], int n) // Assume p has n elements
{
return sqrt(inner_product(p, p+n, p, 0.0));
}
struct DiffSquared
{
double operator()(double x, double y) const
{ return (x-y)*(x-y); }
};
double dist(double p[], double q[], int n) // Assume p and q have n elements
{
return sqrt(inner_product(p, p+n, q, 0.0, plus<double>(), DiffSquared()));
}
template<typename InIt1, typename InIt2>
int count_matches(InIt1 begin1, InIt1 end1, InIt2 begin2)
{
int n = 0;
for ( ; begin1 != end1; begin1++, begin2++)
{
if (*begin1 == *begin2)
n++;
}
return n;
}
Here's a solution that has no loops, but uses something we hadn't talked about:
#include <numeric> // for inner_product
#include <iterator> // for iterator_traits
#include <functional> // for plus
using namespace std;
template<typename T1, typename T2>
struct Equals
{
bool operator()(const T1& lhs, const T2& rhs) const
{ return lhs == rhs; }
};
template<typename InIt1, typename InIt2>
int count_matches(InIt1 begin1, InIt1 end1, InIt2 begin2)
{
return inner_product(begin1, end1, begin2, 0, plus<int>(),
Equals<typename iterator_traits<InIt1>::value_type,
typename iterator_traits<InIt2>::value_type>());
}
template<typename InIt1, typename InIt2, typename Pred>
int count_matches(InIt1 begin1, InIt1 end1, InIt2 begin2, Pred p)
{
return inner_product(begin1, end1, begin2, 0, plus<int>(), p);
}
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdlib> // for rand
using namespace std;
const size_t TOP_N = 10;
struct Gag
{
Gag(string t, double f) : text(t), funniness(f) {}
string text;
double funniness;
};
bool is_funnier(const Gag& lhs, const Gag& rhs)
{
return lhs.funniness > rhs.funniness;
}
char random_letter()
{
return 'a' + rand() % 26;
}
Gag make_random_gag()
{
string s;
generate_n(back_inserter(s), 6, random_letter);
return Gag(s, (100.0 * rand()) / RAND_MAX);
}
int main()
{
vector<Gag> v;
generate_n(back_inserter(v), 100000, make_random_gag);
partial_sort(v.begin(), v.begin()+TOP_N, v.end(), is_funnier);
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(4);
for (int k = TOP_N; k >= 1; k--)
cout << setw(2) << k << ". " << v[k-1].text << " "
<< v[k-1].funniness << endl;
}
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
#include <iterator>
using namespace std;
int intabs(int k)
{
return k < 0 ? -k : k;
}
int main()
{
int n;
while (cin >> n)
{
vector<int> v;
v.reserve(n); // not necessary, just a minor optimization
string s;
getline(cin,s);
istringstream iss(s);
copy(istream_iterator<int>(iss), istream_iterator<int>(),
back_inserter(v));
adjacent_difference(v.begin(), v.end(), v.begin());
transform(v.begin()+1, v.end(), v.begin()+1, intabs);
sort(v.begin()+1, v.end());
if (n == 1 || (v[1] == 1 && v[n-1] == n-1 &&
adjacent_find(v.begin()+1, v.end(), greater_equal<int>())
== v.end()))
cout << "Jolly";
else
cout << "Not jolly";
cout << endl;
}
}
Of course, while short and sweet, this solution isn't as efficient as it could be: The sort is O(N log N), but we can determine whether a sequence is jolly in linear time. Doing so without writing a loop is not particularly interesting, though, and more trouble than it's worth. Here's one way to do it: Replace the call to sort and the if statement that follows it with
vector<int> seen(n-1); // initialized to zeroes for_each(v.begin()+1, v.end(), RecordOccurrence(seen)); if (find(seen.begin(), seen.end(), 0) == seen.end()) cout << "Jolly"; else cout << "Not jolly"; cout << endl;
where RecordOccurrence is defined as
struct RecordOccurrence
{
RecordOccurrence(vector<int>& vv) : vec(vv) {}
void operator()(int k)
{
if (k >= 1 && k <= vec.size())
vec[k-1] = 1;
}
vector<int>& vec;
};