递归

老王爱上猫 2014-08-08 11:54:12
从0,1,2,3,4中取3个数可重复(即0,0,0是合理的),列出所有情况...
...全文
248 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
老王爱上猫 2014-08-09
  • 打赏
  • 举报
回复
引用 18 楼 u013656585 的回复:
#include "stdafx.h"
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <sys/stat.h>

/***************************************************************************************/
//对于一个只由0,1,2,3,4组成的三位字符串,可能的组合是000到444                          //
//我的解法是将000到444看成一个五进制数,那么数值的范围就是0 ~ 124                      //
//我只需要借循环输出0~124对应的五进制数的三位字符表示就行了                            //
/***************************************************************************************/
char * ConvertInt2Str(unsigned int nBeConvrt, unsigned int nDesCharLen = 3/*输出字符串位数即长度*/)
{
	assert(nBeConvrt < pow((double)5, (int)nDesCharLen));
	char *pCh;
	unsigned int nTemp = nBeConvrt;
	pCh = new char(nDesCharLen+1);
	assert(pCh != NULL);
	for (int i = nDesCharLen ; i > 0; i--)
	{
		pCh[nDesCharLen - i] = nTemp/pow((double)5,i-1) + 48;
		nTemp = nTemp%(unsigned int)pow((double)5,i-1);
	}
	pCh[nDesCharLen] = '\0';

	return pCh;	
}

int _tmain(int argc, _TCHAR* argv[])
{
	char *pCh2Print;
	int ac = 0;
	for (;ac < 125; ac++)
	{
		pCh2Print = ConvertInt2Str(ac);
		printf("%s\n", pCh2Print);
	}
	
	system("pause");

	return 0;
}
大家有指教直说,别骂我就行。。。
这个方法好新颖,另外将5,当参数传进去,就可以实现N个数中取M个更通用.
老王爱上猫 2014-08-09
  • 打赏
  • 举报
回复
引用 21 楼 mujiok2003 的回复:
C(M,N)递归
谢谢!就是你这个
老王爱上猫 2014-08-09
  • 打赏
  • 举报
回复
引用 8 楼 lovesmiles 的回复:
Data[5]={0,1,2,3,4}

for(int i=0;i<5;i++)

  for(int j=0;j<5;j++)

    for(int k=0;k<5;k++)
          printf("%d,%d,%d\n",Data[i],Data[i],Data[k]);

全排例需要什么递归?
我没说清楚,不一定是5选3,需要通用的N选M,同样谢谢
赵4老师 2014-08-08
  • 打赏
  • 举报
回复
//qplw.cpp
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int v=0;
int w=0;
int m;//记录字符串长度
int n;//记录字符串中的字符种类数
char map[256];//记录是哪几种字符
int count[256];//记录每种字符有多少个
int stack[1000];//递归用的栈,并记录当前生成的排列
void Make_Map(char *str) {//统计字符串的相关信息
    int s[256];
    int i;
    memset(s,0,sizeof(s));
    memset(count,0,sizeof(count));
    m=strlen(str);
    if (w<1 || m<w) w=m;
    while(*str) {
        s[*str]++;
        str++;
    }
    n=0;
    for (i=0;i<256;i++)
        if (s[i]) {
            map[n]=i;
            count[n]=s[i];
            n++;
        }
}
void Find(int depth) {//递归式回溯法生成全排列
    if (depth==w) {
        int i;
        for (i=0;i<depth;i++) putchar(map[stack[i]]);
        putchar('\n');
    } else {
        int i;
        if (v && depth>0) {
            for (i=0;i<depth;i++) putchar(map[stack[i]]);
            putchar('\n');
        }
        for (i=0;i<n;i++)
            if (count[i]) {
                stack[depth]=i;
                count[i]--;
                Find(depth+1);
                count[i]++;
            }
    }
}
void main(int argc,char**argv) {
    if (argc<2) {
        printf("%s 要产生全排列的字符串 [限定长度|-1]\n",argv[0]);
        return;
    }
    if (argc>=3) w=atoi(argv[2]);
    if (-1==w) v=1;
    Make_Map(argv[1]);
    Find(0);
}
//C:\test>qplw
//qplw 要产生全排列的字符串 [限定长度|-1]
//
//C:\test>qplw 123
//123
//132
//213
//231
//312
//321
//
//C:\test>qplw 123 2
//12
//13
//21
//23
//31
//32
//
//C:\test>qplw 122333 3
//122
//123
//132
//133
//212
//213
//221
//223
//231
//232
//233
//312
//313
//321
//322
//323
//331
//332
//333
//
//C:\test>qplw 123 -1
//1
//12
//123
//13
//132
//2
//21
//213
//23
//231
//3
//31
//312
//32
//321
//
movsd 2014-08-08
  • 打赏
  • 举报
回复
老王爱上猫 2014-08-08
  • 打赏
  • 举报
回复
找到答案,来人给分!
vcf_reader 2014-08-08
  • 打赏
  • 举报
回复
楼主是打算暴力破解别人的密码吧?
mujiok2003 2014-08-08
  • 打赏
  • 举报
回复
shiguojie19892 2014-08-08
  • 打赏
  • 举报
回复
转了一圈又回到了原点 ,其实就只需要3个循环就解决了。可以测试一下。
shiguojie19892 2014-08-08
  • 打赏
  • 举报
回复
//这个结果本身就是对的!!!

int main()
{
	int count = 0;
	int n = 3;//要排列的个数
	int a[5] = {0,1,2,3,4};

	for(int i = 0; i < sizeof(a)/4; i++)
	{
		for (int j = 0; j < sizeof(a)/4; j++)
		{
			for (int m = 0; m < sizeof(a)/4; m++)
			{

				printf("%d: %d%d%d\r\n", count++, a[i], a[j], a[m]);
			}
		}
	}
	system("pause");
	return 0;
}
RaphaeL_yb 2014-08-08
  • 打赏
  • 举报
回复
#include "stdafx.h"
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <sys/stat.h>

/***************************************************************************************/
//对于一个只由0,1,2,3,4组成的三位字符串,可能的组合是000到444                          //
//我的解法是将000到444看成一个五进制数,那么数值的范围就是0 ~ 124                      //
//我只需要借循环输出0~124对应的五进制数的三位字符表示就行了                            //
/***************************************************************************************/
char * ConvertInt2Str(unsigned int nBeConvrt, unsigned int nDesCharLen = 3/*输出字符串位数即长度*/)
{
	assert(nBeConvrt < pow((double)5, (int)nDesCharLen));
	char *pCh;
	unsigned int nTemp = nBeConvrt;
	pCh = new char(nDesCharLen+1);
	assert(pCh != NULL);
	for (int i = nDesCharLen ; i > 0; i--)
	{
		pCh[nDesCharLen - i] = nTemp/pow((double)5,i-1) + 48;
		nTemp = nTemp%(unsigned int)pow((double)5,i-1);
	}
	pCh[nDesCharLen] = '\0';

	return pCh;	
}

int _tmain(int argc, _TCHAR* argv[])
{
	char *pCh2Print;
	int ac = 0;
	for (;ac < 125; ac++)
	{
		pCh2Print = ConvertInt2Str(ac);
		printf("%s\n", pCh2Print);
	}
	
	system("pause");

	return 0;
}
大家有指教直说,别骂我就行。。。
shiguojie19892 2014-08-08
  • 打赏
  • 举报
回复
#pragma warning(disable:4786)

#include <iostream>
#include <windows.h>

using namespace std;

struct Int
{
int a;
int b;
int c;
};

Int Itest[1000];

bool duibi(int a, int b, int c);

int main()
{
int count = 0;
int test[15] = {0,0,0,1,1,1,2,2,2,3,3,3,4,4,4};
for (int i = 0; i<15; i++)
{
for (int j = 0; j<15; j++)
{
for(int n = 0; n<15; n++)
{
if (0 != count)
{
if (!duibi(test[i], test[j], test[n]))//如果不重复,继续添加
{
Itest[count].a = test[i];
Itest[count].b = test[j];
Itest[count].c = test[n];

count++;
}
}
else
{ //第一个直接添加
Itest[count].a = test[i];
Itest[count].b = test[j];
Itest[count].c = test[n];

count++;
}
}
}
}

for (i = 0; i <count; i++)
{
printf("%d: %d%d%d\r\n", i, Itest[i].a, Itest[i].b, Itest[i].c);
}

system("pause");
return 0;
}

bool duibi(int a, int b, int c)
{
for (int i = 0; i < 1000; i++)
{
if (Itest[i].a == a &&
Itest[i].b == b &&
Itest[i].c == c)
{
return true;
}
}

return false;
}

leleyjg 2014-08-08
  • 打赏
  • 举报
回复
引用 10 楼 u013656585 的回复:
[quote=引用 8 楼 lovesmiles 的回复:]
Data[5]={0,1,2,3,4}

for(int i=0;i<5;i++)

  for(int j=0;j<5;j++)

    for(int k=0;k<5;k++)
          printf("%d,%d,%d\n",Data[i],Data[i],Data[k]);

全排例需要什么递归?
兄台此言不差,若是不止三位数作何解?[/quote] printf("%d,%d,%d\n",Data[i],Data[i],Data[k]); 是否应该是: printf("%d,%d,%d\n",Data[i],Data[j],Data[k]);
shiguojie19892 2014-08-08
  • 打赏
  • 举报
回复
引用 13 楼 u013656585 的回复:
[quote=引用 11 楼 shiguojie19892 的回复:]
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
	int count = 0;
	int test[15] = {0,0,0,1,1,1,2,2,2,3,3,3,4,4,4};
	for (int i = 0; i<15; i++)
	{
		for (int j = 0; j<15; j++)
		{
			for(int n = 0; n<15; n++)
			{
				
				printf("%d: %d%d%d\r\n", count, test[i], test[j], test[n]);
				count++;
			}
		}
	}

	system("pause");
	return 0;
}
好吧,我原本的意思是输出的字符串不止三位,但是兄台的解题思路倒是给了小弟一个启发。。。[/quote] 这个我试了一下,会有很多的重复的输出,需要STL的一个容器来过滤重复的,正在调试啊。。。
shiguojie19892 2014-08-08
  • 打赏
  • 举报
回复
#pragma warning(disable:4786)
#include <iostream>
#include <set>
#include <windows.h>

using namespace std;

struct Int
{
	int a;
	int b;
	int c;
};
typedef set<Int> SET_INT;
set<Int>::iterator it_set;

Int Itest;
SET_INT set_int;

int main()
{
	int count = 0;
	int test[15] = {0,0,0,1,1,1,2,2,2,3,3,3,4,4,4};
	for (int i = 0; i<15; i++)
	{
		for (int j = 0; j<15; j++)
		{
			for(int n = 0; n<15; n++)
			{
				Itest.a = test[i];
				Itest.b = test[j];
				Itest.c = test[n];
				
				set_int.insert(Itest);
			}
		}
	}

	for (it_set = set_int.begin(); it_set!=set_int.end(); it_set++)
	{
		Itest = *it_set;
		cout << Itest.a << Itest.b << Itest.c;
	}

	system("pause");
	return 0;
}
RaphaeL_yb 2014-08-08
  • 打赏
  • 举报
回复
引用 11 楼 shiguojie19892 的回复:
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
	int count = 0;
	int test[15] = {0,0,0,1,1,1,2,2,2,3,3,3,4,4,4};
	for (int i = 0; i<15; i++)
	{
		for (int j = 0; j<15; j++)
		{
			for(int n = 0; n<15; n++)
			{
				
				printf("%d: %d%d%d\r\n", count, test[i], test[j], test[n]);
				count++;
			}
		}
	}

	system("pause");
	return 0;
}
好吧,我原本的意思是输出的字符串不止三位,但是兄台的解题思路倒是给了小弟一个启发。。。
shiguojie19892 2014-08-08
  • 打赏
  • 举报
回复
shiguojie19892 2014-08-08
  • 打赏
  • 举报
回复
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
	int count = 0;
	int test[15] = {0,0,0,1,1,1,2,2,2,3,3,3,4,4,4};
	for (int i = 0; i<15; i++)
	{
		for (int j = 0; j<15; j++)
		{
			for(int n = 0; n<15; n++)
			{
				
				printf("%d: %d%d%d\r\n", count, test[i], test[j], test[n]);
				count++;
			}
		}
	}

	system("pause");
	return 0;
}
RaphaeL_yb 2014-08-08
  • 打赏
  • 举报
回复
引用 8 楼 lovesmiles 的回复:
Data[5]={0,1,2,3,4}

for(int i=0;i<5;i++)

  for(int j=0;j<5;j++)

    for(int k=0;k<5;k++)
          printf("%d,%d,%d\n",Data[i],Data[i],Data[k]);

全排例需要什么递归?
兄台此言不差,若是不止三位数作何解?
赵4老师 2014-08-08
  • 打赏
  • 举报
回复
引用 4 楼 u013656585 的回复:
赵老师,人家说过的,字符可以重复的,对于0,1,2,3,4,这四个字符的三位任意组合应该有5^3 = 125种吧。。。从000到444都行。。。
qplw 000111222333444 3
加载更多回复(5)

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧