/* 用到的处理手法 or 收获 or 注意事项: 1. substr函数分离邮箱的用户名和MTA,当需要有两个返回值时,通过传两个引用并改变它们来实现 2.对于map,在使用map[key]前,必须先检查一下key是否存在 如果map不包含key,使用下标有一个危险的副作用,会在map中插入一个key的元素,value取默认值,返回value。也就是说,map[key]不可能返回null 见blog: http://www.cnblogs.com/nzbbody/p/3409298.html 3.在输出时要输出很多空格,所以不妨把5个空格作为一个常量space来输出 4.空格的处理一定要小心谨慎,为此PE过一次 */
#include <iostream> #include <string> #include <vector> #include <set> #include <map> //#define debug using namespace std; const string space = " "; void separate(const string &s, string &user, string &mta) { int k = s.find('@'); user = s.substr(0, k); mta = s.substr(k + 1); } int main() { #ifdef debug freopen("E:\in.txt", "r", stdin); freopen("E:\out.txt", "w", stdout); #endif int k; string s, t, user1, mta1, user2, mta2; set<string> addr; //输入所有MTA,转换为地址列表 while (cin >> s && s != "*") //s为 MTA 而非 * { cin >> s >> k; while (k--) { cin >> t; addr.insert(t + "@" + s); } } while (cin >> s && s != "*") //处理发件人地址 { separate(s, user1, mta1); vector<string> mta; //所有需要连接的mta,按照输入排序 map<string, vector<string> > dest; //每个MTA需要发送的客户 set<string> vis; while (cin >> t && t != "*") { separate(t, user2, mta2); //处理收件人地址 if (vis.count(t)) continue; //重复的收件人 vis.insert(t); if (!dest.count(mta2)) { mta.push_back(mta2); dest[mta2] = vector<string> (); } dest[mta2].push_back(t); } getline(cin, t); //是为了吃掉 * 后的那个回车,也可用 getchar() 代替 string data; while (getline(cin, t) && t[0] != '*') data += space + t + " "; for (int i = 0; i < mta.size(); i++) { string mta2 = mta[i]; vector<string> users = dest[mta2]; cout << "Connection between " << mta1 << " and " << mta2 << endl; cout << space << "HELO " << mta1 << " "; cout << space + "250 "; cout << space + "MAIL FROM:<" + s + "> "; cout << space + "250 "; bool ok = false; for (int j = 0; j < users.size(); j++) { cout << space + "RCPT TO:<" + users[j] << "> "; cout << space; if (addr.count(users[j])) { ok = true; cout << "250 "; } else cout << "550 "; } if (ok) cout << space + "DATA " + space + "354 " + data + space + ". " + space + "250 "; cout << space + "QUIT " + space << "221 "; } } #ifdef debug fclose(stdin); fclose(stdout); #endif return 0; }