Bir dizeden olmayan ilk tekrarlayan karakteri bulmak için nasıl?

5 Cevap php

I've spent half day trying to figure out this and finally I got working solution. However, I feel like this can be done in simpler way. I think this code is not really readable.

Sorun: Bir dizeden olmayan ilk tekrarlayan karakterini bulun.

$ String = "abbcabz"

Bu durumda, fonksiyon çıktı "c" olmalıdır.

The reason I use concatenation instead of $input[index_to_remove] = '' in order to remove character from a given string is because if I do that, it actually just leave empty cell so that my return value $input[0] does not not return the character I want to return.

Örneğin,

$str = "abc";
$str[0] = '';
echo $str;

Bu irade çıktı "bc"

Ama aslında, eğer test

var_dump($str);

bana verecek:

string(3) "bc"

İşte benim niyeti:

Given: input

while first char exists in substring of input {
  get index_to_remove
  input = chars left of index_to_remove . chars right of index_to_remove

  if dupe of first char is not found from substring
     remove first char from input 
}
return first char of input

Kod:

function find_first_non_repetitive2($input) {

    while(strpos(substr($input, 1), $input[0]) !== false) {

        $index_to_remove = strpos(substr($input,1), $input[0]) + 1;
        $input = substr($input, 0, $index_to_remove) . substr($input, $index_to_remove + 1);

        if(strpos(substr($input, 1), $input[0]) == false) {
            $input = substr($input, 1);     
        }
    }
    return $input[0];
}

5 Cevap

Python:

def first_non_repeating(s):
 for i, c in enumerate(s):
  if s.find(c, i+1) < 0:
   return c
 return None

PHP aynı:

function find_first_non_repetitive($s)
{
 for($i = 0; i < strlen($s); i++) {
  if (strpos($s, $s[i], i+1) === FALSE)
   return $s[i];
 }
}

Pseudocode:

Array N;

For each letter in string
  if letter not exists in array N
    Add letter to array and set its count to 1
  else
    go to its position in array and increment its count
End for

for each position in array N
  if value at potition == 1
    return the letter at position and exit for loop
  else
    //do nothing (for clarity)
end for

Temelde, dize tüm farklı harfleri bulmak, ve her harf için, sen dize var kaç o harfin bir sayısı ile ilişkilendirmek. o zaman 1 sayısını sahip ilk birini döndürmek

Dizileri kullanarak bu yöntemin karmaşıklığı en kötü durumda O (n ^ 2) 'dir. Bunu performansını artırmak için bir ilişkisel dizi kullanabilirsiniz.

Bu bazı standart PHP işlevlerini kullanarak çok daha okunabilir kod yapılabilir:

// Count number of occurrences for every character
$counts = count_chars($string);

// Keep only unique ones (yes, we use this ugly pre-PHP-5.3 syntax here, but I can live with that)
$counts = array_filter($counts, create_function('$n', 'return $n == 1;'));

// Convert to a list, then to a string containing every unique character
$chars = array_map('chr', array_keys($counts));
$chars = implode($chars);

// Get a string starting from the any of the characters found
// This "strpbrk" is probably the most cryptic part of this code
$substring = strlen($chars) ? strpbrk($string, $chars) : '';

// Get the first character from the new string
$char = strlen($substring) ? $substring[0] : '';

// PROFIT!
echo $char;

Bu kodunuzu değiştirmeniz gerekir ...


$array = str_split($string);
$array = array_count_values($array);
$array = array_filter($array, create_function('$key,$val', 'return($val == 1);'));
$first_non_repeated_letter = key(array_shift($array));

Edit: çok yakında konuştu. 'Array_unique' çıkardı, aslında yinelenen değerleri düştü düşündüm. Ama karakter sırasını should ilk karakteri bulmak mümkün korunacaktır.

İşte bunu yapardı Scala bir fonksiyon:

def firstUnique(chars:List[Char]):Option[Char] = chars match { 
  case Nil => None
  case head::tail => {
    val filtered = tail filter (_!=head)
    if (tail.length == filtered.length) Some(head) else firstUnique(filtered)
  }
}

scala> firstUnique("abbcabz".toList)
res5: Option[Char] = Some(c)

Ve burada Haskell eşdeğerdir:

firstUnique :: [Char] -> Maybe Char
firstUnique [] = Nothing
firstUnique (head:tail) = let filtered = (filter (/= head) tail) in
            if (tail == filtered) then (Just head) else (firstUnique filtered)

* Ana> firstUnique "abbcabz"

Sadece 'c'

Için eşitlik karşılaştırıldığında edilebilir şeyler listeleri üzerinde soyutlayarak daha genelde bu çözebilir:

firstUnique :: Eq a => [a] -> Maybe a

Dizeler sadece böyle bir listesi vardır.