CCF CSP 竞赛试题——URL映射(201803-3)

  • 以下代码参考自@海岛BLOG,区别是,这里把两趟match操作分开了。
  • 关于去除前导0,以下代码能AC,说明测例里面可能不包含0,00,000之类值为0的数字。
#include <iostream>
#include <vector>
#include <cctype>
#include <string>
using namespace std;

bool ismatch(const string& url, const string& rule) {
	int i = 0, j = 0, n = rule.size(), m = url.size();
	while (i < n) {
		if (j == m) return false;
		if (rule[i] == url[j])
			++i, ++j;
		else {
			if (rule[i] != '<') return false;
			switch (rule[i + 1]) {
				case 's': {
					while (j < m && url[j] != '/') ++j;
					i += 5;
					break;
				}
				case 'i': {
					while (j < m && isdigit(url[j])) ++j;
					i += 5;
					break;
				}
				case 'p': {
					return true;
				}
			}
		}
	}
	return j == m;
}

void printParam(const string& url, const string& rule) {
	int i = 0, j = 0, n = rule.size(), m = url.size();
	while (i < n) {
		if (rule[i] == '<') {
			cout << ' ';
			switch (rule[i + 1]) {
				case 's': {
					while (j < m && url[j] != '/') cout << url[j++];
					i += 5;
					break;
				}
				case 'i': {
					while (j < m && url[j] == '0') ++j;
					while (j < m && isdigit(url[j])) cout << url[j++];
					i += 5;
					break;
				}
				case 'p': {
					while (j < m) cout << url[j++];
					i += 6;
					break;
				}
			}
		} else {
			++i, ++j;
		}
	}
}

int main() {
	int n, m;
	cin >> n >> m;
	vector<string> rules(n);
	vector<string> names(n);
	for (int i = 0; i < n; ++i) cin >> rules[i] >> names[i];
	while (m--) {
		string url;
		cin >> url;
		bool matched = false;
		for (int i = 0; i < n; ++i) if (ismatch(url, rules[i])) {
			matched = true;
			cout << names[i];
			printParam(url, rules[i]);
			cout << endl;
			break;
		}
		if (!matched) cout << "404" << endl;
	}
	return 0;
}

  • 以下为原创。
#include <iostream>
#include <vector>
#include <cctype>
#include <string>
using namespace std;

struct RULE {
	string name;
	vector<string> args;
};

void decode(vector<string>& out, const string& s) {
	int i = 0, n = s.size();
	while (i < n) {
		int j = i;
		while (++j < s.size() && s[j] != '/');
		out.push_back(s.substr(i, j - i));
		i = j;
	}
}

bool testInt(const string& s) {
	if (s == "/") return false;
	for (int i = 1; i < s.size(); ++i) if (!isdigit(s[i])) return false;
	return true;
}

int main() {
	int n, m;
	cin >> n >> m;
	vector<RULE> rules(n);
	for (int k = 0; k < n; ++k) {
		string s;
		cin >> s >> rules[k].name;
		decode(rules[k].args, s);
	}
	while (m--) {
		string s;
		cin >> s;

		vector<string> tokens;
		decode(tokens, s);
		int k = 0;
		vector<string> extra;
		while (k < n) {
			if (rules[k].args.size() <= tokens.size()) {
				extra.clear();
				int i = 0, j = 0;
				while (i < rules[k].args.size()) {
					string& cur = rules[k].args[i];
					if (cur == "/<int>") {
						if (!testInt(tokens[j])) break;
						int z = 1;
						while (z < tokens[j].size() && tokens[j][z] == '0') ++z;
						extra.push_back(z == tokens[j].size() ? "0" : tokens[j].substr(z));
					} else if (cur == "/<str>") {
						if (tokens[j] == "/") break;
						extra.push_back(tokens[j].substr(1));
					} else if (cur == "/<path>") {
						string t;
						while (j < tokens.size()) t.append(tokens[j++]);
						t.erase(t.begin());
						if (t.empty()) break;
						extra.push_back(t);
						--j;
					} else {
						if (cur != tokens[j]) break;
					}
					++i, ++j;
				}
				if (i == rules[k].args.size() && j == tokens.size()) {
					cout << rules[k].name;
					for (int i = 0; i < extra.size(); ++i) cout << " " << extra[i];
					cout << endl;
					break;
				}
			}
			++k;
		}
		if (k == n) cout << "404" << endl;
	}
	return 0;
}
发布了33 篇原创文章 · 获赞 4 · 访问量 8746

猜你喜欢

转载自blog.csdn.net/Touchig/article/details/102797769