求字典序的值和下一个排列

 

#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
//计算n的阶乘
int factorial(int n) {
    if(n==1)
        return 1;
    else if(n==0)
        return 0;
    else return n*factorial(n-1);
}

//求字典序的值
int dicOrder(int * nums,int len) {
    int sum=0;//总和
    int count;//比a[i]小,且没有在i前面出现过的值的个数;
    for (int i = 0; i < len; i++) {//从第一位数开始
        count = nums[i]-1;//记录比a[i]小的数的个数,
        for (int j = 1; j < nums[i]; j++) {//从1开始到小于这个数为止,
            for (int k = 0; k < i; k++) {
                if (j == nums[k])//排除那些在前面已经出现过了的值
                    count--;
            }
        }
        sum += count * factorial(len - i - 1);
    }
    return sum;
}
//求下一个排列;
void nextPermutation(int * nums,int len) {
    int max = len-1;
    int i,temp,j=max;
    for(; j>=1; j--) {
        if(nums[j]>nums[j-1]) { //从后往前,遇到第一个递增数
            i = j-1;//找到替换点
            for(int k = max; k>i; k--) {
                if(nums[k]>nums[i]) { //找到大于替换点的数,交换
                    temp = nums[k];
                    nums[k]=nums[i];
                    nums[i]=temp;
                    break;//结束
                }
            }
            for(int m = j, n = max; m<n; m++,n--) { //将替换点后的数字排序
                temp=nums[m];
                nums[m]=nums[n];
                nums[n]=temp;
            }    
            return ;
        }
    }
    if(j==0) { //若没有找到,则换成最小的数,也就是从小到大排序,
        for(int i = 0,j=max; i<j; i++,j--) {
            temp = nums[j];
            nums[j]=nums[i];
            nums[i]=temp;
        }
    }
}

int main() {
//创建文件
    ofstream createFile("input.txt");//在当前C++文件的目录下创建
    createFile << "8" << endl;
    createFile << "26458173" << endl;
    createFile.close();

    ifstream ReadFile("input.txt");
    ofstream WriteFile("output.txt");
//读取文件
    char c;
    ReadFile.get(c);//获取文件的第一行的字符,赋值给c
    int len = (int)c - 48;//并转化为int类型
    char line;
    ReadFile.get(line);//再获取第2行的字符串
    char *chara = new char[len];
    for (int i = 0; i < len; i++) {
        ReadFile.get(chara[i]);//先获取其中的每个字符
    }
    int * nums = new int[len];
    for (int i = 0; i < len; i++)
        nums[i]=(int)chara[i]-48;//转为数字

    WriteFile<<dicOrder(nums,len)<<endl;
    nextPermutation(nums,len);
    for(int i = 0; i <len; i++) {
        WriteFile<<nums[i];//把下一个排列输出到文件
    }
    ReadFile.close();//关闭输入流
    WriteFile.close();//关闭输出流
    system("pause");
    return 0;
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值