Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [C++]Перестановки в антилексикографическом порядке


Автор: Vampire551 21.5.2008, 15:01
Допишите пожалуйста прогу так чтобы она отбирала "хорошие" перестановки и записывала их в массив. "Хорошие" перестановки - это если перестановку разбить на 2 части то сумма цифр в левой части должна быть равна или примерно равна сумме цифр в правой части. Например: ряд (1 2 3 4), "хорошие" перестановки - (1 4 2 3),(1 4 3 2),(2 3 1 4), (3 2 1 4), (2 3 4 1), (4 1 3 2 ), (4 1 2 3). Заранее благодарен. smile 
Код

#include <stdio.h>
#include <conio.h>
#include<iostream.h>

#define N 4

void swap(int *a, int *b)
{
  int t;
  t=*a;
  *a=*b;
  *b=t;
}

void reverse(int * P,int m)
{
  int i=0, j=m;
  while(i<j)
 {
   swap(&P[i], &P[j]);
   i++;
   j--;
 }
}

void antilex(int * P,int m)
{
  int i;
  if(m==0)
 {
  for(i=0; i<N; i++)
  printf("%d ",P[i]);
  printf("\n");
 }
else
{
  for(i=0; i<=m; i++)
 {
   antilex(P,m-1);
   if(i<m)
  {
    swap(&P[i], &P[m]);
    reverse(P,m-1);
  }
 }
}
}

void main()
{
 clrscr();
 int i;
 int P[N];
 for(i=0; i<N; i++)
 P[i] = i+1;
 antilex(P,N-1);
 getch();
}

M
Rodman
Модератор: Название темы должно содержать язык написания!

Автор: Rififi 21.5.2008, 15:51
Цитата(Vampire551 @  21.5.2008,  15:01 Найти цитируемый пост)
сумма цифр в левой части должна быть равна или примерно равна сумме цифр в правой части

и насколько "примерно"?

Автор: Vampire551 21.5.2008, 16:02
Если сможете сделайте пожалуйста только с равно. Про "примерно" надо уточнить у препода, там вроде еще какое то условие есть. Заранее спасибо. smile 

Автор: Rififi 21.5.2008, 16:28
Компилировать компилятором, который знаком со стандартной библиотекой шаблоновне по наслышке (Visual C++ 6.0 и выше, Borland C++ Builder, ...)

Код
#include <iostream>
#include <iterator>
#include <algorithm>
#include <numeric>
#include <vector>
#include <stdexcept>

template <typename T, const size_t N>
static void show_permutes(const T (&arr_p)[N])
{
    // число элементов должно быть чётным
    if (N & 1)
        throw std::runtime_error("Нечётное количество элементов в массиве");

    // делаем копию массива
    T arr[N];
    std::copy(arr_p, arr_p+N, arr);

    // Индекс "половинного элемента"
    const size_t half = N / 2;
    
    // Итератор для вывода на консоль
    std::ostream_iterator<T> output(std::cout, " ");
    
    // Ищем среди всех возможных перестановок...
    while(std::next_permutation(arr, arr+N))
    {
        // ... только те, у которых равны суммы левой и правой половинок
        if (std::accumulate(arr, arr+half, T()) == std::accumulate(arr+half, arr+N, T()))
        {
            // И выводим их на консоль
            std::copy(arr, arr+N, output);
            std::cout << std::endl;
        }
    }
}

int main()
{
    int arr[] = {1,2,3,4};
    show_permutes(arr);
    return (0);
}


Результат:
Код
1 4 2 3
1 4 3 2
2 3 1 4
2 3 4 1
3 2 1 4
3 2 4 1
4 1 2 3
4 1 3 2

Автор: Vampire551 21.5.2008, 17:14
Спасибо большое за программу. Но мне нужно было доделать мою прогу (просто нужен именно тот алгоритм, перестановки в антилексикографическом порядке).  smile  Помогите пожалуйста. Заранее благодарен. 

Автор: t_gran 22.5.2008, 06:30
Цитата

Но мне нужно было доделать мою прогу

Доделать, так доделать. smile А самому?
Код

#include <stdio.h>    

#define N 4    
//-----------------------------------------------//
void swap (int *a, int *b)    
{    
   int t;
   t= *a;
   *a= *b;
   *b= t;
}    
//-----------------------------------------------//
void reverse (int *P, int m)
{    
   int i= 0, j= m;
   while (i < j)
   {
      swap (&P[i], &P[j]);
      i++;
      j--;
   }
}    
//-----------------------------------------------//
void antilex (int *P, int m)    
{    
   int i;    
   if (m == 0)
   {
      int sumL= 0, sumR= 0;
      for (i= 0; i < N / 2; i++)
         sumL+= P[i];
      for (; i < N; i++)
         sumR+= P[i];
      if (sumL == sumR)
      {
         for (i= 0; i < N; i++)
            printf ("%d ", P[i]);
         printf("\n");
      }
   }
   else
   {
      for (i= 0; i <= m; i++)
      {
         antilex (P, m - 1);
         if (i < m)
         {
            swap (&P[i], &P[m]);
            reverse (P, m - 1);
         }
      }
   } // else if (m == 0)
}
//-----------------------------------------------//
int main()    
{    
   int i;
   int P[N];
   for (i= 0; i < N; i++)
      P[i]= i + 1;
   antilex (P, N - 1);
   return 0;
}


Автор: Vampire551 22.5.2008, 11:36
Спасибо огромное за программу. smile  smile 

Автор: t_gran 23.5.2008, 03:03
Vampire551, тогда помечай тему как закрытую.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)