Переставить строку с анаграммой строки - получить новую должность, старые значения позиции


Я пишу функцию, чтобы захватить с собой пару анаграммы (слова или фразы пишется с той же буквы) и определить, как вы могли бы переместить письма, чтобы изменить одно в другое.

Например: поклонник -> женился

Результаты будут что-то вроде этого:

[[0, 1], [1, 6], [2, 0], [3, 4], [4, 2], [5, 5], [6, 3]]

Персонаж в 0 (а) место переходит на 1 символ в позиции 1 (Д) переходит на 6 и т. д. Я уже успешно решил эту, но, возможно, есть лучший способ!

Языка (обязательно!) это JavaScript. Вот моя текущая, рабочая функция:

function _get_new_positions(source, target) {
    // convert both strings to arrays - uppercase so we can find the destination
    // spot without worrying about cases
    source = source.toUpperCase().split('');
    target = target.toUpperCase().split('');

    var transform = [];
    var repeated = [];
    var found = 0;

    for(var i=0; i<source.length; i++) {
        // keep track of how many times we've found and 'moved' this letter
        repeated[source[i]] = repeated[source[i]] ? repeated[source[i]] + 1 : 1;
        found = 0;
        want  = repeated[source[i]];
        for(var j=0; j<target.length; j++) {
            if( target[j] == source[i] ) {
                found++;
                console.log('found is ' + found);
                if( found == want ) {
                    transform.push([i,j]);
                    break;
                }
            }
        }
    }
    return transform;
}

Спасибо за Ваш вклад.



1299
1
задан 10 июля 2011 в 03:07 Источник Поделиться
Комментарии
2 ответа

Можно упростить логику по настройке каждого персонажа вы найдете в целевое значение null. Я также хотел бы использовать цикл "while", как показано ниже.

function _get_new_positions(source, target) {
var transform = [], i, j, found, want;
// convert both strings to arrays - uppercase so we can find the destination without worrying about cases
source = source.toUpperCase().split('');
target = target.toUpperCase().split('');
for(i=0; i<source.length; i++) {
j = 0;
found = false;
want = source[i];
while((j < target.length) && !(found = (target[j] == want))){j++}
if (! found) {
console.log("Cannot find character: " + want + " at [i]: " + i);
} else {
console.log("Found character: " + want + " at [i,j]: " + i + j);
target[j] = ''; //blank out the character for future searches
transform.push([i,j])
}
}
return transform;
}

2
ответ дан 11 июля 2011 в 08:07 Источник Поделиться

Его можно упростить, не преобразовывать в массив с помощью шара, также используя замену выполнить вторую петлю и стереть найденные совпадения. Кроме того, возвращаемое значение может быть уменьшено в массив Ints, так как индекс массива отслеживает положение в источник.

function _get_new_position (source, target){
source = source.toUpperCase()
target = target.toUpperCase();

var result = []
, l = target.length;

while(l--){ // Starting from the end, swaps doubled letters index
target = target.replace( source.charAt(l) //
, function (char, index){ // charAt, index
result.unshift(index); // Add the found offset inverted
return ' '; // Suppress the char in source
});
}
return result;
}

1
ответ дан 28 августа 2011 в 04:08 Источник Поделиться