The main point here is to show how some of the more advanced C++ features map to Python code. The point is not what the code does (thus no comments), but how it does it. The example codes should be easily comparable, due to same variable and function names. The C++ code is about twice as long as the Python code, and runs about 7.5 times faster.
Table of contents |
2 Python code 3 External Links |
typedef multimap
char toNumber(char letter) {
void findMatch(const string& answer, const string& line, const DicMap& dic,
for (size_t i = 1; i <= line.length(); ++i) {
pair
if (allowNumber)
findMatch(answer + " " + line[0], line.substr(1, line.length()), dic, false, answers);
bool readDic(DicMap& dic, const string& dicfile) {
string number = line;
number.erase(remove_if(number.begin(), number.end(), not1(ptr_fun(::isalpha))), number.end());
transform(number.begin(), number.end(), number.begin(), ::toupper);
transform(number.begin(), number.end(), number.begin(), toNumber);
dic.insert(make_pair(number, line));
}
return true;
int main(int argc, char* argv[]) {
ifstream in(argv[2]);
if (!in) return 1;
string line;
while (!in.eof()) {
getline(in, line);
string line_real = line;
line_real.erase( remove_if(line_real.begin(), line_real.end(), not1(ptr_fun(::isdigit))), line_real.end());
Answers answers;
findMatch("", line_real, dic, true, answers);
for (Answers::iterator i = answers.begin(); i != answers.end(); ++i)
cout << line << ":" << *i << endl;
}
letter2digit = "E", "JNQ", "RWX", "DSY", "FT", "AM", "CIV", "BKU", "LOP", "GHZ"
def toNumber(letter):
for i in range(1, len(line) + 1):
if dic.has_key(line[:i]):
allowNumber = False
for e in dic[line[:i]]:
findMatch(answer + ' ' + e, line[i:], dic, True, answers)
if allowNumber:
findMatch(answer + ' ' + line[0], line[1:], dic, False, answers)
C++ code
using namespace std; static string letter2digit[] = { "E", "JNQ", "RWX", "DSY", "FT", "AM", "CIV", "BKU", "LOP", "GHZ" };
for (int i = 0; i < 10; ++i)
if (letter2digit[i].find(letter) != string::npos)
return '0' + i;
return '0';
} bool allowNumber, Answers& answers) {
if (line.empty()) {
if (answer.length() != 0)
answers.push_back(answer);
return;
}
} ifstream in(dicfile.c_str());
if (!in) return false;
string line;
while (!in.eof()) {
getline(in, line);
} DicMap dic;
if (!readDic(dic, argv[1])) return 1;
}
Python code
import string
import sys
In the Python sample, the "main"-block was moved into a function for convenience; It need not be there. for i in range(len(letter2digit)):
if letter in letter2digit[i]:
return chr(ord('0') + i)
def findMatch(answer, line, dic, allowNumber, answers):
if not line:
answers.append(answer)
return
def readDic(dicfile):
dic = { }
for line in file(dicfile):
line = line.strip()
number = filter(lambda x: x in string.ascii_letters, line).upper()
number = "".join(map(toNumber, number))
dic[number] = dic.get(number, [ ]) + [line]
return dic
def main():
dic = readDic(sys.argv[1])
for line in file(sys.argv[2]):
line = line.strip()
line_real = filter(lambda x: x in string.digits, line)
answers = [ ]
findMatch("", line_real, dic, True, answers)
for answer in answers:
print "%s:%s" % (line, answer)
main()
External Links