如何随机排列字符串中的辅音?
How to shuffle consonants in a string?
在PHP中,我们知道可以使用函数str_shuffle()
随机打乱字符串字符。所以一个字符串 "developer"
每次都会变成 "lrevdeope", "dvolpeere"
等等。
但这不是我想要的。相反,我只想随机洗牌辅音。所以 "developer"
应该在每次页面刷新时变为 "verelodep", "leveroped"
等。
我们怎样才能实现呢?有什么想法吗?
几分钟后我得到了这个:
$s = 'developer';
$cons = [];
for ($i = 0; $i < strlen($s); $i++) {
if (!in_array($s[$i], ['a', 'e', 'i', 'o', 'u', 'y'])) {
$cons[] = $s[$i];
$s[$i] = '-';
}
}
shuffle($cons);
for ($i = 0; $i < strlen($s); $i++) {
if ($s[$i] == '-') {
$s[$i] = array_shift($cons);
}
}
echo $s . PHP_EOL;
您可以像这样创建自定义函数:
function shuffle_consonants($str) {
$str = str_split($str);
$vowels = ['a','e','i','o','u'];
foreach($str as $char)
if(!in_array($char, $vowels)) $con .= $char;
$con = str_shuffle($con);
$idx = 0;
foreach($str as &$char)
if(!in_array($char, $vowels)) $char = $con[$idx++];
return implode("", $str);
}
echo shuffle_consonants("developer");
好吧,这里有一个替代方案:
$word = "developer";
$letters = str_split($word);
$consonants = array_filter($letters, function ($letter) {
return !in_array($letter, ['a', 'e', 'i', 'o', 'u', 'y']);
}); //Get all consonants with their index
$consonantPositions = array_keys($consonants); //keep indexes (shuffle will lose them)
shuffle($consonants);
$letters = array_combine($consonantPositions, $consonants) + $letters; // put the shuffled consonants in their indexes and glue them back into the letters
ksort($letters); // put the keys back in their place
echo implode("",$letters);
我很欣赏 u_mulder 方法的总体设计,但我想为任何可能感兴趣的读者做一些 refinements/micro-optimizations。
- 存储
strlen()
值以便 php 不必重复生成它。
调用strpos()
区分元音和辅音。 (参考:in_array vs strpos for performance in php)
暂时不要将输入字符串中的辅音字母替换为-
。
- 在第二个循环中只迭代辅音(相对于迭代字符串中的所有字母)。
- 在不调用函数的情况下对字符串进行替换。
代码:(Demo)
$string="developer";
$consonants=[];
$length=strlen($string);
for($offset=0; $offset<$length; ++$offset){ // iterate each letter of the string ... OR for($offset=strlen($string); --$offset;){
if(strpos('aeiou',$string[$offset])===false){ // isolate the consonants
$consonants[]=$string[$offset]; // store the consonant
$offsets[]=$offset; // store the offset (aka indexed position of the consonant in the string)
}
}
shuffle($consonants); // shuffle the array of stored consonants
foreach($consonants as $index=>$consonant){ // iterate ONLY the stored consonants
$string[$offsets[$index]]=$consonant; // reassign the consonants in their new positions
}
echo $string; // possible output: revepoled
这里是数组函数与 foreach 循环的混合,用于重新插入打乱的辅音:
$string="developer";
$consonants=array_diff(str_split($string),['a', 'e', 'i', 'o', 'u']); // isolate consonants, preserve offsets as keys
$offsets=array_keys($consonants); // store copy of offsets before shuffling
shuffle($consonants); // shuffle the array of stored consonants (returned value is re-indexed)
foreach($consonants as $i=>$consonant){
$string[$offsets[$i]]=$consonant; // reassign the shuffled consonants at the known consonant positions
}
echo $string;
对于那些认为我没有任何独立想法可提供的人...这是另一种方法,它将实现两个字符串函数调用,然后是一个正则表达式函数调用(这会对速度产生负面影响,但并不可怕)可以写成两行。
代码:(Demo)
$word="developer";
$shuffled_consonants=str_shuffle(str_replace(['a','e','i','o','u'],'',$word)); // generate shuffled string of consonants
// reinsert shuffled consonants at original consonant positions
echo preg_replace_callback(
'~[^aeiou]~', // match each consonant at original position
function($m)use($shuffled_consonants){ // pass in the shuffled string
static $offset=0; // init the offset counter
return $shuffled_consonants[$offset++]; // insert new consonant at original position using post-incrementation
},
$word);
在PHP中,我们知道可以使用函数str_shuffle()
随机打乱字符串字符。所以一个字符串 "developer"
每次都会变成 "lrevdeope", "dvolpeere"
等等。
但这不是我想要的。相反,我只想随机洗牌辅音。所以 "developer"
应该在每次页面刷新时变为 "verelodep", "leveroped"
等。
我们怎样才能实现呢?有什么想法吗?
几分钟后我得到了这个:
$s = 'developer';
$cons = [];
for ($i = 0; $i < strlen($s); $i++) {
if (!in_array($s[$i], ['a', 'e', 'i', 'o', 'u', 'y'])) {
$cons[] = $s[$i];
$s[$i] = '-';
}
}
shuffle($cons);
for ($i = 0; $i < strlen($s); $i++) {
if ($s[$i] == '-') {
$s[$i] = array_shift($cons);
}
}
echo $s . PHP_EOL;
您可以像这样创建自定义函数:
function shuffle_consonants($str) {
$str = str_split($str);
$vowels = ['a','e','i','o','u'];
foreach($str as $char)
if(!in_array($char, $vowels)) $con .= $char;
$con = str_shuffle($con);
$idx = 0;
foreach($str as &$char)
if(!in_array($char, $vowels)) $char = $con[$idx++];
return implode("", $str);
}
echo shuffle_consonants("developer");
好吧,这里有一个替代方案:
$word = "developer";
$letters = str_split($word);
$consonants = array_filter($letters, function ($letter) {
return !in_array($letter, ['a', 'e', 'i', 'o', 'u', 'y']);
}); //Get all consonants with their index
$consonantPositions = array_keys($consonants); //keep indexes (shuffle will lose them)
shuffle($consonants);
$letters = array_combine($consonantPositions, $consonants) + $letters; // put the shuffled consonants in their indexes and glue them back into the letters
ksort($letters); // put the keys back in their place
echo implode("",$letters);
我很欣赏 u_mulder 方法的总体设计,但我想为任何可能感兴趣的读者做一些 refinements/micro-optimizations。
- 存储
strlen()
值以便 php 不必重复生成它。 调用
strpos()
区分元音和辅音。 (参考:in_array vs strpos for performance in php)暂时不要将输入字符串中的辅音字母替换为
-
。- 在第二个循环中只迭代辅音(相对于迭代字符串中的所有字母)。
- 在不调用函数的情况下对字符串进行替换。
代码:(Demo)
$string="developer";
$consonants=[];
$length=strlen($string);
for($offset=0; $offset<$length; ++$offset){ // iterate each letter of the string ... OR for($offset=strlen($string); --$offset;){
if(strpos('aeiou',$string[$offset])===false){ // isolate the consonants
$consonants[]=$string[$offset]; // store the consonant
$offsets[]=$offset; // store the offset (aka indexed position of the consonant in the string)
}
}
shuffle($consonants); // shuffle the array of stored consonants
foreach($consonants as $index=>$consonant){ // iterate ONLY the stored consonants
$string[$offsets[$index]]=$consonant; // reassign the consonants in their new positions
}
echo $string; // possible output: revepoled
这里是数组函数与 foreach 循环的混合,用于重新插入打乱的辅音:
$string="developer";
$consonants=array_diff(str_split($string),['a', 'e', 'i', 'o', 'u']); // isolate consonants, preserve offsets as keys
$offsets=array_keys($consonants); // store copy of offsets before shuffling
shuffle($consonants); // shuffle the array of stored consonants (returned value is re-indexed)
foreach($consonants as $i=>$consonant){
$string[$offsets[$i]]=$consonant; // reassign the shuffled consonants at the known consonant positions
}
echo $string;
对于那些认为我没有任何独立想法可提供的人...这是另一种方法,它将实现两个字符串函数调用,然后是一个正则表达式函数调用(这会对速度产生负面影响,但并不可怕)可以写成两行。
代码:(Demo)
$word="developer";
$shuffled_consonants=str_shuffle(str_replace(['a','e','i','o','u'],'',$word)); // generate shuffled string of consonants
// reinsert shuffled consonants at original consonant positions
echo preg_replace_callback(
'~[^aeiou]~', // match each consonant at original position
function($m)use($shuffled_consonants){ // pass in the shuffled string
static $offset=0; // init the offset counter
return $shuffled_consonants[$offset++]; // insert new consonant at original position using post-incrementation
},
$word);