Вчера я провел весь день, пытаясь решить проблему, которая требует, чтобы я получил k-ю перестановку или отменил перестановку.
Я обнаружил, что лучшим способом были факторные цифры, после нескольких часов поиска в Google и чтения десятков PDF-файлов \ powerpoints мне наконец-то удалось заставить его работать идеально как карандашом, бумагой, так и кодом.
Проблема теперь в том, что есть повторяющиеся предметы.
Я попробовал все, но не смог заставить вещь работать так, как она должна работать. Факторика всегда генерирует гораздо больший ранг для перестановки, не может просто позволить ей «распознавать» только неповторяющиеся перестановки.
Кто-нибудь знает способ использования акторадической системы, чтобы отменить перестановку с повторяющимися предметами? (например: abaac)?
Если кто-нибудь знает, пожалуйста, я хотел бы небольшой пример и интуитивное объяснение, которое наверняка принесет пользу многим другим в будущем.
Большое спасибо:)
PS: Вот мой попытанный код на C ++, который я написал для себя. Я знаю, что он вообще не оптимизирован, а просто чтобы показать вам, что я получил до сих пор:
Этот код будет работать правильно, если нет повторяющихся элементов, но он будет неправильным для повторяющихся элементов (next_permutation, конечно, не может использоваться, когда говорят, что я хочу 1 миллиардную перестановку).
#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
using namespace std;
int f(int n) {
if(n<2) return 1;
return n*f(n-1);
}
int pos(string& s,char& c) {
for(int i=0;i<s.size();++i) {
if(s[i]==c) return i;
}
return -1;
}
int main() {
const char* perm = "bedac";
string original=perm;
sort(original.begin(),original.end());
string s=original;
string t=perm;
int res=0;
for(;s!=t && next_permutation(s.begin(),s.end());++res);
cout<<"real:"<<res<<endl;
s=original;
string n;
while(!s.empty()) {
int p=pos(s,t[0]);
n+=p;
t.erase(0,1);
s.erase(p,1);
}
for(res=0;!n.empty();(res+=n[0]*f(n.size()-1)),n.erase(0,1));
cout<<"factoradix:"<<res<<endl;
return 0;
}