如何从字符串中找到第一个非重复字符?

时间:2010-06-02 06:58:36

标签: php string

我花了半天的时间试图弄清楚这一点,最后我得到了解决方案。 但是,我觉得这可以用更简单的方式完成。 我认为这段代码不是真的可读。

问题:从字符串中查找第一个非重复字符。

$ string =“abbcabz”

在这种情况下,函数应输出“c”。

我使用连接而不是$input[index_to_remove] = ''的原因 为了从给定的字符串中删除字符 是因为如果我这样做,它实际上只留下空单元格,以便我的 返回值$ input [0]不会返回我想要返回的字符。

例如,

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

这将输出“bc”

但实际上,如果我测试,

var_dump($str);

它会给我:

string(3) "bc"

这是我的意图:

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

代码:

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];
}

10 个答案:

答案 0 :(得分:10)

<?php
    // In an array mapped character to frequency, 
    // find the first character with frequency 1.
    echo array_search(1, array_count_values(str_split('abbcabz')));

答案 1 :(得分:2)

的Python:

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

在PHP中相同:

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

答案 2 :(得分:1)

伪代码:

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

基本上,您会在字符串中找到所有不同的字母,并且对于每个字母,您将其与字符串中存在的字母数量相关联。然后你返回第一个计数为1

的人

如果使用数组,在最坏的情况下,此方法的复杂性为O(n ^ 2)。您可以使用关联数组来提高其性能。

答案 3 :(得分:1)

这可以使用一些标准的PHP函数在更易读的代码中完成:

// 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;

答案 4 :(得分:1)

1-使用像mergesort这样的排序算法(或者quicksort在小输入时具有更好的性能)
2-然后控制重复字符

  
      
  • 非重复字符将为单
  •   
  • repetetvives将相互休闲
  •   

表现:排序+比较
性能:O(n log n)+ O(n)= O(n log n)
例如

    $string = "abbcabz"

    $string = mergesort ($string)
    // $string = "aabbbcz" 
  

然后取第一个char表单字符串,然后与下一个匹配,如果匹配repetetive
  移动到下一个不同的角色并进行比较   第一个不匹配的字符是非重复的

答案 5 :(得分:1)

这是Scala中的一个函数:

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)
  }
}

阶&GT; firstUnique( “abbcabz” .toList)
res5:选项[Char] = Some(c)

这就是Haskell中的等价物:

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

*主&GT; firstUnique“abbcabz”

只是'c'

您可以更一般地通过抽象可以比较相等的事物列表来解决这个问题:

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

字符串就是这样一个列表。

答案 6 :(得分:1)

$str="abbcade";
$checked= array(); // we will store all checked characters in this array, so we do not have to check them again

for($i=0; $i<strlen($str); $i++)
{
    $c=0;
    if(in_array($str[$i],$checked)) continue;

    $checked[]=$str[$i];

    for($j=$i+1;$j<=strlen($str);$j++)
    {
        if($str[$i]==$str[$j]) 
        {
            $c=1;
            break;  
        }
    }
    if($c!=1) 
    {
        echo "First non repetive char is:".$str[$i]; 
        break;
    }
}

答案 7 :(得分:1)

这应该替换你的代码...


$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));

编辑:说得太早了。拿出'array_unique',认为它实际上删除了重复的值。但是要保留字符顺序 以便能够找到第一个字符。

答案 8 :(得分:0)

在从array_key_exists构建关联array的过程中,也可以使用string完成操作。每个字符将是一个键,并将数字记为值。

$sample = "abbcabz";

$check = [];
for($i=0; $i<strlen($sample); $i++)
{
    if(!array_key_exists($sample[$i], $check))
    {
        $check[$sample[$i]] = 1;
    }
    else
    {
        $check[$sample[$i]] += 1;
    }
}

echo array_search(1, $check);

答案 9 :(得分:0)

此函数使您能够返回第一个不重复的字符

对于 s = "abacabad",输出应为 firstNotRepeatingCharacter(s) = 'c'
字符串中有 2 个非重复字符:'c''d'
返回 c,因为它首先出现在字符串中。

对于s = "abacabaabacaba",输出应该是 firstNotRepeatingCharacter(s) = '_'
此字符串中没有不重复的字符。

function firstNotRepeatingCharacter($s) {
    $array = str_split($s);
    $context = array_count_values($array);
    $r = array_search(1, $context);
    if($r != null) {
        return $r;
    }
    return '_';
}