Нам предоставляется строка и перестановка строки.
Например, строка ввода sandeep
и перестановка psdenae
.
Найти позицию данной перестановки в отсортированном списке перестановок исходной строки.
Нам предоставляется строка и перестановка строки.
Например, строка ввода sandeep
и перестановка psdenae
.
Найти позицию данной перестановки в отсортированном списке перестановок исходной строки.
Общее число перестановок заданной строки длины n будет n! (если все символы различны), поэтому было бы невозможно изучить все комбинации.
Этот вопрос на самом деле похож на вопрос математики P и C
Найдите ранг слова "стек", если он упорядочен в порядке словаря.
Учитывая входную строку как NILSU Возьмите слово, которое мы должны найти в ранге. Возьмите, например, "SUNIL".
Теперь расположите букву "SUNIL" в алфавитном порядке.
Это будет. "I L N S U".
Теперь возьмите первую букву. Его "я". Теперь проверьте, есть ли буква "I" первая буква "SUNIL"? Нет. Количество слов, которые могут быть сформированы начиная с меня будет 4!, поэтому мы знаем, что будет 4! слова перед "SUNIL".
I = 4!= 24
Теперь перейдите к второй букве. Его "L" . Теперь проверьте еще раз, если это письмо, которое мы хотим на первом месте? Нет. Таким образом, количество слов может быть, начинающийся с "L" , будет 4!.
L = 4!= 24
Теперь перейдите к "N". Мы этого хотим? Нет. Запишите количество слов может быть сформировано начиная с "N", еще раз 4!
N = 4!= 24
Теперь перейдите к "S". Это то, чего мы хотим? Да. Теперь удалите письмо из алфавитно упорядоченное слово. Теперь это будет "I L N U"
Напишите S и снова проверьте слово в списке. Мы хотим СИ? Нет. Таким образом, число слов может быть сформировано начиная с SI будет 3!
[S]: I- > 3!= 6
Go для L. мы хотим SL? Нет. Так что это будет 3!.
[S]: L- > 3!= 6
Переходим на N., мы хотим SN? Нет.
[S]: N- > 3!= 6
Перейдите к SU. Мы этого хотим? Да. Вырежьте букву U из списка и то это будет "I L N". Теперь попробуй, я хочу, чтобы SUI? Нет. Так что число слов, которые начинаются с SUI, будет 2!
[SU]: I- > 2!= 2 Теперь иди за Л. Мы хотим "СУЛЬ". Нет, поэтому число слова, начинающиеся с SUL, будут равны 2!.
[SU]: L- > 2!= 2
Теперь иди за Н. Мы хотим СОЛНЦЕ? Да, теперь удалите это письмо. и это будет "I L". Мы хотим "SUNI"? Да. Удалите эту букву. Единственный буква слева - "L" .
Теперь иди для Л. Мы хотим СОЛНЦЕ? Да. SUNIL были первыми вариантами, поэтому у нас есть 1!. [SUN] [I] [L] = 1!= 1
Теперь добавьте все числа, которые мы получаем. Сумма будет.
24 + 24 + 24 + 6 + 6 + 6 + 2 + 2 + 1 = 95.
Таким образом, слово SUNIL будет на 95-й позиции, если мы посчитаем слова, которые могут быть созданы с использованием букв SUNIL, упорядоченных в порядке словаря.
Таким образом, благодаря этому методу вы могли бы легко решить эту проблему.
Создание @Algorithmist ответа и его комментарий к его ответу и использование принципа, обсуждаемого в этом сообщении, когда повторяются буквы, я сделал следующий алгоритм в JavaScript, который работает для всех буквенных слов даже с повторяющимися экземплярами букв.
function anagramPosition(string) {
var index = 1;
var remainingLetters = string.length - 1;
var frequencies = {};
var splitString = string.split("");
var sortedStringLetters = string.split("").sort();
sortedStringLetters.forEach(function(val, i) {
if (!frequencies[val]) {
frequencies[val] = 1;
} else {
frequencies[val]++;
}
})
function factorial(coefficient) {
var temp = coefficient;
var permutations = coefficient;
while (temp-- > 2) {
permutations *= temp;
}
return permutations;
}
function getSubPermutations(object, currentLetter) {
object[currentLetter]--;
var denominator = 1;
for (var key in object) {
var subPermutations = factorial(object[key]);
subPermutations !== 0 ? denominator *= subPermutations : null;
}
object[currentLetter]++;
return denominator;
}
var splitStringIndex = 0;
while (sortedStringLetters.length) {
for (var i = 0; i < sortedStringLetters.length; i++) {
if (sortedStringLetters[i] !== splitString[splitStringIndex]) {
if (sortedStringLetters[i] !== sortedStringLetters[i+1]) {
var permutations = factorial(remainingLetters);
index += permutations / getSubPermutations(frequencies, sortedStringLetters[i]);
} else {
continue;
}
} else {
splitStringIndex++;
frequencies[sortedStringLetters[i]]--;
sortedStringLetters.splice(i, 1);
remainingLetters--;
break;
}
}
}
return index;
}
anagramPosition("ARCTIC") // => 42
Я не комментировал код, но я попытался сделать имена переменных максимально возможными. Если вы запустите его через процесс отладчика, используя консоль инструментов разработчика, и запустите несколько console.logs, вы сможете увидеть, как он использует формулу в вышеописанном S.O. пост.
Я попытался реализовать это в js. Он работает для строки, у которой нет повторяющихся букв, но в противном случае я ошибаюсь. Вот мой код:
function x(str) {
var sOrdinata = str.split('').sort()
console.log('sOrdinata = '+ sOrdinata)
var str = str.split('')
console.log('str = '+str)
console.log('\n')
var pos = 1;
for(var j in str){
//console.log(j)
for(var i in sOrdinata){
if(sOrdinata[i]==str[j]){
console.log('found, position: '+ i)
sOrdinata.splice(i,1)
console.log('Nuovo sOrdinata = '+sOrdinata)
console.log('\n')
break;
}
else{
//calculate number of permutations
console.log('valore di j: '+j)
//console.log('lunghezza stringa da permutare: '+str.slice(~~j+1).length);
if(str.slice(j).length >1 ){sub = str.slice(~~j+1)}else {sub = str.slice(j)}
console.log('substring to be used for permutation: '+ sub)
prep = nrepC(sub.join(''))
console.log('prep = '+prep)
num = factorial(sub.length)
console.log('num = '+num)
den = denom(prep)
console.log('den = '+ den)
pos += num/den
console.log(num/den)
console.log('\n')
}
}
}
console.log(pos)
return pos
}
/* ------------ functions used by main --------------- */
function nrepC(str){
var obj={}
var repeats=[]
var res= [];
for(x = 0, length = str.length; x < length; x++) {
var l = str.charAt(x)
obj[l] = (isNaN(obj[l]) ? 1 : obj[l] + 1);
}
//console.log(obj)
for (var i in obj){
if(obj[i]>1) res.push(obj[i])
}
if(res.length==0){res.push(1); return res}
else return res
}
function num(vect){
var res = 1
}
function denom(vect){
var res = 1
for(var i in vect){
res*= factorial(vect[i])
}
return res
}
function factorial (n){
if (n==0 || n==1){
return 1;
}
return factorial(n-1)*n;
}
Мой подход к проблеме - это сортировка данной перестановки. Количество подстановок символов в строке даст нам положение pemutation в отсортированном списке перестановок.
Неэффективным решением было бы последовательно находить предыдущие перестановки до тех пор, пока вы не достигнете строки, которая больше не может быть переделана. Количество перестановок, необходимых для достижения этого состояния, - это позиция исходной строки.
Однако, если вы используете комбинаторика, вы можете быстрее достичь решения. Предыдущее решение будет выдавать очень медленный вывод, если длина строки превышает 12.