1 洛谷题解格式修正器
写了个有意思的小工具
下载链接:工具下载
使用说明
洛谷题解格式修正器(修正器)
使用说明
注意:本修正器不能保证你的题解过审,只能修改其中一些错误:
- 句末有空格
- 中文与英文、数字、公式间有空格
- 中文标点与英文、数字、公式间无空格
其余错误本工具不会修改,另外在使用本工具后请注意检查,以免出现问题
使用步骤
- 将detector文件和你的题解文件放在同一个目录下
- 将你的题解中的代码块删掉(请做好备份),因为本工具不兼容代码块
- 将你的题解文件名改为 tijie.in
- 运行detector文件
目录下生成的 tijie.out 文件即为修改后的题解
源代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>
using namespace std;
namespace michaele {
typedef unsigned char uc;
const int N = 1e6 + 10;
// 标点符号, punctuation
map <string, bool> punc_mp;
string punc[100] = {"。", ",", ":", ";", "?", "!", ")", ")", "、", "“", "”", "‘", "’", "("};
vector <string> vec_ans;
// 处理后的字符数组
short kind[N];
int len;
// 添加空格
bool ins[N], del[N];
bool isChi (const string &charStr) {
if (charStr.length() != 3) return false;
uc c1 = charStr[0];
uc c2 = charStr[1];
uc c3 = charStr[2];
// UTF-8汉字的三字节模式
return (c1 >= 0xE0 && c1 <= 0xEF) &&
(c2 >= 0x80 && c2 <= 0xBF) &&
(c3 >= 0x80 && c3 <= 0xBF);
}
void init_punc () {
for (auto p : punc) {
punc_mp[p] = 1;
}
}
// 将 string 分割并处理出对应的类型
// 0:中文 1:中文标点 2:英文 3:空格
void init_str (const string &str) {
len = 0;
for (size_t i = 0; i < str.size (); i ++) {
uc ch = str[i];
if (ch >= 0xe0 && ch <= 0xef) {
auto sub = str.substr (i, 3);
if (isChi (sub)) {
if (punc_mp.count (sub)) {
kind[len ++] = 1;
} else {
kind[len ++] = 0;
}
vec_ans.push_back (sub);
i += 2;
}
} else {
string _ch (1, str[i]);
vec_ans.push_back (_ch);
if (ch == ' ') {
kind[len ++] = 3;
} else if (ch == '~' || ch == '*') {
kind[len ++] = 1;
} else {
kind[len ++] = 2;
}
}
}
}
void solve () {
init_punc ();
bool in_block = 0;
string str;
int cnt = 0;
while (getline (cin, str)) {
memset (ins, 0, sizeof ins);
memset (del, 0, sizeof del);
while (vec_ans.size ()) vec_ans.pop_back ();
init_str (str);
cnt ++;
for (int i = 0; i < len; i ++) {
if (kind[i] == 0) {
// 中文
if (i + 1 < len && kind[i + 1] == 2) {
ins[i] = 1;
}
} else if (kind[i] == 1) {
// 中文标点,两边的空格删掉
for (int j = i + 1; j < len && kind[j] == 3; j ++) {
del[j] = 1;
}
for (int j = i - 1; j >= 0 && kind[j] == 3; j --) {
del[j] = 1;
}
} else if (kind[i] == 2) {
// 英文字母及符号,如果下一个是汉字,添加空格
if (i + 1 < len && kind[i + 1] == 0) {
ins[i] = 1;
}
} else if (kind[i] == 3) {
if (del[i]) continue;
int j = i + 1;
while (j < len && kind[j] == 3) {
del[j] = 1;
j ++;
}
if (i == 0) {
j = i + 1;
while (j < len && kind[j] == 3) {
del[j] = 0;
j ++;
}
} else {
if (i - 1 >= 0 && j < len) {
if (kind[i - 1] == 0 && kind[j] == 0) del[i] = 1;
} else {
del[i] = 1;
}
}
}
}
for (int i = 0; i < len; i ++) {
if (del[i]) continue;
cout << vec_ans[i];
if (ins[i]) printf (" ");
}
if (len >= 2 && vec_ans[0] == "$" && vec_ans[1] == "$") {
in_block ^= 1;
}
int fn = 0;
if (len) {
for (int i = 0; i <= 7; i ++) {
if (vec_ans[len - 1] == punc[i]) {
fn = 1;
break;
}
}
// 行间公式
if (len >= 2 && vec_ans[len - 1] == "$" && vec_ans[len - 2] == "$") fn = 1;
// 标题
if (vec_ans[0] == "#") fn = 1;
if (!fn && !in_block) cout << punc[0];
}
if (len > 2 && vec_ans[0] == "$" && vec_ans[1] == "$") {
in_block ^= 1;
}
printf ("\n");
}
}
}
int main() {
freopen ("tijie.in", "r", stdin);
freopen ("tijie.out", "w", stdout);
michaele :: solve ();
return 0;
}