예제 #1
0
int levenshtein_search_test()
{
	long result = errors_counter();

	// Create a tree with known levenshtein count = 100
	std::string b0("abcdefjklmn");
	int testcount = 3;
	while ( testcount ) {
		std::random_shuffle(b0.begin(), b0.end());
		int baselen = (int)b0.size();
		typedef containers::ternary_tree<std::string, std::string> Tst;
		Tst names;
		int L1count = 0, L2count = 0, L3count = 0, L4count = 0;
		for (int i = 0; i < baselen; i++)
		{
			std::string s1(b0);
			mutate(s1, i);
			if (names.insert(std::make_pair(s1, s1)).second)
				L1count++;
			for (int j = 0; j < (int)s1.size(); j++)
			{
				if (j == i)
					continue;
				std::string s2(s1);
				mutate(s2, j);
				if (names.insert(std::make_pair(s2, s2)).second)
					L2count++;
				for (int k = 0; k < (int)s2.size(); k++)
				{
					if (abs(k - j) <= 1 || abs(k - i) <= 1)
						continue;
					std::string s3(s2);
					mutate(s3, k);
					//if (s3.size() < s2.size() && s3.size() == s1.size())
					//	continue;
					//if (names.insert(std::make_pair(s3, s3)).second)
					//	L3count++;
					for (int m = 2; m < (int)s3.size() - 2; m++)
					{
						if (abs(m - j) <= 2 || abs(m - i) <= 2 || abs(m - k) <= 2)
							continue;
						std::string s4(s3);
						mutate(s4, m);
						if (m + 1 >= (int)s4.size())
							continue;
						mutate(s4, m + 1);
						if (m - 1 < 0)
							continue;
						mutate(s4, m - 1);
						if (m + 2 >= (int)s4.size())
							continue;
						mutate(s4, m + 2);
						if (m - 2 < 0)
							continue;
						mutate(s4, m - 2);
						if (abs((int)s4.size() - (int)b0.size()) < 2) {
							s4.insert(rand()%s4.size(), 1, 'Z');
							s4.insert(rand()%s4.size(), 1, 'Z');
						}
						if (names.insert(std::make_pair(s4, s4)).second)
							L4count++;
					}
				}
			}
		}

		if (names.size() != L1count + L2count + L3count + L4count) {
			std::cout << "levenshtein tree name collision, try again";
			continue;
		}
		Tst::search_results_list results = names.create_search_results();
		typedef Tst::search_results_list::iterator ResultsIter;
		names.levenshtein_search(b0, std::back_inserter(results), 2);
		if (results.size() != L1count + L2count + L3count)
		{
			Tst found;
			for (ResultsIter rit = results.begin(); rit != results.end(); ++rit)
				found[**rit] = **rit;
			BOOST_CHECK(found.size() == L1count + L2count); // + L3count);
			std::cout << "\nSearch " << b0 //<< ", L-count: " << names.levenshtein_search_count
					<< ", found " << results.size() << " strings";
			std::cout << " (" << found.size() << " in " << found.node_count() << " nodes)\n";
			if (found.size() != L1count + L2count) { // + L3count) {
				Tst::iterator fit = found.begin();
				for (Tst::iterator nit = names.begin(); nit != names.end(); ++nit)
				{
					if (fit != found.end() && *nit == *fit) {
						std::cout << *nit << "\n";
						++fit;
					}
					else
						std::cout << *nit << " ###\n";
				}
			//	std::cout << "full-frontal:\n";
			//	for (ResultsIter rit = results.begin(); rit != results.end(); ++rit)
			//		std::cout << **rit << "\n";
			}
		}
		testcount--;
	}
	return errors_counter() - result;
}
예제 #2
0
int basic_insertion_test()
{
	long result = errors_counter();

	typedef containers::ternary_tree<std::basic_string<CharT>, int> Tst;
	Tst tst;

	const char* strings[] = { "\0", "aa", "aab", "aac", "add", "aee", "bab" };
	widen<CharT> w;

	// Construction postconditions
	check_empty(tst);

	// Standard insert()
	tst.insert(std::make_pair(w(strings[1]), 1));
	tst.insert(std::make_pair(w(strings[5]), 5));

	std::pair<std::basic_string<CharT>, int> inval(w(strings[3]), 3);
	std::pair<Tst::iterator, bool> vr = tst.insert(inval);
	BOOST_CHECK(vr.first != tst.end());
	BOOST_CHECK(vr.second == true);
	vr = tst.insert(inval);
	BOOST_CHECK(vr.first != tst.end());
	BOOST_CHECK(vr.second == false);

	BOOST_CHECK((*tst.find(w(strings[1]))) == 1);
	BOOST_CHECK((*tst.find(w(strings[3]))) == 3);
	BOOST_CHECK((*tst.find(w(strings[5]))) == 5);

	BOOST_CHECK(tst.item_count() == 3);
	BOOST_CHECK(tst.total_key_length() == 3*3-1);

	// In present version, no reassignment
	tst.insert(std::make_pair(w(strings[1]), 4));
	BOOST_CHECK((*tst.find(w(strings[1]))) == 1);
	BOOST_CHECK(tst.item_count() == 3);
	BOOST_CHECK(tst.total_key_length() == 3*3-1);

	// reference_proxy insert()
	tst[w(strings[2])] = 2;
	tst[w(strings[6])] = 6;
	tst[w(strings[4])] = 4;
	BOOST_CHECK(tst[w(strings[2])] == 2);
	BOOST_CHECK(tst[w(strings[4])] == 4);
	BOOST_CHECK(tst[w(strings[6])] == 6);

	BOOST_CHECK(tst.item_count() == 6);
	BOOST_CHECK(tst.total_key_length() == 6*3-1);

	// Now do reassignment
	tst[w(strings[1])] = 7;
	BOOST_CHECK((*tst.find(w(strings[1]))) == 7);  //1);
	tst[w(strings[1])] = 1;

	// iterator used to check sort order of strings
	Tst::const_iterator it(tst.begin());
	int expect_val = 1;
	while (it != tst.end()) {
		Tst::value_type val = *it;
		// string == "a", "b" etc
		BOOST_CHECK(expect_val == 1 || it.key().size() == 3);
		BOOST_CHECK(it.key() == w(strings[expect_val]));
		// value is 1, 2 etc
		BOOST_CHECK(val == expect_val++);
		++it;
	}
	BOOST_CHECK(expect_val == int(tst.item_count() + 1));

	// Test clear() postconditions
	tst.clear();

	check_empty(tst);

	return errors_counter() - result;
}