这道题确实是正常人不适宜做。不过也可以作为代码严谨程度的考验。
我的解法实现相当混乱,无暇修改了,写这篇解题报告的目的有三:一是记录下自己的解题,二是附录相关的测试数据,可能会方便到一些同学。
这道题其实题目描述得挺准确的,没有特别不可理解的地方,比如“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;
}