На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! правила раздела Алгоритмы
1. Помните, что название темы должно хоть как-то отражать ее содержимое (не создавайте темы с заголовком ПОМОГИТЕ, HELP и т.д.). Злоупотребление заглавными буквами в заголовках тем ЗАПРЕЩЕНО.
2. При создании темы постарайтесь, как можно более точно описать проблему, а не ограничиваться общими понятиями и определениями.
3. Приводимые фрагменты исходного кода старайтесь выделять тегами code.../code
4. Помните, чем подробнее Вы опишете свою проблему, тем быстрее получите вразумительный совет
5. Запрещено поднимать неактуальные темы (ПРИМЕР: запрещено отвечать на вопрос из серии "срочно надо", заданный в 2003 году)
6. И не забывайте о кнопочках TRANSLIT и РУССКАЯ КЛАВИАТУРА, если не можете писать в русской раскладке :)
Модераторы: Akina, shadeofgray
  
> ПерестаноBки
    есть строка из n букв, необязательно различных.
    например,
    abbccd
    из этой строки можно нагенерить различные перестановки. генерить надо в лексографическом порядке. как смасрячить взаимнооднозначное соответсвие между номером перестановки при генерации и самой перестановкой?
    выше написанная перестановка имеет номер 1, потом идет abbcdc под номером 2 и т.д.
    генерить не предлагать, так как иногда времени не хватит.
    зы
    благодарен заранее
    Сообщение отредактировано: experimenter -
      мужики, ну, давайте поднапряжемся и дадим мне ответ, а? плиз.
        Имхо это невозможно, без генерения... :'(
          Цитата vesper1, 10.06.03, 18:05:24
          Имхо это невозможно, без генерения... :'(

          ну, как так? я вот в книге одной читал и там как раз таки строилось такое соответсвие, только книгу эта сейчас для меня недоступна. :-/
            я решения проблемы не знаю....
            но мысли имеются:
            найти некоторые инвариант перестанвки, ну или параметр перестановки, зависящий от номера. например кол-во инверсий.  на его основании выполнить все инверсии и поиметь перестановку.


            кстати, почему не льзя заранее нагенерить, а потом по номеру из нагенеренного массива выдирать элемент. дешево и сердито:) (только места жрет)
              Ты знаешь я кажется полгода назад писал подробный ответ на это дело в этом разделе

              ответ сейчас не вспомню но можешь поискать
              если конечно я не путаю
                рассмотрим множество T(k) - произведение k множеств (с номерами от 1 до k), каждое из которых состоит из элементов от 0 до (k-i) (первое- 0,...,k-1, второе - 0,..,k-2, .., k-е - 0 )
                очевидно, что мощность такого T(k) - k!
                элемент, принадлежащий такому множеству представляется в виде (r1,  ...., rk)
                в итоге T(k) - что-то вроде системы счисления с переменным основанием, т.е. для каждого (r1,  ...., rk) можно вычислить его номер (вроде так - n=r1*(k)+r2*(k)+..rk) и наоборот
                пусть t1=(r1, .. , rk), t2=(R1, ... , Rk) -  наборы из T(k); t1 < t2, если до определённого i начала совпадают (r1=R1, .., r(i-1)=R(i-1)), а ri<Ri
                перебор... будем перебирать всё это счастье в "естественном" порядке: увеличивая ri на 1, если переполнение - увеличиваем r(i-1) на единицу и т.д..

                таким образом мы умеем для T(k) вычислять его мощность, вычислять номер элемента (от 1 до k!), по номеру - сам элемент, и делать перебор

                а теперь - гвоздь программы:
                пусть P(k) - множество всех перестановок чисел от 1 до k
                отождествим T(k) и P(k):
                P(k)->T(k): возьмём перестановку (r1, ..., rk) и сопоставим ей элемент (t1, ..., tk) так:
                для любого i от 1 до k найдем число значений, меньших ri среди r(i+1), r(i+2), ..., rk - это число возьмём за ti
                ( пример: (4,8,1,5,7,2,3,6) -> (3,6,0,2,3,0,0,0) )
                T(k)->P(k): меняя i от 1 до k, нужно просто помнить множество значений Si, которые ещё могут быть в перестановке на i-м месте
                ( пример: (3,6,0,2,3,0,0,0) -> (4,8,1,5,7,2,3,6) : S1=1:8; t1=3 => r1=4 (именно четвёрке в множестве S1 предшествует 3 числа); убираем 4 из S1: S2=1:3+5:8, t2=6 => r2=8 => S3=1:3+5+7+8 и т.д...)

                в итоге, чтобы перебрать все P(k), или по номеру получить перестановку, нужно сначала аналогичное действие сделать для T(k), а потом сопоставить по указанному выше правилу нужную перестановку

                удачи :D
                  спасибо! и хоть некоторые части тут сразу не совсем очевидны, тем не менее.
                  и потом, а как быть-то если элементы повторяются?
                  и потом... по сложности алгоритма, я имею в виду время, не тоже самое будет, как если бы мы просто перебирали эти шутовы перестановки?
                  Сообщение отредактировано: experimenter -
                    ух
                    если что-нибудь останется загадкой - обращайся: у меня по этому всему экзамен в четверг ::)

                    "а как быть-то если элементы повторяются?" - в смысле?
                      Цитата DEiL, 15.06.03, 13:07:56
                      ух
                      если что-нибудь останется загадкой - обращайся: у меня по этому всему экзамен в четверг ::)

                      "а как быть-то если элементы повторяются?" - в смысле?

                      насколько я понимаю, алгоритм работает для такого множества
                      (1,2,3,4) <- генерим все перестановки для этого мн-ва
                      а для такого работает?
                      (1,2,2,3) <- а для этого можем генерить?
                      Сообщение отредактировано: experimenter -
                        ой, я кажется понял, о чём ты :-)

                        ты о "abbccd"
                        ну так тут просто - отождестви каждую букву из искомой перестановки с числом каким-нибудь.. например с её позицией в строке.
                        и уже работай с набором чисел. они уже не будут повторяться
                        и когда у тебя будет получена перестановка, сделаешь обратное - цифру заменишь на букву
                        вроде бы так..
                          читай выше :-)
                            Цитата DEiL, 15.06.03, 13:11:46
                            ой, я кажется понял, о чём ты :-)

                            ты о "abbccd"
                            ну так тут просто - отождестви каждую букву из искомой перестановки с числом каким-нибудь.. например с её позицией в строке.
                            и уже работай с набором чисел. они уже не будут повторяться
                            и когда у тебя будет получена перестановка, сделаешь обратное - цифру заменишь на букву
                            вроде бы так..

                            а не получится, что у двух одинаковых перестановок будут разные представления?
                              хм... да, ты прав - подстава..
                              блин
                                все равно спасибо. 8D
                                  незачто :-)
                                  хоть кому-то пригодилось ЭТО ;D
                                    Вообще нормально бы в рекурсию уйти - мы такую задачу на уроках делали, рекурсия там будет, рекурсия. :-/
                                      Цитата Fieral, 19.06.03, 09:45:50
                                      Вообще нормально бы в рекурсию уйти - мы такую задачу на уроках делали, рекурсия там будет, рекурсия. :-/

                                      ну, понятно. по-моему задачи такого типа в легче всего рекурсией решать. по-крайней мере, я так всегда делаю. вопрос в другом - как организовать рекурсию. вот в чем вопрос!  ::)
                                        Я так понимаю, что до кода дело так и не дошло, тады вот: (хотел еще неделю назад публикануть, но посмотрел и понял как все запущено; однако может ктоньть разберется)
                                        ExpandedWrap disabled
                                          <br>char GenKey(  HWND  hwndDlg,<br>                   char lkey,//длинна перестановки<br>                   char * keymask,//какойто выходной буфер :)<br>                   char _sys_=0,//признак цикличного вызова<br>                   char * numkey=0,//перестановка на выходе цикличного вызова<br>                   char *start=0//номер перестановки цикличного вызова<br>                )<br> {<br>  static char i,k,mask[3],nu[MaxLenMath+1],nur[MaxLenMath+1],fa[MaxLenMath+1],f;<br><br>  if(!_sys_)SendDlgItemMessage(hwndDlg,IDC_EDIT31,WM_GETTEXT,<br>                               (WPARAM)(MaxLenMath+1),(LPARAM)nur);<br>  if(_sys_){strcpy(nur,start);nu[0]='1';nu[1]=0;add(start,nu);}<br><br>  for(i=0;i<lkey;i++){keymask[i]=0;}<br>  fak(fa,lkey);<br><br>  f=0;<br>  if(strlen(nur)>strlen(fa)+1){nur[strlen(fa)+1]=0;f=1;}<br>  while(sub(nur,fa)) f++;<br><br>  for(i=lkey;i>1;i--)<br>   {<br>    strcpy(nu,nur);<br>    while(sub(nu,fa));k=0;<br>    strcpy(nur,nu);<br>    fak(fa,i-1);<br>    while(sub(nu,fa)) k++;<br>    k=k+1+(lkey-i);<br>    while(keymask[k-1])k=keymask[k-1];<br>    keymask[k-1]=lkey-i+1;<br>    if(!_sys_){sprintf(mask,"\%d",k);<br>               SendDlgItemMessage(hwndDlg,IDC_EDIT1+lkey-i,WM_SETTEXT,0,<br>                                  (LPARAM)mask);<br>              } else numkey[lkey-i+1]=k;<br>   }<br>  k=lkey;<br>  while(keymask[k-1])k=keymask[k-1];<br>  if(!_sys_){sprintf(mask,"\%d",k);<br>             SendDlgItemMessage(hwndDlg,IDC_EDIT0+lkey,WM_SETTEXT,0,<br>                                (LPARAM)mask);<br>            } else numkey[lkey]=k;<br>  return f;<br> }<br><br>void ReGenKey(HWND  hwndDlg,char lkey,char * keymask)<br> {<br>  char i,k,p,mask[3],nu[MaxLenMath+1]="0",fa[MaxLenMath+1];<br><br>  for(i=0;i<lkey;i++){keymask[i]=0;}<br>  for(i=0;i<(lkey-1);i++)<br>   {<br>    SendDlgItemMessage(hwndDlg,IDC_EDIT1+i,WM_GETTEXT,(WPARAM)3,(LPARAM)mask);<br>    k=MyAtoi(mask);<br>    while(keymask[k-1])k=keymask[k-1];<br>    keymask[i]=k;<br>    sprintf(mask,"\%d",k);<br>    fak(fa,lkey-1-i);<br>    p=k-(i+1);<br>    while(p){add(nu,fa);p--;}<br>   }<br>  SendDlgItemMessage(hwndDlg,IDC_EDIT31,WM_SETTEXT,0,(LPARAM)nu);<br> }<br><br>void trstr(char*a)<br> {<br>  int i=0;<br>  while(a[i]=='0')i++;<br>  if(i)strcpy(a,a+i);<br> }<br><br>char sub(char * a,char * b)<br> {<br>  char reza[MaxLenMath+1];<br>  strcpy(reza,a);<br>  int la=strlen(a),lb=strlen(b),i,ii;<br>  for(i=lb;i>0;i--)<br>  {<br>   if(a[la-lb-1+i]>=b[i-1]) a[la-lb-1+i]=a[la-lb-1+i]-b[i-1]+'0';<br>    else{ii=i-1;<br>         while(a[la-lb-1+ii]=='0'&&(la-lb-1+ii)>=0) {a[la-lb-1+ii]='9';ii--;}<br>         if((la-lb-1+ii)<0){strcpy(a,reza);return 0;}<br>         a[la-lb-1+ii]--;<br>         a[la-lb-1+i]=a[la-lb-1+i]-b[i-1]+10+'0';<br>        }<br>  }<br>  trstr(a);<br>  return 1;<br> }<br><br>char add(char * a,char * b)<br> {<br>  int i=0,ii,la=strlen(a),lb=strlen(b);<br>  char reza[MaxLenMath+1];<br>  if(la!=MaxLenMath){for(i=0;i<MaxLenMath;i++)reza[i]='0';reza[MaxLenMath]=0;<br>                     strcpy(reza+MaxLenMath-la,a);<br>                     strcpy(a,reza);<br>                    }<br>  a[MaxLenMath]=0;la=MaxLenMath;<br>  for(i=lb;i>0;i--)<br>   {<br>    if(a[la-lb-1+i]+b[i-1]-'0'<='9') a[la-lb-1+i]=a[la-lb-1+i]+b[i-1]-'0';<br>     else {ii=i-1;<br>           while(a[la-lb-1+ii]=='9'&&(la-lb-1+ii)>=0){a[la-lb-1+ii]='0';ii--;}<br>           if((la-lb-1+ii)<0)return 0;<br>           a[la-lb-1+ii]++;<br>           a[la-lb-1+i]=a[la-lb-1+i]+b[i-1]-10-'0';<br>          }<br>   }<br>  trstr(a);<br>  return 1;<br> }<br><br>void fak(char* a,char f)<br> {<br>  char ff,aa[MaxLenMath+1];<br>  if(f<=1){a[1]=0;a[0]='1';return;}<br>  sprintf(a,"\%d",f);<br>  strcpy(aa,a);<br>  f--;<br>  while(f>1)<br>   {<br>    ff=f;<br>    while(ff>1){add(a,aa);ff--;}<br>    f--;<br>    strcpy(aa,a);<br>   }<br> }<br>
                                          ну, ты бы хоть примерный алгоритм сказал. :-/
                                            Цитата Experimenter, 21.06.03, 18:59:34
                                            ну, ты бы хоть примерный алгоритм сказал. :-/
                                            Дк.. этот код был написан четыре года назад и алгоритм, который я выдумывал сам, уже давно забыт :(
                                            Так что, Господа Программисты, никогда не ленитесь писать комментарии ;)
                                            Если есть желание, то могу выслать полный проект той прожки в которой использовался этот код, хотя кому-то я ее уже когда-то  высылал...
                                              эту задачу я решил, наконец-то. решил без генерения.
                                              идея такова. есть, например, перестановка aabc (самая первая).
                                              от нее надо добраться до caba. чтобы добраться, надо сначала пройти все перестановки
                                              a???, которых 3! = 6, потом
                                              b???, которых 3!/2! = 3, потом
                                              приходим к перестановке сaab. одну букву подобрали.
                                              таким же макаром движемся от перестановки aab до aba, суммируя перестановки на каждом шаге.
                                              алгоритм и программа рабочие. работает очень быстро.

                                              вот код на С++.
                                              ExpandedWrap disabled
                                                <br>#include <fstream><br>#include <iostream><br>#include <string><br>#include <algorithm><br>#include <iomanip><br><br>using namespace std;<br><br>// global variables<br>long double counter = 0;<br>bool fl      = false;<br>string StrToFind;<br>string StrDistinct;<br><br>// function defenitions<br>ostream & operator << (ofstream &str,string &s);<br>istream & operator >> (ifstream &str,string &s);<br><br>long double GivePermNum   (string a,string b);<br>long double GiveFactorial (string a);<br>long double Factorial     (long double n);<br>void              MakeDistinct(string &s); <br><br>int main();<br><br><br>int main()<br>{<br>string s;<br>long double  lC;<br>cout.setf(ios::right);<br><br>while(true)<br>{<br>cin>>StrToFind;<br>if((string)"#" == StrToFind) break;<br>else<br>{<br>      s = StrToFind;<br>      StrDistinct = StrToFind;<br>      sort(StrDistinct.begin(),StrDistinct.end());<br>      sort(s.begin(),s.end());<br>      MakeDistinct(StrDistinct);<br><br>      lC = GivePermNum(s,StrToFind);<br>      cout<<setw(10)<<(long int)(lC + 0.5)<<endl;<br>}<br><br>}<br><br>return 0;<br>}<br><br>long double GivePermNum(string a,string b)<br>{<br><br>if((size_t)1 == a.length()) return (long double )1;<br>if(a == b ) return (long double )1;<br><br>int i = 0,j = 0;<br>long double lCounter = 0;<br>string c;<br><br>while(StrDistinct[i] !=a[0]) i++;<br><br>while(StrDistinct[i] < b[0])<br>{<br>j = 0;<br>c = a;<br>while(c[j]!= StrDistinct[i]) j++;<br>c.erase(c.begin() + j);<br>lCounter += GiveFactorial(c);<br>i++;<br>}<br><br>bool fl = false;<br><br>i = 0;<br>while(a[i]!= b[0]) i++;<br>a.erase(a.begin() + i);<br>sort(a.begin(),a.end());<br><br>for(i = 0; i < a.length() && !fl; i++)<br>{<br>      if(a[i] == b[0]) fl = true;<br>}<br><br>if(!fl)<br>{<br>      i = 0;<br>      while(StrDistinct[i] !=b[0]) i++;<br>      StrDistinct.erase(StrDistinct.begin() + i);<br>}<br><br><br>return lCounter + GivePermNum(a,b.substr(1,b.length() -1));<br>}<br><br>long double GiveFactorial(string a)<br>{<br>int i = 0, iLen = a.length();<br>long double  lResult = Factorial(iLen);<br>long double  lRepeats;<br>char last;<br><br>      for(i = 0,lRepeats = 0,last = a[0]; i < iLen; i++)<br>      {<br>            if(last == a[i]) lRepeats++;<br>            else<br>            { <br>                  last = a[i];<br>                  lResult/=Factorial(lRepeats);<br>                  lRepeats = 1;<br>            }<br>      }<br>      <br>lResult/=Factorial(lRepeats);<br>return lResult;<br>}<br><br>long double Factorial(long double n)<br>{<br>      return (0 == n) ? (long double)1 : n*Factorial(n-1);<br>}<br><br>void MakeDistinct(string &s)<br>{<br>int i = 1;<br>      while(i < s.length())<br>      {<br>            if(s[i] == s[i-1])<br>                  s.erase(s.begin() + i);<br>            else i++;<br>      }<br>}<br><br>ostream & operator << (ofstream &str,string &s)<br>{<br>int i, iLen = s.length();<br>for(i = 0; i < iLen; str<<s[i++]);<br>return str;<br>}<br><br>istream & operator >> (ifstream &str,string &s)<br>{<br>char c; bool fl = true;<br>while(fl)<br>{<br>cin>>c;<br>if(c=='\n') fl = false;<br>else s+=c;<br>}<br><br>return str;<br>}<br>
                                              Сообщение отредактировано: experimenter -
                                                Цитата Experimenter, 07.07.03, 09:31:28
                                                эту задачу я решил, наконец-то. решил без генерения.
                                                идея такова. есть, например, перестановка aabc (самая первая).
                                                от нее надо добраться до caba. чтобы добраться, надо сначала пройти все перестановки
                                                a???, которых 3! = 6, потом
                                                b???, которых 3!/2! = 3, потом
                                                приходим к перестановке сaab. одну букву подобрали.
                                                таким же макаром движемся от перестановки aab до aba, суммируя перестановки на каждом шаге.
                                                алгоритм и программа рабочие. работает очень быстро.

                                                вот код на С++
                                                Ты совершил одну очень большую ошибку о которой я предупреждал ;) Кстати, код какой-то получился до боли знакомый 8D И советую всю математику перевести на работу со строчным представлением цифр, факториал: - вещь страшная :(
                                                  Цитата SVK, 07.07.03, 10:27:15

                                                  Ты совершил одну очень большую ошибку о которой я предупреждал ;) Кстати, код какой-то получился до боли знакомый 8D И советую всю математику перевести на работу со строчным представлением цифр, факториал: - вещь страшная :(

                                                  код писал сам. факториал - вещь нормальная. программу, которая подсчитывает перстановками, я написал, но, чтобы получить ответ от нее, тебе придется ждать до пенсии, в то время как выше написанной потребуется сотые доли секунды.
                                                  например, чтобы определить номер последней перестановки из 12 разных букв той проге придется проделать 12! = 479'001'600 итераций. чуешь? или еще нет?
                                                  так вот обычно проги работают терпимо при кол-ве операций около максимум 10 мил., а тут их почти 500, так что временной тест твоя идея никакой не проходит. :P
                                                  вообще программа написана как олимпиадная задача и оттестирована роботом вот здесь
                                                  http://acm.uva.es/board/index.php, так что все вопросы к нему, если тебе кажется что-то неправильно. и потом, как тебе что-то знакомо, если ты 4 года прогу не видел, алгоритм забыл, а тут тебе показывают прогу, да еще не твою, а ты говоришь, что-де она похожа на твою, 4х-годичной давности? только не говори, что ты имел ввиду, что она похожа на прогу, которую твой сосед написал или ты видел её в инете, ну, я думаю, ты понимаешь почему? ;D
                                                  зы
                                                  блин, я весь пост просмотрел и не нашел ни одного твоего предуприждения на счет какой-либо ошибки.  :P
                                                  Сообщение отредактировано: experimenter -
                                                    Цитата Experimenter, 07.07.03, 13:45:13
                                                    код писал сам.
                                                    Никаких притензий :)

                                                    Цитата Experimenter, 07.07.03, 13:45:13
                                                    факториал - вещь нормальная.
                                                    Я имел в виду, что при больших (даже не очень) перестановках, его значение вылезет за разрядную сетку long double.

                                                    Цитата Experimenter, 07.07.03, 13:45:13
                                                    программу, которая подсчитывает перстановками, я написал, но, чтобы получить ответ от нее, тебе придется ждать до пенсии, в то время как выше написанной потребуется сотые доли секунды.
                                                    Не совсем тебя понял, и вообще, пока ты его еще не забыл - освети подробно, но сжато и формулизировано принцип алгоритма, если не жалко. (Кстати, он обратим?)

                                                    Цитата Experimenter, 07.07.03, 13:45:13
                                                    вообще программа написана как олимпиадная задача и оттестирована роботом вот здесь http://acm.uva.es/board/index.php
                                                    Какая то 'размытая' ссылка, нельзяль по подробнее.

                                                    Цитата Experimenter, 07.07.03, 13:45:13
                                                    и потом, как тебе что-то знакомо, если ты 4 года прогу не видел, алгоритм забыл, а тут тебе показывают прогу, да еще не твою, а ты говоришь, что-де она похожа на твою, 4х-годичной давности?
                                                    У меня феноминальная память на 'лица' 8D Кстати я этого (она похожа на твою) не говорил ;)
                                                      вот ссылка. http://acm.uva.es/problemset/submit.php
                                                      номер задачи 153, а ID надо получить,т.е. зарегиться.
                                                      насчет алгоритма. я имел ввиду, что если делать, как я изначально предполагал, т.е. генерить все подряд в лексографическом порядке, пока не встретишь нужную, то это занимает очень много времени. а на счет обратимости я не знаю, скорее всего да, но это по-моему смысла не имеет.
                                                      вот код такой программы: считает все "на ура", но долго, правда надо, наверное, long int на long double заменить.

                                                      ExpandedWrap disabled
                                                        <br>#include <fstream><br>#include <iostream><br>#include <string><br>#include <algorithm><br>#include <iomanip><br><br>using namespace std;<br><br>// global variables<br>unsigned long  counter = 0;<br>bool fl             = false;<br>string StrToFind;<br><br>// function defenitions<br>ostream & operator << (ofstream &str,string &s);<br>istream & operator >> (ifstream &str,string &s);<br>void GivePermNum(string a,string b);<br>int main();<br><br><br>int main()<br>{<br>string s;<br><br>while(true)<br>{<br>cin>>StrToFind;<br>if((string)"#" == StrToFind) break;<br>else<br>{<br>      s = StrToFind;<br>      sort(s.begin(),s.end());<br><br>      fl = true;<br>      counter = 0;<br>      GivePermNum(s,(string)"");<br>      cout.setf(ios::right);<br>      cout<<setw(10)<<(counter + 1)<<endl;<br>}<br><br>}<br><br>return 0;<br>}<br><br>void GivePermNum(string a,string b)<br>{<br>char last = 0;<br>int  i        = 0;<br>string s;<br><br>      if(0 == a.length())      <br>      {<br>            if(StrToFind == b)<br>                  fl = false;<br>            else<br>                  counter++;<br><br>            return;<br>      }<br><br>      else<br>      {<br>            int iLen = a.length();<br>            for(i = 0; i < iLen && fl; i++)<br>            {<br>                  if (last != a[i])<br>                  {<br>                        last = a[i];<br>                        s       = a;<br>                        s.erase(s.begin() + i);<br>                        GivePermNum(s,b + last);<br>                  }<br><br>            }<br>      }<br>}<br><br>ostream & operator << (ofstream &str,string &s)<br>{<br>int i, iLen = s.length();<br>for(i = 0; i < iLen; str<<s[i++]);<br>return str;<br>}<br><br>istream & operator >> (ifstream &str,string &s)<br>{<br>char c; bool fl = true;<br>while(fl)<br>{<br>cin>>c;<br>if(c=='\n') fl = false;<br>else s+=c;<br>}<br><br>return str;<br>}<br><br>

                                                      зы
                                                      т.е. в итоге сопоставить взаимное соответсвие я не смог, но быстро подссчитать номер смог(в предыдущей проге, а не в той, которая в этом посте.)
                                                      Сообщение отредактировано: experimenter -
                                                        по просьбе трудящихся 8-) дублирую код из предыдущего сообщения..
                                                        ExpandedWrap disabled
                                                          #include <fstream>
                                                          #include <iostream>
                                                          #include <string>
                                                          #include <algorithm>
                                                          #include <iomanip>
                                                           
                                                          using namespace std;
                                                           
                                                          // global variables
                                                          unsigned long  counter = 0;
                                                          bool fl             = false;
                                                          string StrToFind;
                                                           
                                                          // function defenitions
                                                          ostream & operator << (ofstream &str,string &s);
                                                          istream & operator >> (ifstream &str,string &s);
                                                          void GivePermNum(string a,string b);
                                                          int main();
                                                           
                                                           
                                                          int main()
                                                          {
                                                          string s;
                                                           
                                                          while(true)
                                                          {
                                                          cin>>StrToFind;
                                                          if((string)"#" == StrToFind) break;
                                                          else
                                                          {
                                                                s = StrToFind;
                                                                sort(s.begin(),s.end());
                                                           
                                                                fl = true;
                                                                counter = 0;
                                                                GivePermNum(s,(string)"");
                                                                cout.setf(ios::right);
                                                                cout<<setw(10)<<(counter + 1)<<endl;
                                                          }
                                                           
                                                          }
                                                           
                                                          return 0;
                                                          }
                                                           
                                                          void GivePermNum(string a,string b)
                                                          {
                                                          char last = 0;
                                                          int  i        = 0;
                                                          string s;
                                                           
                                                                if(0 == a.length())
                                                                {
                                                                      if(StrToFind == b)
                                                                            fl = false;
                                                                      else
                                                                            counter++;
                                                           
                                                                      return;
                                                                }
                                                           
                                                                else
                                                                {
                                                                      int iLen = a.length();
                                                                      for(i = 0; i < iLen && fl; i++)
                                                                      {
                                                                            if (last != a[i])
                                                                            {
                                                                                  last = a[i];
                                                                                  s       = a;
                                                                                  s.erase(s.begin() + i);
                                                                                  GivePermNum(s,b + last);
                                                                            }
                                                           
                                                                      }
                                                                }
                                                          }
                                                           
                                                          ostream & operator << (ofstream &str,string &s)
                                                          {
                                                          int i, iLen = s.length();
                                                          for(i = 0; i < iLen; str<<s[i++]);
                                                          return str;
                                                          }
                                                           
                                                          istream & operator >> (ifstream &str,string &s)
                                                          {
                                                          char c; bool fl = true;
                                                          while(fl)
                                                          {
                                                          cin>>c;
                                                          if(c=='\n') fl = false;
                                                          else s+=c;
                                                          }
                                                           
                                                          return str;
                                                          }
                                                        из сообщения №22
                                                        ExpandedWrap disabled
                                                          #include <fstream>
                                                          #include <iostream>
                                                          #include <string>
                                                          #include <algorithm>
                                                          #include <iomanip>
                                                           
                                                          using namespace std;
                                                           
                                                          // global variables
                                                          long double counter = 0;
                                                          bool fl      = false;
                                                          string StrToFind;
                                                          string StrDistinct;
                                                           
                                                          // function defenitions
                                                          ostream & operator << (ofstream &str,string &s);
                                                          istream & operator >> (ifstream &str,string &s);
                                                           
                                                          long double GivePermNum   (string a,string b);
                                                          long double GiveFactorial (string a);
                                                          long double Factorial     (long double n);
                                                          void              MakeDistinct(string &s);
                                                           
                                                          int main();
                                                           
                                                           
                                                          int main()
                                                          {
                                                          string s;
                                                          long double  lC;
                                                          cout.setf(ios::right);
                                                           
                                                          while(true)
                                                          {
                                                          cin>>StrToFind;
                                                          if((string)"#" == StrToFind) break;
                                                          else
                                                          {
                                                                s = StrToFind;
                                                                StrDistinct = StrToFind;
                                                                sort(StrDistinct.begin(),StrDistinct.end());
                                                                sort(s.begin(),s.end());
                                                                MakeDistinct(StrDistinct);
                                                           
                                                                lC = GivePermNum(s,StrToFind);
                                                                cout<<setw(10)<<(long int)(lC + 0.5)<<endl;
                                                          }
                                                           
                                                          }
                                                           
                                                          return 0;
                                                          }
                                                           
                                                          long double GivePermNum(string a,string b)
                                                          {
                                                           
                                                          if((size_t)1 == a.length()) return (long double )1;
                                                          if(a == b ) return (long double )1;
                                                           
                                                          int i = 0,j = 0;
                                                          long double lCounter = 0;
                                                          string c;
                                                           
                                                          while(StrDistinct[i] !=a[0]) i++;
                                                           
                                                          while(StrDistinct[i] < b[0])
                                                          {
                                                          j = 0;
                                                          c = a;
                                                          while(c[j]!= StrDistinct[i]) j++;
                                                          c.erase(c.begin() + j);
                                                          lCounter += GiveFactorial(c);
                                                          i++;
                                                          }
                                                           
                                                          bool fl = false;
                                                           
                                                          i = 0;
                                                          while(a[i]!= b[0]) i++;
                                                          a.erase(a.begin() + i);
                                                          sort(a.begin(),a.end());
                                                           
                                                          for(i = 0; i < a.length() && !fl; i++)
                                                          {
                                                                if(a[i] == b[0]) fl = true;
                                                          }
                                                           
                                                          if(!fl)
                                                          {
                                                                i = 0;
                                                                while(StrDistinct[i] !=b[0]) i++;
                                                                StrDistinct.erase(StrDistinct.begin() + i);
                                                          }
                                                           
                                                           
                                                          return lCounter + GivePermNum(a,b.substr(1,b.length() -1));
                                                          }
                                                           
                                                          long double GiveFactorial(string a)
                                                          {
                                                          int i = 0, iLen = a.length();
                                                          long double  lResult = Factorial(iLen);
                                                          long double  lRepeats;
                                                          char last;
                                                           
                                                                for(i = 0,lRepeats = 0,last = a[0]; i < iLen; i++)
                                                                {
                                                                      if(last == a[i]) lRepeats++;
                                                                      else
                                                                      {
                                                                            last = a[i];
                                                                            lResult/=Factorial(lRepeats);
                                                                            lRepeats = 1;
                                                                      }
                                                                }
                                                           
                                                          lResult/=Factorial(lRepeats);
                                                          return lResult;
                                                          }
                                                           
                                                          long double Factorial(long double n)
                                                          {
                                                                return (0 == n) ? (long double)1 : n*Factorial(n-1);
                                                          }
                                                           
                                                          void MakeDistinct(string &s)
                                                          {
                                                          int i = 1;
                                                                while(i < s.length())
                                                                {
                                                                      if(s[i] == s[i-1])
                                                                            s.erase(s.begin() + i);
                                                                      else i++;
                                                                }
                                                          }
                                                           
                                                          ostream & operator << (ofstream &str,string &s)
                                                          {
                                                          int i, iLen = s.length();
                                                          for(i = 0; i < iLen; str<<s[i++]);
                                                          return str;
                                                          }
                                                           
                                                          istream & operator >> (ifstream &str,string &s)
                                                          {
                                                          char c; bool fl = true;
                                                          while(fl)
                                                          {
                                                          cin>>c;
                                                          if(c=='\n') fl = false;
                                                          else s+=c;
                                                          }
                                                           
                                                          return str;
                                                          }
                                                        Сообщение отредактировано: SVK -
                                                          Всем привет!
                                                          Ребят, может подскажете мне.... давненько я уже прог не писал, но тут понадобилось...
                                                          мне нужно написать на С++ в Билдере:
                                                          1) рекурентный способ вывода списка перестановок из n-элементов в лексикографическом порядке;
                                                          2) нерекурентный- вводим лексикографический номер, разряд перестановки и исходное множество, нам в ответ- перестановку;
                                                          3) нерекурентный- наоборот: вводим перестановку а машина нам даёт её лексикографический номер.

                                                          вот програмка котурую тут обсуждали...я не очень понял что она реализует. Её вроде можно использовать в одном пункте
                                                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                          0 пользователей:


                                                          Рейтинг@Mail.ru
                                                          [ Script execution time: 0.1398 ]   [ 15 queries used ]   [ Generated: 23.10.26, 09:50 GMT ]