Use C++ language to complete a program that reads in a word list and finds words from it that match a given search patte
Posted: Sun Jul 10, 2022 11:25 am
Use C++ language to complete a program thatreads in a word list and finds words from it that match a givensearch pattern. The word list is in a text file that consists ofwords separated from one another by newline characters. All thecharacters are in lower case and the words are sorted inlexicographical, i.e., dictionary order. The search pattern is aC++ string whose length matches that of the required word. Eachcharacter location where the letter is already known is filled inwith the known alphabet in lower case. Character locations wherethe letter is unknown are filled with the '*' character. Forexample, given the following list
and the search pattern *a , the matches would be aa and ba . Forthe search pattern a* the only match is aa . Finally, with thesearch pattern ** , the matches are aa as well as ba.
The file q.h makers for following declaration for compare anddefinition for the class Crossword :
//q.h file, to implement class Crossword
#ifndef Q_H
#define Q_H
#include <string>
#include <vector>
namespace hlp2
{
// Returns true if the word matches thepattern
bool compare(const std::string &word, conststd::string &pattern);
class Crossword
{
public:
using Container = // TODO - DefineContainer alias here
// TODO - Define Container2 aliashere
Crossword(const std::string&filename);
void find(const std::string&pattern, Container &matches);
// Find matches forintersecting pattern1 and pattern2
// Intersection for pattern1is at pos1
// Intersection for pattern2is at pos2
void find(
const std::string&pattern1,
int pos1,
const std::string&pattern2,
int pos2,
Container2&matches);
private:
Container dictionary;
};
}
#endif
The constructor takes in a reference to a read-only string thatspecifies the file to read the list of words from. The constructorenters each word from the list as a string into dictionary startingfrom the beginning of the file and adding each new word to the endof dictionary . The first version of find has parameter patternthat specifies the search pattern to use to find words. The searchbegins from the start of dictionary and adds each new matching wordto the end of matches . find uses the compare function to check ifa word matches pattern . If so, it returns true , else it returnsfalse . pattern may consist of any combination of English alphabetsas well as the asterisk ( '*' ), where '*' matches any Englishletter in the same position. pattern may be of any length including0. The other version of find is meant to produce solutions forpairs of intersecting words where each word has its search patternand position of intersection with the other word. The first wordhas search pattern pattern1 and intersection position pos1 wherepos1 is the index of the intersecting character. Similarly, theother word has parameters pattern2 and pos2 . Solutions for theintersecting words are to be stored in Container2 which is a vectorof pair s of strings . Each pair consists of a word matchingpattern1 as the first element and a word that matches pattern2 assecond element.
Implement Crossword member functions in q.h (givenabove) as well as compare in q.cpp (to create from scratch) so thatthe code compiles and produces the right output.
qdriver.cpp:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "q.h"
std::ostream &operator<<(std::ostream &os, consthlp2::Crossword::Container &rhs)
{
for (hlp2::Crossword::Container::const_iterator it= rhs.cbegin(); it != rhs.cend(); ++it)
os << *it << '\n';
return os;
}
std::ostream &operator<<(std::ostream &os, consthlp2::Crossword::Container2 &rhs)
{
for (hlp2::Crossword::Container2::const_iteratorit = rhs.cbegin(); it != rhs.cend(); ++it)
os << (*it).first << ','<< (*it).second << '\n';
return os;
}
void test1()
{
std::cout << "Test 1 : ";
bool actual = hlp2::compare("", "");
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< actual << ")\n";
}
void test2()
{
std::cout << "Test 2 : ";
bool actual1 = hlp2::compare("", "a");
bool expected1 = false;
bool actual2 = hlp2::compare("b", "");
bool expected2 = false;
if (actual1 == expected1 && actual2 ==expected2)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< actual1 << ' ' << actual2 << ")\n";
}
void test3()
{
std::cout << "Test 3 : ";
bool actual = hlp2::compare("abc", "abc");
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< actual << ")\n";
}
void test4()
{
std::cout << "Test 4 : ";
bool actual = hlp2::compare("abc", "abc*");
bool expected = false;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< actual << ")\n";
}
void test5()
{
std::cout << "Test 5 : ";
bool actual = hlp2::compare("abc", "*b");
bool expected = false;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< actual << ")\n";
}
void test6()
{
std::cout << "Test 6 : ";
bool actual = hlp2::compare(" a b c ","*a*b*c*");
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< actual << ")\n";
}
void test7()
{
std::cout << "Test 7 : ";
hlp2::Crossword cw("dict.txt");
std::vector<std::string> m;
cw.find("", m);
bool actual = m.empty();
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< m << ")\n";
}
void test8()
{
std::cout << "Test 8 : ";
hlp2::Crossword cw("dict.txt");
std::vector<std::string> m;
cw.find("qwertyuiop", m);
bool actual = m.empty();
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< m << ")\n";
}
void test9()
{
std::cout << "Test 9 : ";
hlp2::Crossword cw("dict.txt");
std::vector<std::string> m;
cw.find("av*le", m);
std::vector<std::string> e{"avale","avile"};
bool actual = (m.size() == e.size()) &&std::equal(m.cbegin(), m.cend(), e.cbegin());
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< m << ")\n";
}
void test10()
{
std::cout << "Test 10 : ";
hlp2::Crossword cw("dict.txt");
std::vector<std::string> m;
cw.find("z*", m);
int actual = m.size();
int expected = 4;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< m << ")\n";
}
void test11()
{
std::cout << "Test 11 : ";
hlp2::Crossword cw("dict.txt");
hlp2::Crossword::Container2 m;
cw.find("*pple", 0, "b*n*na", 1, m);
hlp2::Crossword::Container2 e{{"apple","banana"}};
bool actual = (m.size() == e.size()) &&std::equal(m.cbegin(), m.cend(), e.cbegin());
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< m << ")\n";
}
void test12()
{
std::cout << "Test 12 : ";
hlp2::Crossword cw("dict.txt");
hlp2::Crossword::Container2 m;
cw.find("*pple", 0, "b*n*na", 3, m);
hlp2::Crossword::Container2 e{{"apple","banana"}};
bool actual = (m.size() == e.size()) &&std::equal(m.cbegin(), m.cend(), e.cbegin());
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< m << ")\n";
}
void test13()
{
std::cout << "Test 13 : ";
hlp2::Crossword cw("dict.txt");
hlp2::Crossword::Container2 m;
cw.find("*pple", 2, "b*n*na", 3, m);
hlp2::Crossword::Container2 e{};
bool actual = (m.size() == e.size()) &&std::equal(m.cbegin(), m.cend(), e.cbegin());
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< m << ")\n";
}
int main()
{
test1();
test2();
test3();
test4();
test5();
test6();
test7();
test8();
test9();
test10();
test11();
test12();
test13();
}
output:
Test 1 : PassTest 2 : PassTest 3 : PassTest 4 : PassTest 5 : PassTest 6 : PassTest 7 : PassTest 8 : PassTest 9 : PassTest 10 : PassTest 11 : PassTest 12 : PassTest 13 : Pass
aa aaa ba
and the search pattern *a , the matches would be aa and ba . Forthe search pattern a* the only match is aa . Finally, with thesearch pattern ** , the matches are aa as well as ba.
The file q.h makers for following declaration for compare anddefinition for the class Crossword :
//q.h file, to implement class Crossword
#ifndef Q_H
#define Q_H
#include <string>
#include <vector>
namespace hlp2
{
// Returns true if the word matches thepattern
bool compare(const std::string &word, conststd::string &pattern);
class Crossword
{
public:
using Container = // TODO - DefineContainer alias here
// TODO - Define Container2 aliashere
Crossword(const std::string&filename);
void find(const std::string&pattern, Container &matches);
// Find matches forintersecting pattern1 and pattern2
// Intersection for pattern1is at pos1
// Intersection for pattern2is at pos2
void find(
const std::string&pattern1,
int pos1,
const std::string&pattern2,
int pos2,
Container2&matches);
private:
Container dictionary;
};
}
#endif
The constructor takes in a reference to a read-only string thatspecifies the file to read the list of words from. The constructorenters each word from the list as a string into dictionary startingfrom the beginning of the file and adding each new word to the endof dictionary . The first version of find has parameter patternthat specifies the search pattern to use to find words. The searchbegins from the start of dictionary and adds each new matching wordto the end of matches . find uses the compare function to check ifa word matches pattern . If so, it returns true , else it returnsfalse . pattern may consist of any combination of English alphabetsas well as the asterisk ( '*' ), where '*' matches any Englishletter in the same position. pattern may be of any length including0. The other version of find is meant to produce solutions forpairs of intersecting words where each word has its search patternand position of intersection with the other word. The first wordhas search pattern pattern1 and intersection position pos1 wherepos1 is the index of the intersecting character. Similarly, theother word has parameters pattern2 and pos2 . Solutions for theintersecting words are to be stored in Container2 which is a vectorof pair s of strings . Each pair consists of a word matchingpattern1 as the first element and a word that matches pattern2 assecond element.
Implement Crossword member functions in q.h (givenabove) as well as compare in q.cpp (to create from scratch) so thatthe code compiles and produces the right output.
qdriver.cpp:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "q.h"
std::ostream &operator<<(std::ostream &os, consthlp2::Crossword::Container &rhs)
{
for (hlp2::Crossword::Container::const_iterator it= rhs.cbegin(); it != rhs.cend(); ++it)
os << *it << '\n';
return os;
}
std::ostream &operator<<(std::ostream &os, consthlp2::Crossword::Container2 &rhs)
{
for (hlp2::Crossword::Container2::const_iteratorit = rhs.cbegin(); it != rhs.cend(); ++it)
os << (*it).first << ','<< (*it).second << '\n';
return os;
}
void test1()
{
std::cout << "Test 1 : ";
bool actual = hlp2::compare("", "");
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< actual << ")\n";
}
void test2()
{
std::cout << "Test 2 : ";
bool actual1 = hlp2::compare("", "a");
bool expected1 = false;
bool actual2 = hlp2::compare("b", "");
bool expected2 = false;
if (actual1 == expected1 && actual2 ==expected2)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< actual1 << ' ' << actual2 << ")\n";
}
void test3()
{
std::cout << "Test 3 : ";
bool actual = hlp2::compare("abc", "abc");
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< actual << ")\n";
}
void test4()
{
std::cout << "Test 4 : ";
bool actual = hlp2::compare("abc", "abc*");
bool expected = false;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< actual << ")\n";
}
void test5()
{
std::cout << "Test 5 : ";
bool actual = hlp2::compare("abc", "*b");
bool expected = false;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< actual << ")\n";
}
void test6()
{
std::cout << "Test 6 : ";
bool actual = hlp2::compare(" a b c ","*a*b*c*");
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< actual << ")\n";
}
void test7()
{
std::cout << "Test 7 : ";
hlp2::Crossword cw("dict.txt");
std::vector<std::string> m;
cw.find("", m);
bool actual = m.empty();
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< m << ")\n";
}
void test8()
{
std::cout << "Test 8 : ";
hlp2::Crossword cw("dict.txt");
std::vector<std::string> m;
cw.find("qwertyuiop", m);
bool actual = m.empty();
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< m << ")\n";
}
void test9()
{
std::cout << "Test 9 : ";
hlp2::Crossword cw("dict.txt");
std::vector<std::string> m;
cw.find("av*le", m);
std::vector<std::string> e{"avale","avile"};
bool actual = (m.size() == e.size()) &&std::equal(m.cbegin(), m.cend(), e.cbegin());
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< m << ")\n";
}
void test10()
{
std::cout << "Test 10 : ";
hlp2::Crossword cw("dict.txt");
std::vector<std::string> m;
cw.find("z*", m);
int actual = m.size();
int expected = 4;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< m << ")\n";
}
void test11()
{
std::cout << "Test 11 : ";
hlp2::Crossword cw("dict.txt");
hlp2::Crossword::Container2 m;
cw.find("*pple", 0, "b*n*na", 1, m);
hlp2::Crossword::Container2 e{{"apple","banana"}};
bool actual = (m.size() == e.size()) &&std::equal(m.cbegin(), m.cend(), e.cbegin());
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< m << ")\n";
}
void test12()
{
std::cout << "Test 12 : ";
hlp2::Crossword cw("dict.txt");
hlp2::Crossword::Container2 m;
cw.find("*pple", 0, "b*n*na", 3, m);
hlp2::Crossword::Container2 e{{"apple","banana"}};
bool actual = (m.size() == e.size()) &&std::equal(m.cbegin(), m.cend(), e.cbegin());
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< m << ")\n";
}
void test13()
{
std::cout << "Test 13 : ";
hlp2::Crossword cw("dict.txt");
hlp2::Crossword::Container2 m;
cw.find("*pple", 2, "b*n*na", 3, m);
hlp2::Crossword::Container2 e{};
bool actual = (m.size() == e.size()) &&std::equal(m.cbegin(), m.cend(), e.cbegin());
bool expected = true;
if (actual == expected)
std::cout << "Pass\n";
else
std::cout << "Fail \n("<< m << ")\n";
}
int main()
{
test1();
test2();
test3();
test4();
test5();
test6();
test7();
test8();
test9();
test10();
test11();
test12();
test13();
}
output:
Test 1 : PassTest 2 : PassTest 3 : PassTest 4 : PassTest 5 : PassTest 6 : PassTest 7 : PassTest 8 : PassTest 9 : PassTest 10 : PassTest 11 : PassTest 12 : PassTest 13 : Pass
aa aaa ba