/*
Name: 递增进位制和递减进位制数
Copyright: 始发于goal00001111的专栏;允许自由转载,但必须注明作者和出处
Author: goal00001111
Date: 18-11-08 16:03
Description: 序号转化为递增进位制和递减进位制数
字典全排列生成法,递增进位排列生成算法,递减进位排列生成算法和循环左移排列生成算法的映射生成函数。
有关算法的分析讨论详见拙作《有序全排列生成算法》:
http://blog.csdn.net/goal00001111/archive/ 2008/11/18 /3326619.aspx*/
#include<iostream>
#include <time.h>
using namespace std;
void ZhongJieShu_1(int zJ[], int a[], int len);//字典全排列生成算法
void ZhongJieShu_2(int zJ[], int a[], int len);//递增进位排列生成算法
void ZhongJieShu_3(int zJ[], int a[], int len);//递减进位排列生成算法
void ZhongJieShu_4(int zJ[], int a[], int len);//循环左移排列生成算法
void DiZeng(int dZ[], long long p[], int len, long long m);
void DiJian(int dZ[], int len, long long m);
void DiZYingShe(int yShe[], int dZJ[], int len);
void DiJYingShe(int yShe[], int dZ[], int len);
int main()
{
const int N = 9;
int diZ[N-1] = {0};
int diJ[N-1] = {0};
int yShe_1[N-1] = {0};
int yShe_2[N-1] = {0};
int yShe_3[N-1] = {0};
int yShe_4[N-1] = {0};
int a[N] = {8,3,9,6,4,7,5,2,1};
cout << "原序列 : ";
for (int i=0; i<N; i++)
cout << a[i] << ' ';
cout << endl;
cout << endl;
cout << "字典全排列生成算法之中介数 : ";
ZhongJieShu_1(yShe_1, a, N-1);
cout << endl;
cout << "递增进位排列生成算法之中介数 : ";
ZhongJieShu_2(yShe_2, a, N-1);
cout << endl;
cout << "递减进位排列生成算法之中介数 : ";
ZhongJieShu_3(yShe_3, a, N-1);
cout << endl;
cout << "循环左移排列生成算法之中介数 : ";
ZhongJieShu_4(yShe_4, a, N-1);
cout << endl;
long long p[N-1] = {1,2,6,24,120,720,5040,40320};
long long m = 100;
cout << "序号 : " << m << endl;
cout << endl;
cout << "递增序列 : ";
DiZeng(diZ, p, N-1, m);
cout << endl;
cout << "字典全排列生成算法之新映射 : ";
DiZYingShe(yShe_1, diZ, N);
cout << endl;
cout << "递增进位排列生成算法之新映射 : ";
DiZYingShe(yShe_2, diZ, N);
cout << endl;
cout << "递减序列 : ";
DiJian(diJ, N, m);
cout << endl;
cout << "递减进位排列生成算法之新映射 : ";
DiJYingShe(yShe_3, diJ, N);
cout << endl;
cout << "循环左移排列生成算法之新映射 : ";
DiJYingShe(yShe_4, diJ, N);
cout << endl;
system("pause");
return 0;
}
void DiJYingShe(int yShe[], int dZ[], int len)
{
int pos = len - 2;
int r = 0;
while (pos >= 0)
{
yShe[pos] += dZ[pos] + r;
if (yShe[pos] >= pos + 2)
{
yShe[pos] -= pos + 2;
r = 1;
}
else
r = 0;
pos--;
}
for (int i=0; i<len-1; i++)
cout << yShe[i] << ' ';
cout << endl;
}
void DiZYingShe(int yShe[], int dZ[], int len)
{
int pos = len - 2;
int r = 0;
while (pos >= 0)
{
yShe[pos] += dZ[pos] + r;
if (yShe[pos] >= len - pos)
{
yShe[pos] -= len - pos;
r = 1;
}
else
r = 0;
pos--;
}
for (int i=0; i<len-1; i++)
cout << yShe[i] << ' ';
cout << endl;
}
void DiJian(int dJ[], int len, long long m)
{
int pos = len;
while (m > 0)
{
dJ[pos-2] = m % pos;
m /= pos;
pos--;
}
for (int i=0; i<len-1; i++)
cout << dJ[i] << ' ';
cout << endl;
}
void DiZeng(int dZ[], long long p[], int len, long long m)
{
int pos = 0;
while (m > 0)
{
while (m < p[len-1-pos])
{
dZ[pos++] = 0;
}
if (m == p[len-1-pos])
{
dZ[pos++] = 1;
while (pos < len)
dZ[pos++] = 0;
break;
}
else
{
dZ[pos] = m / p[len-1-pos];
m %= p[len-1-pos];
pos++;
}
}
for (int i=0; i<len; i++)
cout << dZ[i] << ' ';
cout << endl;
}
void ZhongJieShu_1(int zJ[], int a[], int len)//字典全排列生成法
{
for (int i=0; i<len; i++)
{
for (int j=i+1; j<=len; j++)
{
if (a[i] > a[j])
zJ[i]++;
}
}
for (int i=0; i<len; i++)
cout << zJ[i] << ' ';
cout << endl;
}
void ZhongJieShu_2(int zJ[], int a[], int len)//递增进位排列生成算法
{
int pos, num = len+1;
while (num > 1)
{
for (pos=0; pos<=len; pos++)
{
if (a[pos] == num)
break;
}
int s = 0;
for (int j=pos+1; j<=len; j++)
{
if (a[pos] > a[j])
s++;
}
zJ[len+1-num] = s;
num--;
}
for (int i=0; i<len; i++)
cout << zJ[i] << ' ';
cout << endl;
}
void ZhongJieShu_3(int zJ[], int a[], int len)//递减进位排列生成算法
{
int pos, num = len+1;
while (num > 1)
{
for (pos=0; pos<=len; pos++)
{
if (a[pos] == num)
break;
}
int s = 0;
for (int j=pos+1; j<=len; j++)
{
if (a[pos] > a[j])
s++;
}
zJ[num-2] = s;
num--;
}
for (int i=0; i<len; i++)
cout << zJ[i] << ' ';
cout << endl;
}
void ZhongJieShu_4(int zJ[], int a[], int len)//循环左移排列生成算法
{
int pos;
for (pos=0; pos<=len; pos++)//寻找数字len+1
{
if (a[pos] == len+1)
break;
}
int s = 0;
for (int i=pos+1; i<=len; i++)
{
if (a[pos] > a[i])
s++;
}
zJ[len-1] = s; //设置最大的数字len+1的中介数
int num = len;//从第二大的数字开始循环左移排列
while (num > 1)
{
int s = 0;
while (pos >= 0 && a[pos] != num)//左移寻找num-1,并累计比num小的数字
{
if (num > a[pos])
s++;
pos--;
}
if (a[pos] != num)//若左侧没有找到num-1
{
pos = len;
while (a[pos] != num)//从右界开始左移寻找num-1,并累计比num小的数字
{
if (num > a[pos])
s++;
pos--;
}
}
zJ[num-2] = s;
num--;
}
for (int i=0; i<len; i++)
cout << zJ[i] << ' ';
cout << endl;
}