这道题确实是正常人不适宜做。不过也可以作为代码严谨程度的考验。
我的解法实现相当混乱,无暇修改了,写这篇解题报告的目的有三:一是记录下自己的解题,二是附录相关的测试数据,可能会方便到一些同学。
这道题其实题目描述得挺准确的,没有特别不可理解的地方,比如“0+1”和“1”比较,就是如题所述,比较0和1,前者小于后者即可,测试数据并无异常。
需要注意的是
1.涉及到数字比较,不能懒得直接用int类型,数字是可以任意长度的,需要按照字符串的格式,依次比较正负,长度,逐位比较。
2.先预处理会简单很多,不然像我这样需要考虑很多边边角角。
解题报告可参考http://blog.csdn.net/ederick/article/details/7244985,更为简洁。
测试数据如下:
[input]
10 x-3 X0001 123-456-7890 123+456+7890 xYz000123J XyZ+123j #$%^&*[]- abcdefgh Abc47jKL+00123 ABC+47jkL123 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 X+0000000000000000000000000000000000000000000000000 x-000000000000000000000000 11111111111111111111111111111111111111111111111111111111 99999999999999999999999999999999999999999999999 abc[ ABC{ #$%^&*(){}00001234#$%^&*(){}00001234 #$%^&*(){}1234#$%^&*(){}123[output]
1 -1 2 1 3 0 4 -1 5 0 6 0 7 0 8 1 9 -1 10 1
我的程序(accepted):
#include <iostream> #include <string> using namespace std; string extractword(string str, int index, bool afterdigit, int& step, bool& isdigit, int& digit, bool& neg) { string word; neg = false; isdigit = false; digit = 0; step = 0; bool effective = false; bool repeatedzero = false; if(!afterdigit) { effective = true; } for(int i = index; i < str.length(); ++i) { step++; if(str[i] == '-' || str[i] == '+') { if(i == index) { if(!afterdigit && str[i] == '-') { neg = true; } } else { if(isdigit & neg) { digit *= -1; } step--; return word; } if(!afterdigit && i + 1 < str.length() && (str[i + 1] <= '9' && str[i + 1] >= '0')) { continue; } } if(str[i] <= '9' && str[i] >= '0') { if(!isdigit) { if(i != index && !(i == index + 1 && (str[index] == '+' || str[index] == '-') && effective)) { step--; return word; } } isdigit = true; afterdigit = true; digit = digit * 10 + str[i] - '0'; if(str[i] == '0' && i + 1 < str.length() && (str[i + 1] <= '9' && str[i + 1] >= '0')) { continue; } } if(str[i] <= 'Z' && str[i] >= 'A') { str[i] += 'a' - 'A'; } if(str[i] <= 'z' && str[i] >= 'a') { if(isdigit) { if(neg) { digit *= -1; } step--; return word; } } word.push_back(str[i]); } if(isdigit && neg) { digit *= -1; } return word; } int compare(string a, string b) { bool afterdigita = false, afterdigitb = false; int i = 0, j = 0; while(i < a.length() && j < b.length()) { int stepa = 0, stepb = 0; bool isdigita = false, isdigitb = false; bool isnega = false, isnegb = false; int digita = -1, digitb = -1; string worda = extractword(a, i, afterdigita, stepa, isdigita, digita, isnega); string wordb = extractword(b, j, afterdigitb, stepb, isdigitb, digitb, isnegb); if(isdigita) { afterdigita = true; } else { afterdigita = false; } if(isdigitb) { afterdigitb = true; } else { afterdigitb = false; } if(isdigita && isdigitb) { if(isnega && !isnegb) { if(worda == "0" && wordb == "0") { return 0; } else { return -1; } } if(isnegb && !isnega) { if(worda == "0" && wordb == "0") { return 0; } else { return -1; } } if(worda.length() != wordb.length()) { if(isnega) { return worda.length() < wordb.length() ? 1 : -1; } else { return worda.length() < wordb.length() ? -1 : 1; } } for(int i = 0; i < worda.length(); ++i) { if(worda[i] != wordb[i]) { if(isnega) { return (worda[i] - '0') < (wordb[i] - '0') ? 1 : -1; } else { return (worda[i] - '0') < (wordb[i] - '0') ? -1 : 1; } } } /* if(digita < digitb) { return -1; } else if(digita > digitb) { return 1; } */ } else { if(worda < wordb) { return -1; } else if(worda > wordb) { return 1; } } i += stepa; j += stepb; } if(i < a.length()) { return 1; } if(j < b.length()) { return -1; } return 0; } int main() { int N; cin>>N; for(int no = 0; no < N; ++no) { string a, b; cin>>a>>b; //cout<<"a: "<<a<<", b: "<<b<<endl; cout<<no + 1<<" "; cout<<compare(a, b)<<endl; } return 0; }