输入N个数,输出所有可能的排列组合(6+个小时啊,耶稣~)

输入N个数,输出所有可能的排列组合

一行代码一行泪。。。手都被发热的笔记本烤的不舒服了。。。。6个多小时过去鸟。。。终于粗来鸟。。。。

昨天同学问到一个排列组合的问题,本身不会很难,原题是固定输入4个数字,例如1 2 3 4,输出所有可能的排列组合

暴力的话应该不难的。代码+debug,半个小时。

如果是输入N个数字呢?

先说简单的暴力方法,如果输入4个数字,输出所有的排列组合

代码比较短,也比较简单,没有很刻意的去把代码的风格写的好一点,所以数字常量什么的表介意。。。。

/**********************************************************************
code writer : EOF
code date :2014.06.11
e-mail : [email protected]
code purpose:
        just for fun...
************************************************************************/
#include <stdio.h>

void fun(void);

int main()
{
        fun();

        return 0;
}

void fun(void)
{
        int array[4];
        int buffer[4];

        int temp = 0;

        int circle_1 = 0;
        int circle_2 = 0;
        int circle_3 = 0;
        int circle_4 = 0;

        printf("Hey,guys! Please input four numbers\n");

        //Input four number .
        for(temp = 0;temp < 4;temp++)
        {
                while(!scanf("%d",&array[temp]))

        for(temp = 0;temp < 4;temp++)
        {
                while(!scanf("%d",&array[temp]))
                {
                        while(getchar() != '\n')
                        {
                        }
                        printf("Input again and make sure the input data is right.\n");
                }
        }

        for(circle_1 = 0;circle_1 < 4;circle_1++)
        {
                buffer[0] = array[circle_1];

                for(circle_2 = 0;circle_2 < 4;circle_2++)
                {
                        if(array[circle_2] != array[circle_1])
                        {

                                buffer[1] = array[circle_2];

                                for(circle_3 = 0;circle_3 < 4;circle_3++)
                                {
                                        if(array[circle_3] != array[circle_2] && array[circle_3] != array[circle_1])
                                        {

                                                buffer[2] = array[circle_3];

                                                for(circle_4 = 0;circle_4 < 4;circle_4++)
                                                {
                                                        if(array[circle_4] != array[circle_3] &&
                                                           array[circle_4] != array[circle_2] &&
                                                           array[circle_4] != array[circle_1])
                                                        {
                                                                buffer[3] = array[circle_4];

                                                                for(temp = 0;temp < 4;temp++)
                                                                {
                                                                        printf("%d ",buffer[temp]);
                                                                }
                                                                printf("\n");
                                                        }
                                                }
                                        }
                                }
                        }
                }
        }
}

可以看出这里嵌套的for循环层数是取决于等待排列的数据的个数的,开销相当的大。

如果输入N个数字,输出所有的排列组合,这种方法是不可行的。

测试结果:

[email protected]:~/Desktop$ ./a.out

Hey,guys! Please input four numbers

1 2 3 4

1 2 3 4

1 2 4 3

1 3 2 4

1 3 4 2

1 4 2 3

1 4 3 2

2 1 3 4

2 1 4 3

2 3 1 4

2 3 4 1

2 4 1 3

2 4 3 1

3 1 2 4

3 1 4 2

3 2 1 4

3 2 4 1

3 4 1 2

3 4 2 1

4 1 2 3

4 1 3 2

4 2 1 3

4 2 3 1

4 3 1 2

4 3 2 1

利用递归。。。。做出n的版本。

/****************************************************************
code writer : EOF
code date : 2014.06.12
e-mail:[email protected]
code purpose:
	It's a hard time to finished this program but everthing is
Ok...It was here.
	Just change the macro ARRAYSIZE into the number of input
variable.This program would process it and print out all combination
of your input.

****************************************************************/
#include <stdio.h>

#define ARRAYSIZE 3
#define USED   1
#define UNUSED 0

struct location
{
	/*
	* There is a trick that we put the array into a structure.
	* What's happend? Why do we have to do this?
	* If you can't answer that questions, you may program without this trick and
	* you will thank god "It helps me a lot..."
	*/
	int state[ARRAYSIZE];

	/*
	* We could pass this object as individual unit.
	* You need not to warry about problem make you sad when you are using pointer.
	* It would gone like a normal type variable. All in all, It's a very useful trick.
	*/
};

int buffer[ARRAYSIZE];//Deliberately,I used global varibles.This "buffer" array would be used as a buffer for printing out
int array[ARRAYSIZE];//Deliberately,I used global varibles. This "array" array would be used as a buffer for original inputed date

int  check(int depth,struct location current_state);//Prototype for function check
void fun(void);//Aha ...just like a puppet...

int main()
{
	fun();

	return 0;
}

void fun(void)
{
	int temp = 0;

	struct location initial_state;//structure for memory initial location state

	//input original data
	for(temp = 0;temp < ARRAYSIZE;temp++)
	{
		while(!scanf("%d",&array[temp])) // error check...I like it...useful and safe.
		{
			while(getchar() != '\n')
			{
			}
			printf("Input error\nPlease input agina!");
		}
	}

	//initialization
	for(temp = 0;temp < ARRAYSIZE;temp++)
	{
		buffer[temp] = 0;
		initial_state.state[temp] = UNUSED;
	}

	printf("\n\n");

	//Game start!
	check(ARRAYSIZE-1,initial_state);
}

int  check(int depth,struct location current_state)
{
/*
local varible description:

	depth: It is used for current depth of recursion.
	current_state: It is used for which location have alread been used.

If we have eight inputed variables.

---> depth decrese in this direction

location one   1 0 0 0 0 0 0 0
     ...
location four  0 0 0 1 0 0 0 0
location five  0 0 0 0 1 0 0 0
     ...
location eight 0 0 0 0 0 0 0 1

It would print out follow this location, if the current_state structure is like that.

*/
	int temp = 0;
	int foo  = 0;
	int last_location = -1;//used for saving the location which this data putted into

	if(depth > 0)
	{
		for(foo = 0;foo < ARRAYSIZE ;foo++)//try to use different possible location.
		{
			for(temp = 0;temp < ARRAYSIZE ;temp++)//find a location for current data.
			{
				if(temp <= last_location)
				{
					continue;//jump over the location where the data have been putted.
				}

				if(current_state.state[temp] == UNUSED)//If this location is empty, we could use it for current data.
				{
					current_state.state[temp] = USED;//Don't forget to change current state into "USED".
					last_location = temp;//save current location into last_location
					buffer[ARRAYSIZE-(depth+1)] = array[temp];//It's time to put the data input buffer
					check(depth-1,current_state);
					current_state.state[last_location] = UNUSED;//clear used location and prepare for depth recursion.
					break;//We have found a empty location for current data so break out.
				}
			}

		}
	}
	else if(depth == 0)//If we touch the deepest floor, it's time to print out all data in buffer.
	{
		for(temp = 0;temp < ARRAYSIZE ;temp++)//check which location was left for the last one data.
		{

			if(current_state.state[temp] == UNUSED)
			{
				current_state.state[temp] = USED;
				last_location = temp;
				buffer[ARRAYSIZE-(depth+1)] = array[temp];
				break;
			}
		}

		for(temp = 0;temp < ARRAYSIZE;temp++)//Needless to describle what's happend in this loop....haha...
		{
			printf("%d ",buffer[temp]);
		}
		printf("\n");
	}
}

[email protected]:~/Desktop$ ./a.out

1 2 3

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

check(depth-1,current_state);的位置非常关键,而且这里把数组放进结构体是故意的,利用结构体可以直接赋值的性质,并且规避掉数组传参实质是传指针的性质,防止递归层数据之间相互影响。

其实这种排列组合只要稍加限制,可以和八皇后问题联系起来

输入N个数,输出所有可能的排列组合(6+个小时啊,耶稣~),布布扣,bubuko.com

时间: 2024-10-20 05:59:06

输入N个数,输出所有可能的排列组合(6+个小时啊,耶稣~)的相关文章

输入5个数用冒泡排序进行从小到大排列

package liu0913; import java.util.Scanner; public class Maopao { public static void main(String[] args) { Scanner sc=new Scanner(System.in); System.out.println("请输入第一个数"); int a=sc.nextInt(); System.out.println("请输入第二个数"); int b=sc.nex

c语言之输入3个数输出最大值

#include <stdio.h> int main() { // 输入abc输出最大值 int a; int b; int c; int max; scanf("%d %d %d", &a, &b, &c); // 输入请空格隔开最后回车 /* if (a > b) { max = a; } else { max = b; } */ max = a; if (b > max) { max = b; } if (c > max)

小弟新手怎样实现输入6个数输出最小数啊!!!!

9p4k0b恐咀冶惹谫馁<http://weibo.com/p/230927983161835786084352?fZ8e_20180414> l179pj召畔角男狙依<http://weibo.com/KAUFRlWp/230927983074420950044672> 25vf39懦凹掳郝茄凹<http://weibo.com/p/230927983014085220110336?1y2Z_20180414> pp3jm6竿布瓶窒睬沸<http://weibo

输入10个数,找出其中绝对值最小的数,将它和最后一个数交换,然后输出这10个数。

题目描述 输入 十个数 输出 交换后的十个数 样例输入 10 2 30 40 50 60 70 80 90 100 样例输出 10 100 30 40 50 60 70 80 90 2 1 #include<stdio.h> 2 void fun_A(); 3 int abs(int n); 4 void swap(int *,int *); 5 int main() 6 { 7 fun_A(); 8 return 0; 9 } 10 void fun_A() 11 { 12 const in

【C语言】要求任意输入10个数,然后按从小到大顺序输出

//要求任意输入10个数,然后按从小到大顺序输出 #include <stdio.h> int main() { int a[10]; int i,j; int temp; printf("请输入10个整数:"); for(i=0;i<10;i++) { scanf("%d",&a[i]); } for(i=0;i<9;i++) { for(j=0;j<9-i;j++) { if(a[j]>a[j+1]) { temp=a

输入三个数a,b,n,输出a和b不大于n的公倍数的个数

题:输入三个数a,b,n,输出a和b不大于n的公倍数的所有个数. 这题的思想是先求得a和b的最大公约数,然后用a和b的积除以最大公约数,得到最小公倍数,再持续加上最小公倍数,直到超过n,记下n的个数.如:8,12,100,最大公约数为4,则最小公倍数为24.则公倍数为:24.48.72.96,即总共有4个. 代码如下: 1 #include<iostream> 2 #include<algorithm> 3 4 using namespace std; 5 6 int main()

输入三个数,从大到小排列

//输入3个数,将这三个数从大到小排列打印出来: Console.Write("请输入第一个数字:"); int a = int.Parse(Console.ReadLine()); Console.Write("请输入第一个数字:"); int b = int.Parse(Console.ReadLine()); Console.Write("请输入第一个数字:"); int c = int.Parse(Console.ReadLine());

(c语法百题11)输入一个数 ,输出其绝对值

知识点: if语句 内容: 输入一个数 ,输出其绝对值. 输入说明: 一行一个整数 输出说明: 一行一个整数 输入样例: -3 输出样例 : 3 #include <stdio.h> int main() { int a; scanf("%d",&a); if (a<0) { a=-a; } printf("%d\n",a); return 0; } (c语法百题11)输入一个数 ,输出其绝对值,布布扣,bubuko.com

编程题:用一组数组做函数参数来实现,输入两个数,输出其中最大数

#include<stdio.h> float max(float x,float y) { float z; if(x>y)z=x; else z=y; return z; } void main() { float a[2],c; scanf("%f,%f",&a[0],&a[1]); c=max(a[0],a[1]); printf("%f,%f,the max is %f\n",a[0],a[1],c); } 编程题:用一组