Member 13554561 Ответов: 2

Вопрос о перестановке с использованием рекурсии


ожидаемый результат: "abc" --> abc,acb,bca,bac,cab,cba
пример вывода: при передаче строки s="abc" я получаю: cc ccc ccc


код (багги) таков::

#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>


string subS(string fullS, int s,int len);
string permut(string s ,int n);
void swap(string s,int a,int b);

int main (int argc, string argv[])
{

    if (argc!=2)
    printf("usage: ./permutation 5");

    int n = strlen(argv[1]);
    permut(argv[1],n);

    // print permutations of string s , of length n


}
  string subS(string fullS, int s,int len)

   {
      string sub = fullS;

       for(int j=0;j<len;j++)
       {
           sub[j]=fullS[s];
           s=s+1;
       }
        sub[len]='\0';
       return sub;
   }


    string permut(string s ,int n)
    {
        if (s!=NULL)
        {


            if(n==1)
                return s;
            else
            {
                string dummy_s=s;// dummy variable so as not to pass the string
                

                string sub=subS(dummy_s,1,n-1);// get the substring of s starting at s[1] and of length n-1
                
                string smaller=permut(sub,n-1);// permute the substring
                
                string final = strncat(smaller,s,1); // append the first letter of s to the permuted string.will be using it to print the permutations of
                 
                

//generating the permutations by taking s[0] and appending it to "smaller".This is done using a string "final" and swapping s[0] with its left neigbour and printing the each of these strings 
                for (int i=n-1;i>0;i--)
                {
                    printf("%s\n",final);
                    swap(final,i,i-1);
                }
                
            }
        }
        return s;

    }

    void swap(string s,int a,int b)
    {
        if (a<=b)
            return;
        else
        {
            char c= s[a];
            s[a]=s[b];
            s[b]=c;

        }
    }


Что я уже пробовал:

я попытался представить логику моего кода через комментарии.Не уверен, что я должен добавить здесь.


Richard MacCutchan

В чем же вопрос?

Member 13554561

когда я запускаю этот код через отладчик, я вижу, что как только я прохожу dummy_s переменной в перестое() функцию, чтобы сабы() функция(для получения подстроки S-и тот, кто будет переставляться), строку s сам получает изменен, что сабы() возвращает. Почему? весь смысл отправки dummy_s вместо s состоял в том, чтобы оставить s неизменным.

Member 13554561

Кроме того, есть ли способ получить перестановки строк с помощью функции permut (), которая возвращает строку-как я пытаюсь здесь вместо функции void permut () - что является обычным способом реализации такого кода? Спасибо

Richard MacCutchan

Да, просто добавьте правильный оператор return, который возвращает нужный вам элемент.

Richard MacCutchan

Я не уверен, что происходит, но вы не должны использовать strncat со строкой std::.

Member 13554561

Я новичок. не уверен, что означает std::string.Кроме того, почему бы не использовать strncat?

Richard MacCutchan

Если вы не знаете, что означает любой из этих способов, то неудивительно, что ваш код не работает. Я предлагаю вам зайти на сайт MSDN и прочитать документацию по обоим пунктам.

Member 13554561

:-)

2 Ответов

Рейтинг:
20

CPallini

Мне кажется, вы слишком усложняете код.

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


Рейтинг:
1

Patrice T

Насколько я понимаю, ваш код совершенно неверен.
Прежде всего вам нужно изучить алгоритм, пока вы его не поймете.
Возьмите лист бумаги и потренируйтесь, думайте, что ваш единственный инструмент для получения всех перестановок-это функция подкачки, думайте механически. Совет: практикуйтесь по крайней мере с 4 буквами, чтобы выявить повторяющиеся паттерны.
Рекурсивные перестановки - форум C++ [^]

Это может помочь освоить один или несколько методов анализа, У. Е. сверху вниз Djikstra способ это хорошее начало.
https://en.wikipedia.org/wiki/Top-down_and_bottom-up_design[^]
https://en.wikipedia.org/wiki/Structured_programming[^]
https://en.wikipedia.org/wiki/Edsger_W._Dijkstra[^]
https://www.cs.utexas.edu/users/EWD/ewd03xx/EWD316.PDF[^]