Appearance
20-表示数值的字符串
题目描述
https://leetcode.cn/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
数值(按顺序)可以分成以下几个部分:
若干空格 一个小数或者整数 (可选)一个'e'或'E',后面跟着一个整数 若干空格 小数(按顺序)可以分成以下几个部分:
(可选)一个符号字符('+' 或 '-') 下述格式之一: 至少一位数字,后面跟着一个点 '.' 至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字 一个点 '.' ,后面跟着至少一位数字 整数(按顺序)可以分成以下几个部分:
(可选)一个符号字符('+' 或 '-') 至少一位数字 部分数值列举如下:
["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"] 部分非数值列举如下:
["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]
示例 1:
输入:s = "0"
输出:true
示例 2:
输入:s = "e"
输出:false
示例 3:
输入:s = "."
输出:false
示例 4:
输入:s = ".1"
输出:true
提示:
1 <= s.length <= 20 s 仅含英文字母(大写和小写),数字(0-9),加号 '+' ,减号 '-' ,空格 ' ' 或者点 '.' 。
思路【未完成】
- Trim 去掉首尾空格
- 判断全整型函数 IsUnsignInt(string s)
实现代码
csharp
public class Solution {
private bool IsUnsignInt(string s, int start){
for(int i=start; i<s.Length; i++){
if(s[i] >= '0' && s[i] <= '9'){
}
else{
return false;
}
}
return true;
}
private bool IsInt(string s, int start){
if(s[start] == '+' || s[start] == '-'){
return IsUnsignInt(s,start+1);
}
else{
return IsUnsignInt(s,start);
}
}
private bool IsNumber(string s, int start){
}
public bool IsNumber(string s) {
s = s.Trim();
//判断首字母
return IsNumber(s,0);
}
}
思路2:【官方:状态机】
csharp
public class Solution {
public bool IsNumber(string s) {
Dictionary<State, Dictionary<CharType, State>> transfer = new Dictionary<State, Dictionary<CharType, State>>();
Dictionary<CharType, State> initialDictionary = new Dictionary<CharType, State> {
{CharType.CHAR_SPACE, State.STATE_INITIAL},
{CharType.CHAR_NUMBER, State.STATE_INTEGER},
{CharType.CHAR_POINT, State.STATE_POINT_WITHOUT_INT},
{CharType.CHAR_SIGN, State.STATE_INT_SIGN}
};
transfer.Add(State.STATE_INITIAL, initialDictionary);
Dictionary<CharType, State> intSignDictionary = new Dictionary<CharType, State> {
{CharType.CHAR_NUMBER, State.STATE_INTEGER},
{CharType.CHAR_POINT, State.STATE_POINT_WITHOUT_INT}
};
transfer.Add(State.STATE_INT_SIGN, intSignDictionary);
Dictionary<CharType, State> integerDictionary = new Dictionary<CharType, State> {
{CharType.CHAR_NUMBER, State.STATE_INTEGER},
{CharType.CHAR_EXP, State.STATE_EXP},
{CharType.CHAR_POINT, State.STATE_POINT},
{CharType.CHAR_SPACE, State.STATE_END}
};
transfer.Add(State.STATE_INTEGER, integerDictionary);
Dictionary<CharType, State> pointDictionary = new Dictionary<CharType, State> {
{CharType.CHAR_NUMBER, State.STATE_FRACTION},
{CharType.CHAR_EXP, State.STATE_EXP},
{CharType.CHAR_SPACE, State.STATE_END}
};
transfer.Add(State.STATE_POINT, pointDictionary);
Dictionary<CharType, State> pointWithoutIntDictionary = new Dictionary<CharType, State> {
{CharType.CHAR_NUMBER, State.STATE_FRACTION}
};
transfer.Add(State.STATE_POINT_WITHOUT_INT, pointWithoutIntDictionary);
Dictionary<CharType, State> fractionDictionary = new Dictionary<CharType, State> {
{CharType.CHAR_NUMBER, State.STATE_FRACTION},
{CharType.CHAR_EXP, State.STATE_EXP},
{CharType.CHAR_SPACE, State.STATE_END}
};
transfer.Add(State.STATE_FRACTION, fractionDictionary);
Dictionary<CharType, State> expDictionary = new Dictionary<CharType, State> {
{CharType.CHAR_NUMBER, State.STATE_EXP_NUMBER},
{CharType.CHAR_SIGN, State.STATE_EXP_SIGN}
};
transfer.Add(State.STATE_EXP, expDictionary);
Dictionary<CharType, State> expSignDictionary = new Dictionary<CharType, State> {
{CharType.CHAR_NUMBER, State.STATE_EXP_NUMBER}
};
transfer.Add(State.STATE_EXP_SIGN, expSignDictionary);
Dictionary<CharType, State> expNumberDictionary = new Dictionary<CharType, State> {
{CharType.CHAR_NUMBER, State.STATE_EXP_NUMBER},
{CharType.CHAR_SPACE, State.STATE_END}
};
transfer.Add(State.STATE_EXP_NUMBER, expNumberDictionary);
Dictionary<CharType, State> endDictionary = new Dictionary<CharType, State>() {
{CharType.CHAR_SPACE, State.STATE_END}
};
transfer.Add(State.STATE_END, endDictionary);
int length = s.Length;
State state = State.STATE_INITIAL;
for (int i = 0; i < length; i++) {
CharType type = ToCharType(s[i]);
if (!transfer[state].ContainsKey(type)) {
return false;
} else {
state = transfer[state][type];
}
}
return state == State.STATE_INTEGER || state == State.STATE_POINT || state == State.STATE_FRACTION || state == State.STATE_EXP_NUMBER || state == State.STATE_END;
}
CharType ToCharType(char ch) {
if (ch >= '0' && ch <= '9') {
return CharType.CHAR_NUMBER;
} else if (ch == 'e' || ch == 'E') {
return CharType.CHAR_EXP;
} else if (ch == '.') {
return CharType.CHAR_POINT;
} else if (ch == '+' || ch == '-') {
return CharType.CHAR_SIGN;
} else if (ch == ' ') {
return CharType.CHAR_SPACE;
} else {
return CharType.CHAR_ILLEGAL;
}
}
enum State {
STATE_INITIAL,
STATE_INT_SIGN,
STATE_INTEGER,
STATE_POINT,
STATE_POINT_WITHOUT_INT,
STATE_FRACTION,
STATE_EXP,
STATE_EXP_SIGN,
STATE_EXP_NUMBER,
STATE_END
}
enum CharType {
CHAR_NUMBER,
CHAR_EXP,
CHAR_POINT,
CHAR_SIGN,
CHAR_SPACE,
CHAR_ILLEGAL
}
}
思路3
首先去除空格,然后根据各个符号出现情况判断当前的数字是否合法。
参考代码
csharp
public class Solution {
public bool IsNumber(string s) {
// 思路,去除空格
// 遍历 记录是否 遇到过 . e 数字等信息
s = s.Trim();
bool seenDot = false;
bool seenE = false;
bool seenNum = false;
bool seenSign = false;
//依次判断
for(int i=0; i<s.Length; i++){
char c = s[i];
if(c >= '0' && c <= '9'){
seenNum = true;
}
else if(c == '+' || c == '-'){ //符号位只能出现在首位或者前一位是E
if(i!=0 && s[i-1] != 'E' && s[i-1] != 'e'){
return false;
}
seenSign = true;
}
else if(c == 'E' || c == 'e'){
if(seenE || !seenNum){
return false;
}
seenE = true;
seenNum = false; //注意遇到e的时候,因为后面必须要跟上数字,所以要把 seenNum 设置为 false
}
else if(c == '.'){
if(seenDot || seenE){
return false;
}
seenDot = true;
}
else{
return false;
}
}
return seenNum;
}
}
复习 : 20220611
csharp
public class Solution {
private void ScanNumber(string s, ref int i, ref bool hasNumber){
while(i < s.Length && s[i] >= '0' && s[i] <= '9'){
hasNumber = true;
i++;
}
}
public bool IsNumber(string s) {
int i = 0;
//判断空格
while(i<s.Length && s[i] == ' '){
i++;
}
if(i == s.Length){
return false;
}
//判断符号
bool hasSign = false;
if(s[i] == '+' || s[i] == '-'){
hasSign = true;
i++;
}
//判断数字
bool hasNumber = false;
ScanNumber(s,ref i,ref hasNumber);
bool hasDot = false;
//判断小数
if(i<s.Length && i < s.Length && s[i] == '.'){
hasDot = true;
i++;
ScanNumber(s,ref i,ref hasNumber);
}
//判断E
bool hasE = false;
if(i < s.Length && (s[i] == 'E' || s[i] == 'e') && hasNumber ){
hasE = true;
hasNumber = false;
i++;
ScanNumber(s,ref i,ref hasNumber);
//判断符号
bool hasESign = false;
if(i<s.Length && (s[i] == '+' || s[i] == '-')){
hasESign = true;
hasNumber = false;
i++;
}
ScanNumber(s,ref i,ref hasNumber);
}
while(i<s.Length && s[i] == ' '){
i++;
}
return i == s.Length && hasNumber;
}
}
AlgoPress