开发者

Re-arrange a string using every x letter position with PHP

开发者 https://www.devze.com 2023-01-20 15:57 出处:网络
I\'m trying to figure out how to re-arrange a string using every x position so that an exampleinput string of \"ABCDEFGHI\" and the x being 4 would yield DHCIFEGBA. Here\'s how I got that:

I'm trying to figure out how to re-arrange a string using every x position so that an example input string of "ABCDEFGHI" and the x being 4 would yield DHCIFEGBA. Here's how I got that:

The 1st letter is easy: it's character 4. [A, B, C, D]

The 2nd letter is also easy: it's character 8. [E, F, G, H]

The 3rd letter is mostly easy: it's character 3. This happens because I looped around as I counted, so I used I, A, B, C.

The 4th letter is where things get trickier: It's character 9. Because D and H are already gone, they don't get used in the count, resulting in E, F, G, I.

Letter #5 follows the same pattern, skipping C and D: A, B, E, F

Letter #6 has skips AND a wrap: G, A, B, E.

Letter #7 wraps again: G, A, B, G.

Letter #8 also wraps (technically twice since 'cursor' was behind G before: A, B, A, B

Letter #9 is our remainder: A, A, A, A

It's clearly going to need to开发者_JAVA技巧 loop until output string length matches input string length - it's all of this mess in the middle (Mostly the skips and loops) that I can't for the life of me figure out.

Any help or guidance is appreciated.


works perfectly with an unique range but will fail with something like ABCDEAFGHAI

$s = 'ABCDEFGHI';
$_len = strlen($s);
$out = '';
$c = 3;
echo '<pre>';
while ( $_len > 0 ) {
    echo strlen($s) ,  ' :: '.  $s . "\n";
    $term = $s[$c-1];
    list($a,$b) = explode($term, $s);
    $s = $b.$a;
    $x = strlen($s);
    if($x <= $c) {
        for($i=0; $i<($c-$x);$i++)
            $s .= $s;
    }

    $out .= $term;
    $_len--;
}

echo "\n\n\n" , $out;

output:

9 :: ABCDEFGHI
8 :: EFGHIABC
7 :: IABCEFG
6 :: EFGIAB
5 :: ABEFG
4 :: GABE
6 :: GABGAB
4 :: ABAB
4 :: AAAA

DHCIFEGBA

a hopefully better solution

function rearrangeString($string, $step = 4) {
    $output = '';
    $lenght = strlen($string);

    if($step >= $lenght) {
        return strrev($string);
    } elseif($step < 1) {
        return $string;
    } else {
        for($i=0; $i < $lenght; $i++) {
            $_tempLen = strlen($string);

            $output .= $string[$step-1];

            list($a,$b) = explode($string[$step-1], $string);

            $string = $b . $a;

            $_tempLen = strlen($string);
            if($step > $_tempLen) {
                $string = str_repeat($string, $step-$_tempLen+1);
            }
            unset($_tempLen, $a, $b);
        }

        return $output;
    }
}

$rearranged = rearrangeString('ABCDEFGHI');
var_dump($rearranged == 'DHCIFEGBA');

$rearranged = rearrangeString('ABCDEFGHI', 9);
var_dump($rearranged == 'IHGFEDCBA');

$rearranged = rearrangeString('ABCDEFGHI', 1);
var_dump($rearranged == 'ABCDEFGHI');

$rearranged = rearrangeString('ABCDEFGHI', 3);
var_dump($rearranged == 'CFIDHEBGA');

$rearranged = rearrangeString('ABCDEFGHI', 6);
var_dump($rearranged == 'FCAIBEHD');

$rearranged = rearrangeString('FARBE', 2);
var_dump($rearranged == 'ABFER');


Should work with any $s and $n

  <?php
    $s = "ABCDEFGHI";
    $n = 4;

    for ($i=0,$l=strlen($s) ; $l ; $l--)
    {
       $i = ($i+$n-1) % $l;
       echo $s[$i];
       $s = ($i ? substr($s, 0, $i) : '') . ($i < $l-1 ? substr($s, $i+1) : '');
    }
    echo "\n";
  ?>


I would try like this, though I haven't tested the code, yet:

$s = 'ABCDEFGHI';
$out = '';

While strlen($s) > 0 {
    $pos = 4 % strlen($s);
    $out += $s[$pos];
    if (strlen($s) > 3) $end = 3;
    else $end = strlen($s) - 1;
    $s = substr($s, 4, strlen($s)) + substr($s, 0, $end);
}

echo $out;
0

精彩评论

暂无评论...
验证码 换一张
取 消