замена букв в тексте (псевдокод) - PullRequest
0 голосов
/ 08 января 2012

Я делаю скрипт для создания имени пользователя. Это должно быть четыре буквы длиной; Традиционно мы использовали 3 буквы фамилии + 1 имени.
Если он уже использовался, мы вручную подумали об альтернативе.

Так что, если меня зовут Фред Флинстоунс, мы должны попробовать FLIF. Если это не работает; мы перебираем имя: FLIA, FLIB, FLIC ... FLIZ, FLAA, FLAB, FLAC, ... FLZZ, FAAA, FAAB, ...

Самый простой способ - перебрать последние буквы; затем сделайте еще один набор циклов по второй последней букве и выполните цикл по последним буквам; затем набор циклов по третьему последнему, второму последнему, последнему; и четвертый + третий + второй + последний. Это заставляет многое делать, когда циклы вложены друг в друга + нечитаемы для других людей + много печатать.
Я мог бы использовать счетчик на букву, но это также не кажется элегантным Я мог бы попробовать с одним счетчиком, а затем использовать mod 26, чтобы увидеть, сколько букв нужно заменить (но это кажется очень сложным).

Есть ли какие-нибудь элегантные / эффективные способы сделать это?


Бонусные баллы за первую попытку сохранить строку как можно более «логически правильной» (например, оставить последнюю букву F для Фреда или пропустить буквы FLIF; FLNF, FLSF, FLTF, ...).

1 Ответ

1 голос
/ 16 января 2012

Не уверен, что это именно то, что вы имеете в виду, но если вы структурируете свой username-скрипт следующим образом (я использовал PHP как язык), вы можете расширить его, добавив опции с более высокими коэффициентами размытости, сохраняя код читабельным:

echo findName('FLINTSTONE', 'FRED');

function findName($last, $first) {
    for ($fuzzFactor = 0; ; $fuzzFactor++) {
        $candidates = fuzzNames($last, $first, $fuzzFactor);

        if (empty($candidates)) {
            // exhausted
            return "sorry, I'm out of options!";
        }

        foreach ($candidates as $candidate) {
            if (isUnique($candidate)) {
                return $candidate;
            }
        }
    }
}

function fuzzNames($last, $first, $fuzzFactor) {
    switch ($fuzzFactor) {
        case 0:
            // no fuzz, return first choice
            return array(substr($last, 0, 3) . $first[0]);
        case 1:
            // replace the third letter of the last name
            // by the fourth/fifth/.../last letter (FLNF, FLTF, ... , FLEF)
            $candidates = array();
            for ($i = 3; $i < strlen($last); $i++) {
                $candidates[] = substr($last, 0, 2) . $last[$i] . $first[0];
            }
            return $candidates;
        case 2:
            // replace the second and third letter of the last name
            // by their follow-ups (FINF, FITF, ... , FNEF)
            $candidates = array();
            for ($i = 2; $i < strlen($last) - 1; $i++) {
                for ($j = $i + 1; $j < strlen($last); $j++) {
                    $candidates[] = $last[0] . $last[$i] . $last[$j] . $first[0];
                }
            }
            return $candidates;
        default:
            return array();
    }
}
...