Sorensen–Dice coefficient: Difference between revisions
Content added Content deleted
(J second draft) |
(Added C++ solution) |
||
Line 43: | Line 43: | ||
If there is a built-in or easily, freely available library implementation for Sørensen–Dice coefficient calculations it is acceptable to use that with a pointer to where it may be obtained. |
If there is a built-in or easily, freely available library implementation for Sørensen–Dice coefficient calculations it is acceptable to use that with a pointer to where it may be obtained. |
||
=={{header|C++}}== |
|||
{{trans|Wren}} |
|||
<syntaxhighlight lang="cpp">#include <algorithm> |
|||
#include <cctype> |
|||
#include <cstdlib> |
|||
#include <fstream> |
|||
#include <iostream> |
|||
#include <iterator> |
|||
#include <set> |
|||
#include <sstream> |
|||
#include <string> |
|||
#include <vector> |
|||
std::multiset<std::string> split(const std::string& phrase) { |
|||
std::multiset<std::string> result; |
|||
std::istringstream is(phrase); |
|||
std::string word; |
|||
while (is >> word) { |
|||
for (char& ch : word) { |
|||
ch = std::tolower(static_cast<unsigned char>(ch)); |
|||
} |
|||
size_t length = word.size(); |
|||
if (length == 1) { |
|||
result.emplace(1, word[0]); |
|||
} else { |
|||
for (size_t i = 0; i + 1 < length; ++i) { |
|||
result.insert(std::string{word[i], word[i + 1]}); |
|||
} |
|||
} |
|||
} |
|||
return result; |
|||
} |
|||
double sorensen(const std::string& s1, const std::string& s2) { |
|||
auto a = split(s1); |
|||
auto b = split(s2); |
|||
std::multiset<std::string> c; |
|||
std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), |
|||
std::inserter(c, c.begin())); |
|||
return (2.0 * c.size()) / (a.size() + b.size()); |
|||
} |
|||
int main() { |
|||
std::vector<std::string> tasks; |
|||
std::ifstream is("tasks.txt"); |
|||
if (!is) { |
|||
std::cerr << "Cannot open tasks file.\n"; |
|||
return EXIT_FAILURE; |
|||
} |
|||
std::string task; |
|||
while (getline(is, task)) { |
|||
tasks.push_back(task); |
|||
} |
|||
const size_t tc = tasks.size(); |
|||
const std::string tests[] = {"Primordial primes", |
|||
"Sunkist-Giuliani formula", |
|||
"Sieve of Euripides", "Chowder numbers"}; |
|||
std::vector<std::pair<double, size_t>> sdi(tc); |
|||
std::cout << std::fixed; |
|||
for (const std::string& test : tests) { |
|||
for (size_t i = 0; i != tc; ++i) { |
|||
sdi[i] = std::make_pair(sorensen(tasks[i], test), i); |
|||
} |
|||
std::partial_sort(sdi.begin(), sdi.begin() + 5, sdi.end(), |
|||
[](const std::pair<double, size_t>& a, |
|||
const std::pair<double, size_t>& b) { |
|||
return a.first > b.first; |
|||
}); |
|||
std::cout << test << " >\n"; |
|||
for (size_t i = 0; i < 5 && i < tc; ++i) { |
|||
std::cout << " " << sdi[i].first << ' ' << tasks[sdi[i].second] |
|||
<< '\n'; |
|||
} |
|||
std::cout << '\n'; |
|||
} |
|||
return EXIT_SUCCESS; |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Primordial primes > |
|||
0.685714 Sequence of primorial primes |
|||
0.666667 Factorial primes |
|||
0.571429 Primorial numbers |
|||
0.545455 Prime words |
|||
0.521739 Almost prime |
|||
Sunkist-Giuliani formula > |
|||
0.565217 Almkvist-Giullera formula for pi |
|||
0.378378 Faulhaber's formula |
|||
0.342857 Haversine formula |
|||
0.333333 Check Machin-like formulas |
|||
0.307692 Resistance calculator |
|||
Sieve of Euripides > |
|||
0.461538 Four sides of square |
|||
0.461538 Sieve of Pritchard |
|||
0.413793 Sieve of Eratosthenes |
|||
0.400000 Piprimes |
|||
0.384615 Sierpinski curve |
|||
Chowder numbers > |
|||
0.782609 Chowla numbers |
|||
0.640000 Powerful numbers |
|||
0.608696 Rhonda numbers |
|||
0.608696 Fermat numbers |
|||
0.600000 Lah numbers |
|||
</pre> |
|||
=={{header|J}}== |
=={{header|J}}== |