2013-07-06 8 views

Odpowiedz

14

Możesz porównać IndexOf do LastIndexOf aby sprawdzić, czy jest więcej niż jeden specyficzny charakter w string bez wyraźnej liczenia:

var s = "12121.23.2"; 
var ch = '.'; 
if (s.IndexOf(ch) != s.LastIndexOf(ch)) { 
    ... 
} 
+0

Nie powiedzie się, jeśli znak nie jest obecny, ponieważ oba indeksy mają wartość -1. –

+3

@DrewNoakes Dlaczego? Jeśli znak nie występuje wcale, obie funkcje zwracają '-1', więc'! = 'Zwraca wartość 'false'. Potrzebujesz dwóch lub więcej znaków: zero lub jeden znak, pierwszy i ostatni indeks są takie same (rzeczywisty indeks lub '-1'). – dasblinkenlight

+0

Ugh, tak, masz rację :) Mój błąd. –

7

Można łatwo policzyć liczbę wystąpień o charakterze z LINQ:

string foo = "12121.23.2"; 
foo.Count(c => c == '.'); 
2
Boolean MoreThanOne(String str, Char c) 
{ 
    return str.Count(x => x==c) > 1; 
} 
+0

ciąg znaków i znak nie mogą mieć takiego samego znaku w nich – Arka

+0

Tak i nie używam go ani w mojej odpowiedzi, proszę zrozumieć, co robię, jeśli nie rozumiesz, spróbuj uruchomić i przekonaj się, czy to działa, czy nie. –

6

Jeżeli kwestie wydajności, napisać go samodzielnie:

public static bool ContainsDuplicateCharacter(this string s, char c) 
{ 
    bool seenFirst = false; 
    for (int i = 0; i < s.Length; i++) 
    { 
     if (s[i] != c) 
      continue; 
     if (seenFirst) 
      return true; 
     seenFirst = true; 
    } 
    return false; 
} 

W ten sposób przechodzisz tylko jedną treść ciągu, a wyskakujesz jak najwcześniej. W najgorszym przypadku odwiedzasz wszystkie postacie tylko raz. W odpowiedzi @ dasblinkenlight odwiedzasz wszystkie postacie dwa razy, aw odpowiedzi @ mensi musisz liczyć wszystkie wystąpienia, nawet jeśli masz dwa, możesz zatrzymać obliczenia. Ponadto, przy użyciu metody rozszerzania Count wykorzystuje się Enumerable<char>, który będzie działał wolniej niż bezpośredni dostęp do znaków w określonych indeksach.

Następnie można napisać:

string s = "12121.23.2"; 

Debug.Assert(s.ContainsDuplicateCharacter('.')); 
Debug.Assert(s.ContainsDuplicateCharacter('1')); 
Debug.Assert(s.ContainsDuplicateCharacter('2')); 
Debug.Assert(!s.ContainsDuplicateCharacter('3')); 
Debug.Assert(!s.ContainsDuplicateCharacter('Z')); 

Ja też myślę, że to ładniejszy mieć funkcję, która wyjaśnia dokładnie, co próbujesz osiągnąć. Można jednak owijać dowolne inne odpowiedzi w takiej funkcji.

0

Odpowiedź dasblinkenlight jest prawie poprawna. Musisz również sprawdzić, czy łańcuch faktycznie zawiera "." w tym. Ponieważ zarówno IndexOf(), jak i LastIndexOf() zwrócą -1 w przypadku, gdy nie ma "." char w ciągu znaków.

Tutaj jest korygowany przykład:

var s = "12121.23.2"; 
var ch = '.'; 
if ((s.IndexOf(ch) >= 0) && (s.IndexOf(ch) != s.LastIndexOf(ch))) { 
    ... 
} 

EDIT: źle, nie ma potrzeby, aby sprawdzić, czy rzeczywiście zawiera ciąg znaków ''.

+0

Źle, zobacz komentarz na jego odpowiedź – mensi

+0

Tak, widzę. Mój błąd. – Aleksei

Powiązane problemy