이것을 확인하는 몇 가지 방법을 알고 있습니다. 정규식, int.parse,, tryparse반복.
누구든지 가장 빠른 확인 방법을 말해 줄 수 있습니까?
필요는 것입니다 확인하지 실제로 구문 분석에 필요합니다.
이것은 다음과 같은 질문이 아닙니다 : 문자열이 숫자인지 어떻게 알 수 있습니까?
문제는 어떻게 식별 하는가에 관한 것이 아닙니다. 가장 빠른 방법 은 무엇입니까 ?
return str.All(Char.IsDigit);
이것을 확인하는 몇 가지 방법을 알고 있습니다. 정규식, int.parse,, tryparse반복.
누구든지 가장 빠른 확인 방법을 말해 줄 수 있습니까?
필요는 것입니다 확인하지 실제로 구문 분석에 필요합니다.
이것은 다음과 같은 질문이 아닙니다 : 문자열이 숫자인지 어떻게 알 수 있습니까?
문제는 어떻게 식별 하는가에 관한 것이 아닙니다. 가장 빠른 방법 은 무엇입니까 ?
return str.All(Char.IsDigit);
답변:
bool IsDigitsOnly(string str)
{
foreach (char c in str)
{
if (c < '0' || c > '9')
return false;
}
return true;
}
아마 가장 빠른 방법 일 것입니다.
char.IsDigit()
IsDigit는 true약 3 백 자 이상의 문자를 반환 합니다. 전각 10 진수 0123(중국과 일본에서 일반적)와 다른 문화권의 숫자 ০১২௧௨௩௪꘤꘥꘦꘧꘨등을 포함합니다.
return str.All(c => c >= '0' && c <= '9');
return str.All(char.IsDigit);. 분석법 그룹을위한 만세!
동일한 문자열의 1000000 구문 분석을 기반으로 한 벤치 마크가 있습니다.
release통계 업데이트 :
IsDigitsOnly: 384588
TryParse: 639583
Regex: 1329571
다음은 코드입니다. IsDigitsOnly가 더 빠릅니다.
class Program
{
private static Regex regex = new Regex("^[0-9]+$", RegexOptions.Compiled);
static void Main(string[] args)
{
Stopwatch watch = new Stopwatch();
string test = int.MaxValue.ToString();
int value;
watch.Start();
for(int i=0; i< 1000000; i++)
{
int.TryParse(test, out value);
}
watch.Stop();
Console.WriteLine("TryParse: "+watch.ElapsedTicks);
watch.Reset();
watch.Start();
for (int i = 0; i < 1000000; i++)
{
IsDigitsOnly(test);
}
watch.Stop();
Console.WriteLine("IsDigitsOnly: " + watch.ElapsedTicks);
watch.Reset();
watch.Start();
for (int i = 0; i < 1000000; i++)
{
regex.IsMatch(test);
}
watch.Stop();
Console.WriteLine("Regex: " + watch.ElapsedTicks);
Console.ReadLine();
}
static bool IsDigitsOnly(string str)
{
foreach (char c in str)
{
if (c < '0' || c > '9')
return false;
}
return true;
}
}
물론 TryParse는 문화적 기호뿐만 아니라 선행 / 후행 공백도 허용합니다. 또한 문자열 길이에 제한이 있습니다.
intTryParse가 false를 반환합니다.
LINQ를 사용하여 간단히 할 수 있습니다.
return str.All(char.IsDigit);
.All 빈 문자열에 대해서는 true를 반환하고 null 문자열에 대해서는 예외를 반환합니다.char.IsDigit 모든 유니 코드 문자에 적용됩니다.char에는 이미 이것을 수행하는 IsDigit (char c)가 있습니다.
public static bool IsDigit(char c)
{
if (!char.IsLatin1(c))
return CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber;
if ((int) c >= 48)
return (int) c <= 57;
else
return false;
}
당신은 단순히 이것을 할 수 있습니다 :
var theString = "839278";
bool digitsOnly = theString.All(char.IsDigit);
다음 char과 같이 for대신 하나의 비교 만 사용하여 약 20 % 더 빠를 수 있습니다 foreach.
bool isDigits(string s)
{
if (s == null || s == "") return false;
for (int i = 0; i < s.Length; i++)
if ((s[i] ^ '0') > 9)
return false;
return true;
}
테스트에 사용되는 코드 (결과는 하드웨어, 버전, 순서 등에 따라 달라지기 때문에 항상 프로파일 링됨) :
static bool isDigitsFr(string s) { if (s == null || s == "") return false; for (int i = 0; i < s.Length; i++) if (s[i] < '0' || s[i] > '9') return false; return true; }
static bool isDigitsFu(string s) { if (s == null || s == "") return false; for (int i = 0; i < s.Length; i++) if ((uint)(s[i] - '0') > 9) return false; return true; }
static bool isDigitsFx(string s) { if (s == null || s == "") return false; for (int i = 0; i < s.Length; i++) if ((s[i] ^ '0') > 9) return false; return true; }
static bool isDigitsEr(string s) { if (s == null || s == "") return false; foreach (char c in s) if (c < '0' || c > '9') return false; return true; }
static bool isDigitsEu(string s) { if (s == null || s == "") return false; foreach (char c in s) if ((uint)(c - '0') > 9) return false; return true; }
static bool isDigitsEx(string s) { if (s == null || s == "") return false; foreach (char c in s) if ((c ^ '0') > 9) return false; return true; }
static void test()
{
var w = new Stopwatch(); bool b; var s = int.MaxValue + ""; int r = 12345678*2; var ss = new SortedSet<string>(); //s = string.Concat(Enumerable.Range(0, 127).Select(i => ((char)i ^ '0') < 10 ? 1 : 0));
w.Restart(); for (int i = 0; i < r; i++) b = s.All(char.IsDigit); w.Stop(); ss.Add(w.Elapsed + ".All .IsDigit");
w.Restart(); for (int i = 0; i < r; i++) b = s.All(c => c >= '0' && c <= '9'); w.Stop(); ss.Add(w.Elapsed + ".All <>");
w.Restart(); for (int i = 0; i < r; i++) b = s.All(c => (c ^ '0') < 10); w.Stop(); ss.Add(w.Elapsed + " .All ^");
w.Restart(); for (int i = 0; i < r; i++) b = isDigitsFr(s); w.Stop(); ss.Add(w.Elapsed + " for <>");
w.Restart(); for (int i = 0; i < r; i++) b = isDigitsFu(s); w.Stop(); ss.Add(w.Elapsed + " for -");
w.Restart(); for (int i = 0; i < r; i++) b = isDigitsFx(s); w.Stop(); ss.Add(w.Elapsed + " for ^");
w.Restart(); for (int i = 0; i < r; i++) b = isDigitsEr(s); w.Stop(); ss.Add(w.Elapsed + " foreach <>");
w.Restart(); for (int i = 0; i < r; i++) b = isDigitsEu(s); w.Stop(); ss.Add(w.Elapsed + " foreach -");
w.Restart(); for (int i = 0; i < r; i++) b = isDigitsEx(s); w.Stop(); ss.Add(w.Elapsed + " foreach ^");
MessageBox.Show(string.Join("\n", ss)); return;
}
Intel i5-3470 @ 3.2GHz, VS 2015 .NET 4.6.1 릴리스 모드 및 최적화 사용 결과 :
time method ratio
0.7776 for ^ 1.0000
0.7984 foreach - 1.0268
0.8066 foreach ^ 1.0372
0.8940 for - 1.1497
0.8976 for <> 1.1543
0.9456 foreach <> 1.2160
4.4559 .All <> 5.7303
4.7791 .All ^ 6.1458
4.8539 .All. IsDigit 6.2421
더 짧은 방법을 사용하려는 유혹을 가진 사람은
.All결과 true빈 문자열 과 예외 null문자열char.IsDigitNd 범주의 모든 유니 코드 문자에 해당됩니다.int.TryParse 화이트 스페이스 및 사인 문자도 허용당신은 성능, 사용도에 대해 우려하는 경우 int.TryParse도 Regex- 자신의 (단순) 함수 쓰기 ( DigitsOnly또는 DigitsOnly2아래,하지만 하지 DigitsOnly3 - LINQ는 상당한 오버 헤드가 발생하는 것 같다).
또한 int.TryParse문자열이 너무 길어서에 맞지 않으면 실패 할 것 int입니다.
이 간단한 벤치 마크는 ...
class Program {
static bool DigitsOnly(string s) {
int len = s.Length;
for (int i = 0; i < len; ++i) {
char c = s[i];
if (c < '0' || c > '9')
return false;
}
return true;
}
static bool DigitsOnly2(string s) {
foreach (char c in s) {
if (c < '0' || c > '9')
return false;
}
return true;
}
static bool DigitsOnly3(string s) {
return s.All(c => c >= '0' && c <= '9');
}
static void Main(string[] args) {
const string s1 = "916734184";
const string s2 = "916734a84";
const int iterations = 1000000;
var sw = new Stopwatch();
sw.Restart();
for (int i = 0 ; i < iterations; ++i) {
bool success = DigitsOnly(s1);
bool failure = DigitsOnly(s2);
}
sw.Stop();
Console.WriteLine(string.Format("DigitsOnly: {0}", sw.Elapsed));
sw.Restart();
for (int i = 0; i < iterations; ++i) {
bool success = DigitsOnly2(s1);
bool failure = DigitsOnly2(s2);
}
sw.Stop();
Console.WriteLine(string.Format("DigitsOnly2: {0}", sw.Elapsed));
sw.Restart();
for (int i = 0; i < iterations; ++i) {
bool success = DigitsOnly3(s1);
bool failure = DigitsOnly3(s2);
}
sw.Stop();
Console.WriteLine(string.Format("DigitsOnly3: {0}", sw.Elapsed));
sw.Restart();
for (int i = 0; i < iterations; ++i) {
int dummy;
bool success = int.TryParse(s1, out dummy);
bool failure = int.TryParse(s2, out dummy);
}
sw.Stop();
Console.WriteLine(string.Format("int.TryParse: {0}", sw.Elapsed));
sw.Restart();
var regex = new Regex("^[0-9]+$", RegexOptions.Compiled);
for (int i = 0; i < iterations; ++i) {
bool success = regex.IsMatch(s1);
bool failure = regex.IsMatch(s2);
}
sw.Stop();
Console.WriteLine(string.Format("Regex.IsMatch: {0}", sw.Elapsed));
}
}
... 다음 결과를 생성합니다 ...
DigitsOnly: 00:00:00.0346094
DigitsOnly2: 00:00:00.0365220
DigitsOnly3: 00:00:00.2669425
int.TryParse: 00:00:00.3405548
Regex.IsMatch: 00:00:00.7017648
이것은 작동해야합니다 :
Regex.IsMatch("124", "^[0-9]+$", RegexOptions.Compiled)
int.Parse또는 int.TryParse문자열이 INT가 보유 할 수 이상의 숫자를 포함 할 수 있기 때문에 항상 작동하지 않습니다.
이 검사를 두 번 이상 수행하려는 경우 컴파일 된 정규식을 사용하는 것이 유용합니다. 처음에는 시간이 더 걸리지 만 그 이후에는 훨씬 빠릅니다.
한 줄의 LINQ 문에서이 작업을 수행 할 수 있습니다. OK, 이것이 이것이 가장 빠른 것은 아니라는 것을 알고 기술적으로 질문에 대답하지는 않지만 아마도 가장 작성하기 쉽습니다.
str.All(c => c >= '0' && c <= '9')
str.All(char.IsDigit)작성하기는 쉽지만 물론 코드와 동일하지는 않습니다.
IsDigit은 유니 코드를 지원합니다. 따라서 Microsoft가 구현할 때 선택한 시간 메모리 상충 관계에 따라 수표가 상당히 비쌀 수 있습니다. 네이티브 코드로 전달한다고 가정하면 전환 비용도 상당히 많이들 수 있습니다.
.IsMatch(string input, string pattern)C # 의 방법 을 사용하여 숫자 (0-9) 만 입력 문자열을 테스트하여 정규식을 사용해 볼 수 있습니다 .
using System;
using System.Text.RegularExpression;
public namespace MyNS
{
public class MyClass
{
public void static Main(string[] args)
{
string input = Console.ReadLine();
bool containsNumber = ContainsOnlyDigits(input);
}
private bool ContainOnlyDigits (string input)
{
bool containsNumbers = true;
if (!Regex.IsMatch(input, @"/d"))
{
containsNumbers = false;
}
return containsNumbers;
}
}
}
문안 인사
이것은 완벽하게 작동하며 다른 많은 방법이 있지만 작동합니다.
bool IsDigitsOnly(string str)
{
if (str.Length > 0)//if contains characters
{
foreach (char c in str)//assign character to c
{
if (c < '0' || c > '9')//check if its outside digit range
return false;
}
}else//empty string
{
return false;//empty string
}
return true;//only digits
}
이 코드를 사용해보십시오 :
bool isDigitsOnly(string str)
{
try
{
int number = Convert.ToInt32(str);
return true;
}
catch (Exception)
{
return false;
}
}
Convert.ToInt32o (n)보다 빠르게 실행 되면 매우 놀랐습니다 . 이 가정을 뒷받침 할 증거가 있습니까?
문자열을 감지하는 매우 영리하고 쉬운 방법은 숫자 만 포함하거나 포함하지 않는 것입니다.
string s = "12fg";
if(s.All(char.IsDigit))
{
return true; // contains only digits
}
else
{
return false; // contains not only digits
}