Read test cases from file and test
This commit is contained in:
parent
9fc2b23a76
commit
936363011c
@ -1,32 +1,98 @@
|
|||||||
/*/ problem source:
|
/*/ problem source:
|
||||||
* https://www.geeksforgeeks.org/find-the-longest-substring-with-k-unique-characters-in-a-given-string/
|
* https://www.geeksforgeeks.org/find-the-longest-substring-with-k-unique-characters-in-a-given-string/
|
||||||
|
|
||||||
|
Possible references include:
|
||||||
|
https://stackoverflow.com/a/7304184 - custom delimeter for istream
|
||||||
*/
|
*/
|
||||||
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <istream>
|
||||||
|
#include <locale>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
struct semicolon_is_space : std::ctype<char> {
|
||||||
|
// this struct/class is adapted from: https://stackoverflow.com/a/7304184
|
||||||
|
semicolon_is_space() : std::ctype<char>(get_table()){};
|
||||||
|
static mask const *get_table() {
|
||||||
|
static mask rc[table_size];
|
||||||
|
rc[(int)';'] = std::ctype_base::space;
|
||||||
|
rc[(int)'\n'] = std::ctype_base::space;
|
||||||
|
return &rc[0];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
class input {
|
||||||
|
public:
|
||||||
|
std::string s;
|
||||||
|
unsigned long k;
|
||||||
|
friend std::istream &operator>>(std::istream &in, input &i);
|
||||||
|
friend std::ostream &operator<<(std::ostream &out, const input &i);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::istream &operator>>(std::istream &in, input &i) {
|
||||||
|
std::getline(in, i.s, '\n'); // An inelegant hack to skip newline character
|
||||||
|
std::getline(in, i.s, ';');
|
||||||
|
in >> i.k;
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const input &i) {
|
||||||
|
out << "String:\n" << i.s << "\nK: " << i.k << std::endl;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
class result {
|
class result {
|
||||||
public:
|
public:
|
||||||
unsigned long longest_start = 0;
|
unsigned long longest_start = 0;
|
||||||
unsigned long longest_end = 0;
|
unsigned long longest_end = 0;
|
||||||
bool match_found = false;
|
bool match_found = false;
|
||||||
bool operator==(const result r) {
|
bool operator==(const result r);
|
||||||
return longest_start == r.longest_start && longest_end == r.longest_end &&
|
friend std::istream &operator>>(std::istream &in, result &r);
|
||||||
match_found == r.match_found;
|
friend std::ostream &operator<<(std::ostream &out, const result &r);
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct input {
|
bool result::operator==(const result r) {
|
||||||
std::string s;
|
return longest_start == r.longest_start && longest_end == r.longest_end &&
|
||||||
unsigned long k;
|
match_found == r.match_found;
|
||||||
};
|
}
|
||||||
|
|
||||||
struct test_case {
|
std::istream &operator>>(std::istream &in, result &r) {
|
||||||
|
in >> r.longest_start >> r.longest_end >> r.match_found;
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const result &r) {
|
||||||
|
out << "longest_start: " << r.longest_start
|
||||||
|
<< " longest_end: " << r.longest_end << " match_found: ";
|
||||||
|
if (r.match_found)
|
||||||
|
out << "true";
|
||||||
|
else
|
||||||
|
out << "false";
|
||||||
|
out << std::endl;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
class test_case {
|
||||||
|
public:
|
||||||
input i;
|
input i;
|
||||||
result r;
|
result r;
|
||||||
|
friend std::istream &operator>>(std::istream &in, test_case &t);
|
||||||
|
friend std::ostream &operator<<(std::ostream &out, const test_case &t);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::istream &operator>>(std::istream &in, test_case &t) {
|
||||||
|
in >> t.i >> t.r;
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const test_case &t) {
|
||||||
|
out << t.i << t.r;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
result find(const std::string &s, const unsigned long k) {
|
result find(const std::string &s, const unsigned long k) {
|
||||||
result r;
|
result r;
|
||||||
std::unordered_map<char, unsigned long> char_count;
|
std::unordered_map<char, unsigned long> char_count;
|
||||||
@ -58,11 +124,24 @@ result find(const std::string &s, const unsigned long k) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main(int argc, char *argv[]) {
|
||||||
std::vector<test_case> test_cases = {{{"aabacbebebe", 3}, {4, 10, true}},
|
std::vector<test_case> test_cases;
|
||||||
{{"aabbcc", 1}, {0, 1, true}},
|
semicolon_is_space delimeter;
|
||||||
{{"aabbcc", 3}, {0, 5, true}},
|
for (int i = 1; i < argc; i++) {
|
||||||
{{"aaabbb", 3}, {0, 0, false}}};
|
test_case t;
|
||||||
|
std::ifstream f(argv[i]);
|
||||||
|
f.imbue(std::locale(f.getloc(), new semicolon_is_space));
|
||||||
|
while (f.good()) {
|
||||||
|
f >> t;
|
||||||
|
if (t.i.s.length()) { // skip empty line/string inputs
|
||||||
|
std::cout << t;
|
||||||
|
test_cases.push_back(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "\n===================================\n" << std::endl;
|
||||||
|
|
||||||
for (const test_case &t : test_cases) {
|
for (const test_case &t : test_cases) {
|
||||||
if (find(t.i.s, t.i.k) == t.r) {
|
if (find(t.i.s, t.i.k) == t.r) {
|
||||||
std::cout << "Test case with string \"" << t.i.s << "\" and k=" << t.i.k
|
std::cout << "Test case with string \"" << t.i.s << "\" and k=" << t.i.k
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
aabacbebebe;3;4;10;1
|
||||||
|
aabbcc;1;0;1;1
|
||||||
|
aabbcc;3;0;5;1
|
||||||
|
aaabbb;3;0;0;0
|
|
Loading…
Reference in New Issue
Block a user