原题是为了识别数字,实现如下:
#include <iostream>
#include <algorithm>
#include <windows.h>
using namespace std;
class solution
{
public:
solution() {}
bool isNumberic(const char* str)
{
//char* 转string
string tmpstr = str;
const char point = '.';
const char scienceCountP = 'e'; //科学计数法;
const char scienceCountN = 'E';
const char positive = '+';
const char negtive = '-';
//隔离 . + - e E;
int LenthOfStr = tmpstr.length();
for(int i = 0; i < LenthOfStr; ++i)
{
if(((tmpstr[i] > '9') || (tmpstr[i] < '0'))
&& (tmpstr[i] != point) && (scienceCountN != tmpstr[i])
&& (scienceCountP != tmpstr[i])
&& (positive != tmpstr[i]) && (negtive != tmpstr[i]))
{ return false; }
}
int positionOfe = -1;
// int positionOfPoint = -1;
int numOfPoint = count(tmpstr.begin(), tmpstr.end(), point); //小数点数量
int numOfP = count(tmpstr.begin(), tmpstr.end(), scienceCountP);//e数量
int numOfN = count(tmpstr.begin(), tmpstr.end(), scienceCountN);//E数量
//int numberOfSign = count(tmpstr.begin(), tmpstr.end(), positive) + count(tmpstr.begin(), tmpstr.end(), negtive);
if(numOfPoint > 1) return false; //小数点多余1,非法;
if(numOfN+numOfP > 1) return false; //科学计数多余1,非法。这里将12e(12e12)这种套娃式表达视为无效;
//以科学计数法为界分割字符串,两个子串中不可再有字符。
if((string::npos != ( positionOfe = tmpstr.find(scienceCountP)))\
|| (string::npos != (positionOfe = tmpstr.find(scienceCountN))))
{
//以e\E分割字符串;
string substr0 = tmpstr.substr(0, positionOfe);
string substr1 = "";
if((LenthOfStr-1) == substr0.length())
return false; //对应5e这种非法情况;
else{
substr1 = tmpstr.substr(positionOfe+1);
}
if(string::npos != substr1.find(point)) return false; //科学表示法的指数位置不能有小数点
//任一个子串中正负号数量不可大于1;
if((1 < (count(substr0.begin(), substr0.end(), positive) + count(substr0.begin(), substr0.end(), negtive)))
|| (1 < (count(substr1.begin(), substr1.end(), positive) + count(substr1.begin(), substr1.end(), negtive))))
{ return false; }
//若存在正负号,则符号必须在子串的首部;
if((string::npos != substr0.find(positive)) && (0 != substr0.find(positive))) return false;
if((string::npos != substr1.find(positive)) && (0 != substr1.find(positive))) return false;
if((string::npos != substr0.find(negtive)) && (0 != substr0.find(negtive))) return false;
if((string::npos != substr1.find(negtive)) && (0 != substr1.find(negtive))) return false;
}
else {
//无科学计数时,数中正负号不能大于1;
if(1 < (count(tmpstr.begin(), tmpstr.end(), positive) + count(tmpstr.begin(), tmpstr.end(), negtive))) return false;
}
return true;
}
};
class stop_watch
{
public:
stop_watch()
: elapsed_(0)
{
QueryPerformanceFrequency(&freq_);
}
~stop_watch(){}
public:
void start()
{
QueryPerformanceCounter(&begin_time_);
}
void stop()
{
LARGE_INTEGER end_time; //小心机:局部变量减少开销;
QueryPerformanceCounter(&end_time);
elapsed_ += (end_time.QuadPart - begin_time_.QuadPart) * 1000000 / freq_.QuadPart;
}
void restart()
{
elapsed_ = 0;
start();
}
double elapsed()
{
return static_cast<double>(elapsed_); //微秒
}
double elapsed_ms()
{
return elapsed_ / 1000.0; //毫秒
}
double elapsed_second()
{
return elapsed_ / 1000000.0; //秒
}
private:
LARGE_INTEGER freq_;
LARGE_INTEGER begin_time_;
long long elapsed_;
};
int main()
{
// solution verify;
// stop_watch watch;
// watch.start();
// const char* a = "5e2"; //所给示例全部满足;
// cout<<verify.isNumberic(a)<< endl;
// watch.stop();
// cout<<"spend time: "<<watch.elapsed_second()<<" s"<<endl;
return 0;
}
说明:这个代码块分成了多个部分,solution部分是原题答案。为了验证其运行时间,网上找了一个轮子精确记录时间,基于windows库(轮子的作者找不到了,有人看到请告知我一下)。
逻辑很简单,就是排除所有特殊字符,数特定字符的个数;没有异常再从e或E的位置切分字符,检查 . + - e E 的位置是否正确。
最后,这一答案检查题目所给的字符正确。
牛客网上的答案都是纯C实现的,那不是我想要的答案。