一个有关C语言的问题?

yu_gh 2002-09-10 06:47:16
我现在要用Sub(*str);实现输入字串,我要输出其所有子串(例:输入1234;输出1,2,3,4,12,13,14,23,24,34,123,124,234,134等,我想请教大哥哥们
怎么实现?(具体)
...全文
52 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
snwcwt 2002-10-08
  • 打赏
  • 举报
回复
例9.7:找出从自然数1,2,...,n中任取r个数的所有组合。例如n=5,r=3,所有组合为:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5


解:采用回溯法找问题的解,将找到的组合以从小到大顺序存于a[0],a[1],...,a[r-1]中,组合的元素满足以下性质:
(1)a[i+1]>a[i],后一个数字比前一个大;
(2)a[i]-1<=n-r+1。
按回溯法思想,找解过程可以叙述如下:首先放弃组合数个数为r的条件,候选组合从只有一个数字1开始。因该候选解满足除问题规模之外的全部条件,扩大其规模,并使其满足上述条件(1),候选组合改为1,2。继续这一过程,得到候选组合1,2,3。该候选项解满足包括问题规模在内的全部要求,因而是一个解。在该解基础上,选下一个候选解,因a[2]上的3调整为4,以及以后调整为5都满足问题的全部要求,得到解1,2,4和1,2,5。由于对5不能再作调整,就要从a[2]回溯至工a[1],这时的a[1]=2,可以调整为3,并向前试探,得到解1,3,4。重复上述向前试探和向后回溯,直至要从a[0]再回溯时,说明已找完问题的全部解。按上述思想写成程序如下:

#include <stdio.h>
#define MAXN 100
int a[MAXN];
void comb_back(int m, int r)
{
int i,j;
i=0;
a[i]=1;
do
{
if(a[i]-i <= m-r+1) /*还可以向前试探*/
{ /*已找到一个组合*/
if(i == r-1)
{
for(j=0; j<r; j++) printf("%4d", a[j]);
printf("\n");
a[i]++;
continue;
}
i++; /*向前试探*/
a[i] = a[i-1]+1;
}
else
{ /*回溯*/
if(i == 0) return; /*已找完了全部解*/
a[--i]++;
}
} while(1);
}

void main()
{
comb_back(5,1);
}


PS:抄自《系统设计师(高级程序员)教程》 版次:2001年5月第1版(P.504)
此书P.493有一递归解法
zhengguoshan 2002-09-22
  • 打赏
  • 举报
回复
/*初始字符串str[0,n)组成一个最小数(升序),从尾巴开始向头判断,
如果涵盖的字符串可以组成一个更大的数,则转换成最小的较大数并且
重新从尾巴向头判断。
比如1234,34可以组成更大的数字,将34变成43:1243。243可以组成比
它大的最小数324:1324。24又可以变成42:1342。342->423:1423。
23->32:1432...
bc++3.1
*/

#include <iostream.h>
#include <string.h>
void sort(char*,char*);//排序成为升序
void display(const char*,const char*);//显示
int canGreater(const char*,const char*);
void beGreater(char*,char*);
void main()
{ char buff[10],ch;
int i,length;
cout<<"Input numbers:"<<endl;
cin>>buff;
length=strlen(buff);
sort(buff,buff+length);
cout<<"The result is:"<<endl;
display(buff,buff+length);
i=length-2;
while(canGreater(buff,buff+length)){
if(canGreater(buff+i,buff+length)){
beGreater(buff+i,buff+length);
display(buff,buff+length);
i=length-1;
}
else i--;

}
}
void sort(char*first,char*end)
{ char *p1,*p2,ch;
for(;first<end-1;first++){
ch=*first;p2=first;
for(p1=first+1;p1<end;p1++){
if(ch>*p1){
ch=*p1;
p2=p1;
}//if
}//for(p1
*p2=*first;
*first=ch;
}//for
}

void display(const char*first,const char*end)
{
for(;first<end;first++)
cout<<*first;
cout<<' ';
}
//判断[first,end)涵盖的字符串是否可以组成更大的数字

int canGreater(const char*first,const char*end)
{ const char *p;
for(p=end-1;p>first;p--)
if(*p>*(p-1)) return 1;
return 0;
}



//把[first,end)涵盖的字符串组成最小的更大数,
//其中[first+1,end)为降序
void beGreater(char*first,char*end)
{ char *p,ch=*first;
for(p=end-1;p>first;p--)
if(*p>*first)
{ ch=*p;
break;
}
*p=*first;
*first=ch;
sort(first+1,end);
}
和这倒题差不多。。
仔细看一下就明白了。。。
liubear 2002-09-22
  • 打赏
  • 举报
回复
这竟是一个算法的题目
alexxing 2002-09-20
  • 打赏
  • 举报
回复
我把上面的主程序改为

int main(void)
{
getAllSubStr("1234");
getAllSubStr("abc");
getAllSubStr("abcd");
getAllSubStr("XYZ");
getAllSubStr("ZYX");
return 0;
}

结果如下,你看是不是符合你的“子串”的定义(至少 “1234” 的结果是完全一样的)


results of 1234:
substr(1)=1
substr(2)=2
substr(3)=12
substr(4)=3
substr(5)=13
substr(6)=23
substr(7)=123
substr(8)=4
substr(9)=14
substr(10)=24
substr(11)=124
substr(12)=34
substr(13)=134
substr(14)=234

results of abc:
substr(1)=a
substr(2)=b
substr(3)=ab
substr(4)=c
substr(5)=ac
substr(6)=bc

results of abcd:
substr(1)=a
substr(2)=b
substr(3)=ab
substr(4)=c
substr(5)=ac
substr(6)=bc
substr(7)=abc
substr(8)=d
substr(9)=ad
substr(10)=bd
substr(11)=abd
substr(12)=cd
substr(13)=acd
substr(14)=bcd

results of XYZ:
substr(1)=X
substr(2)=Y
substr(3)=XY
substr(4)=Z
substr(5)=XZ
substr(6)=YZ

results of ZYX:
substr(1)=Z
substr(2)=Y
substr(3)=ZY
substr(4)=X
substr(5)=ZX
substr(6)=YX


================================================================
人生最大的幸福莫过于顿顿有玉米吃
(CSDN 论坛助手,挺好使!俺们拨号上网的有福了)
alexxing 2002-09-20
  • 打赏
  • 举报
回复
还在讨论哪?这个帖子够长寿的
前面忘了说,我上面的程序是调试通过的

#include <assert.h>
#include <string.h>
#include <stdio.h>

typedef unsigned long HUGEINT;//对64位系统定义 unsigned __int64

inline unsigned getBit(HUGEINT d, int i)
{
return (d >> i) & 1;
}

void getAllSubStr(const char str[])
{
int N = strlen(str);
assert( N < 32 );// 因为采用32位整数,为简化问题,最多处理31个元素

// 计算 ResultCount = 2^N - 2
HUGEINT ResultCount = (1ul << N) - 2ul;

// 所有的整数 1..ResultCount-1 对应所有的排列
printf("\nresults of %s:\n", str);
for ( HUGEINT placement = 1; placement <= ResultCount; placement++ )
{
char buf[32];
char * p = buf;
// placement 各位就表示各元素的出现情况
for ( int i = 0; i < N; i ++ )
{
unsigned bit = getBit(placement, i);
// 其实这里可以优化,但为了清晰,先这么写吧
// 如果此位=1,对应字符放入 buf
if ( bit )
*p++ = str[i];
}
*p = 0;
// 输出此结果
printf(" substr(%lu)=%s\n", placement, buf);
}
}

int main(void)
{
getAllSubStr("abc");
getAllSubStr("abcd");
getAllSubStr("XYZ");
getAllSubStr("ZYX");
return 0;
}


================================================================
人生最大的幸福莫过于顿顿有玉米吃
(CSDN 论坛助手,挺好使!俺们拨号上网的有福了)
用户 昵称 2002-09-20
  • 打赏
  • 举报
回复
kao 这么多人都来了
up
zhf0021 2002-09-20
  • 打赏
  • 举报
回复
up
yu_gh 2002-09-20
  • 打赏
  • 举报
回复
谢谢上面的大哥哥的指导
woxihuanbohe 2002-09-12
  • 打赏
  • 举报
回复
非得要用递归吗
用试探回溯法行不行?
Nokiacoco 2002-09-12
  • 打赏
  • 举报
回复
虽然我不会,但我很愿意学学,多谢各位指点了
starsoft007 2002-09-12
  • 打赏
  • 举报
回复
哦,对不起。
我的程序有点问题。
得到的答案不全。
starsoft007 2002-09-12
  • 打赏
  • 举报
回复
//============================================================
// SubString.cpp
//
// Get all sub string of a specific string.
//============================================================

#include <stdio.h>
#include <string.h>
#include <malloc.h>

char *SubStr(char *str,int sPos,int cnt);

int main(int argc,char *argv[])
{
unsigned int StartPos; // The starting position.
unsigned int NumCounts; // The number amounts you need to fetch.
unsigned int StrLen; // The length of specific string.
unsigned int tmppos;
unsigned int TmpLen;
unsigned int Counts; // Total output.
int flag;
char *string;
char *temp;
char *Result;

// Initialization.
Counts = 0;
flag = 0;
StartPos = 0;
NumCounts = 1;
string = NULL;
temp = NULL;
TmpLen = 0;

// Check whether the argument is input.
if (argc < 2)
{
printf("Please input a string!\n");
return 0;
}

string = argv[1];
StrLen = strlen(string);
if (StrLen <= 0)
{
printf("Invalid string,please input another.\n");
return 0;
}

//
Result = (char *)malloc(sizeof(char) * StrLen);

while (NumCounts < StrLen)
{
StartPos = 0;
while (StartPos < StrLen)
{
temp = SubStr(string,StartPos,1);
strcpy(Result,temp);
tmppos = StartPos + 1;
while (strlen(Result) < NumCounts && tmppos < StrLen)
{
flag = 1;
temp = SubStr(string,tmppos,1);
strcat(Result,temp);
if (strlen(Result) >= NumCounts && tmppos < StrLen )
{
if (Counts%5 == 0)
printf("\n");
printf("%s\t",Result);
Counts++;
tmppos++;
Result = SubStr(Result,0,NumCounts - 1);
}
else
tmppos++;
}
if (!flag)
{
if (Counts%5 == 0 && Counts != 0)
printf("\n");
printf("%s\t",Result);
Counts++;
}
StartPos++;
}
NumCounts++;
}
printf("\nTotal Substring is :%d\n",Counts);
return 0;
}

//============================================================
// SubStr()
//
// Get the sub string of a string
//============================================================
char *SubStr(char *str,int sPos,int cnt)
{
int strLen;
int i;
static char *tmp;
char *tmp1;

tmp1 = NULL;
tmp = (char *)malloc(sizeof(char) * (cnt + 1));
tmp1 = tmp;
strLen = strlen(str);

if (sPos > strLen)
return 0;

for (i = 0; i < sPos; i ++)
str++;

for (i = 0; i < cnt; i++)
*tmp1++ = *str++;
*tmp1 = '\0';
return tmp;
}

俺把取子串的函数给忘了,自己弄了一个。可能没有原配的好
但可以用。
alexxing 2002-09-11
  • 打赏
  • 举报
回复
to stidio_zhougang(回头是岸):
你觉得我的子串是没有顺序的吗?
stidio_zhougang 2002-09-10
  • 打赏
  • 举报
回复
//main.h文件,对上面的类的测试
#include "SoleVector.h"
using namespace std;
int main()
{
cSoleVector *pTest=new cSoleVector();
pTest->PrintSoleVector(pTest->GetSize());
cout<<cSoleVector::counter;
}

网速太慢,我也没办法才这样做,不过TO: alexxing(赤铸)
子串应该有顺序的?!
stidio_zhougang 2002-09-10
  • 打赏
  • 举报
回复
cSoleVector::~cSoleVector()
{
delete[] pOnlyStr;
delete[] pOutputStr;
delete[] pJudgeArray;
}

void cSoleVector::PrintSoleVector(int depth)
{
int i;
if(depth==0)
{
cSoleVector::counter++;
cout<<this->pOutputStr<<endl;
return;
}
for(i=0;i<size;i++)
{
if(this->pJudgeArray[i]==true)
continue;
else
{
this->pJudgeArray[i]=true;
pOutputStr[this->size-depth]=this->pOnlyStr[i];
PrintSoleVector(depth-1);
this->pJudgeArray[i]=false;
}
}
}

int cSoleVector::GetSize()
{
return size;
}
stidio_zhougang 2002-09-10
  • 打赏
  • 举报
回复
//SoleVector.cpp文件,实现部分
#include "SoleVector.h"
#include <string.h>
long cSoleVector::counter=0;
cSoleVector::cSoleVector()
{
int i;
this->size=4;
this->pOnlyStr=new char[size+1];
strcpy(pOnlyStr,"ABCD");
this->pOutputStr=new char[size+1];
this->pJudgeArray=new bool[size];
for(i=0;i<size;i++)
{
*(pOutputStr+i)='\0';
*(pJudgeArray+i)=false;
}
*(pOutputStr+i)='\0';
}
cSoleVector::cSoleVector(const char *pInitValue)
{
int i;
this->size=strlen(pInitValue);
this->pOnlyStr=new char[size+1];
strcpy(pOnlyStr,pInitValue);
this->pOutputStr=new char[size+1];
this->pJudgeArray=new bool[size];
for(i=0;i<size;i++)
{
*(pOutputStr+i)='\0';
*(pJudgeArray+i)=false;
}
*(pOutputStr+i)='\0';
}
hait1984 2002-09-10
  • 打赏
  • 举报
回复
up
stidio_zhougang 2002-09-10
  • 打赏
  • 举报
回复
我刚刚写了一个,三个文件
//SoleVector.h文件,定义部分
#include <iostream>
using namespace std;
class cSoleVector{
public:
cSoleVector();
cSoleVector(const char *pInitValue);
~cSoleVector();
void PrintSoleVector(int depth);
int GetSize();
static long counter;
private:
char *pOnlyStr;
bool *pJudgeArray;
char *pOutputStr;
int size;
};
djwinter 2002-09-10
  • 打赏
  • 举报
回复
循环嵌套很好实现的:)
snwcwt 2002-09-10
  • 打赏
  • 举报
回复
UP一下
加载更多回复(9)

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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