| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- #include "levenshtein.hpp"
- #define STRING_LEN 500
- #define TEST_COUNT 500
- #include <iostream>
- template <class T, typename SIZE=unsigned int>
- int levenshtein_base(const T &a, const T &b, const SIZE aSize, const SIZE bSize)
- {
- int **items = new int*[aSize +1]();
- for (SIZE i =0; i <= aSize; i++)
- {
- items[i] = new int[bSize +1]();
- items[i][0] = i;
- if (i == 0)
- for (SIZE j =1; j <= bSize; j++)
- items[i][j] = j;
- else
- for (SIZE j =1; j <= bSize; j++)
- items[i][j] = std::min(std::min(
- items[i][j -1] +1,
- items[i -1][j] +1),
- (items[i -1][j -1] + (a[i -1] == b[j -1] ? 0 : 1)));
- }
- const int levenshtein = items[aSize][bSize];
- for (SIZE i =0; i < aSize +1; i++)
- delete[] items[i];
- delete[] items;
- return levenshtein;
- }
- bool simpleTest(const std::string &a, const std::string &b, unsigned int expected)
- {
- unsigned int levenshteinScore;
- if ((levenshteinScore = levenshtein(a, b, a.size(), b.size())) != expected)
- {
- std::cerr << "Error: failed asserting levenshteinScore on file "
- << __FILE__ << ":" << __LINE__
- << " (got " << levenshteinScore << ") on "
- << a << " vs " << b
- << std::endl;
- return false;
- }
- if ((levenshteinScore = levenshtein_base(a, b, a.size(), b.size())) != expected)
- {
- std::cerr << "Error: failed asserting levenshteinScore on file "
- << __FILE__ << ":" << __LINE__
- << " (got " << levenshteinScore << ")"
- << std::endl;
- return false;
- }
- return true;
- }
- char randomChar()
- {
- return (rand() % 94) + 32;
- }
- std::string generateString()
- {
- std::string str;
- for (int i =0; i < STRING_LEN; i++)
- str += randomChar();
- return str;
- }
- void speedTest(const std::string &a, const std::string &b)
- {
- const unsigned int timeBefore = time(NULL);
- for (unsigned int i =0; i < TEST_COUNT; ++i)
- levenshtein(a, b, a.size(), b.size());
- const unsigned int timeMid = time(NULL);
- for (unsigned int i =0; i < TEST_COUNT; ++i)
- levenshtein_base(a, b, a.size(), b.size());
- const unsigned int timeEnd = time(NULL);
- std::cout << "Processing items in "
- << (float) (1000.f * (timeMid -timeBefore)) / TEST_COUNT
- << "ms (optimized) vs "
- << (float) (1000.f * (timeEnd -timeMid)) / TEST_COUNT
- << "ms" << std::endl;
- }
- void speedTestEq()
- {
- std::string a, b;
- a = b = generateString();
- if (!simpleTest(a, b, 0))
- return;
- speedTest(a, b);
- }
- void speedTestAddDel()
- {
- std::string a, b;
- a = generateString();
- b = a;
- b.erase(rand() % b.size(), 1);
- b.erase(rand() % b.size(), 1);
- b.erase(rand() % b.size(), 1);
- b.insert(rand() % b.size(), std::string(1, randomChar()));
- b.insert(rand() % b.size(), std::string(1, randomChar()));
- b.insert(rand() % b.size(), std::string(1, randomChar()));
- if (!simpleTest(a, b, 6))
- return;
- speedTest(a, b);
- }
- void speedTestDiff()
- {
- std::string a, b;
- a = b = generateString();
- b[rand() % b.size()] = randomChar();
- b[rand() % b.size()] = randomChar();
- b[rand() % b.size()] = randomChar();
- if (!simpleTest(a, b, 3))
- return;
- speedTest(a, b);
- }
- int main()
- {
- srand(11);
- if (!simpleTest("qwerty123", "qwerty123", 0))
- exit(EXIT_FAILURE);
- if (!simpleTest("abcdefghuijklmnop", "abcdefg0huijk0lmnop", 2))
- exit(EXIT_FAILURE);
- std::cout << "starting eq speed test" << std::endl;
- speedTestEq();
- std::cout << "starting add/del speed test" << std::endl;
- speedTestAddDel();
- std::cout << "starting diff speed test" << std::endl;
- speedTestDiff();
- exit(EXIT_SUCCESS);
- }
|