您的位置:首页 > 其它

ZOJ-1004-Anagrams by Stack

2006-05-10 06:09 447 查看
程序虽然Accpeted了,但是还是觉得有必要认真归纳一下解题过程,这样会比较有助于自己的提高,今天先从1004开始,其他题的日后再补上。
题目如下:
AnagramsbyStack
[align=center][/align]
Timelimit:1SecondsMemorylimit:32768K
TotalSubmit:1583AcceptedSubmit:659
[align=center][/align]
Howcananagramsresultfromsequencesofstackoperations?TherearetwosequencesofstackoperatorswhichcanconvertTROTtoTORT:
[
iiiioooo
ioiiooio
]
whereistandsforPushandostandsforPop.Yourprogramshould,givenpairsofwordsproducesequencesofstackoperationswhichconvertthefirstwordtothesecond.
Input
Theinputwillconsistofseverallinesofinput.Thefirstlineofeachpairofinputlinesistobeconsideredasasourceword(whichdoesnotincludetheend-of-linecharacter).Thesecondline(again,notincludingtheend-of-linecharacter)ofeachpairisatargetword.Theendofinputismarkedbyendoffile.
Output
Foreachinputpair,yourprogramshouldproduceasortedlistofvalidsequencesofiandowhichproducethetargetwordfromthesourceword.Eachlistshouldbedelimitedby
[
]
andthesequencesshouldbeprintedin"dictionaryorder".Withineachsequence,eachiandoisfollowedbyasinglespaceandeachsequenceisterminatedbyanewline.
Process
Astackisadatastorageandretrievalstructurepermittingtwooperations:
Push-toinsertanitemand
Pop-toretrievethemostrecentlypusheditem
Wewillusethesymboli(in)forpushando(out)forpopoperationsforaninitiallyemptystackofcharacters.Givenaninputword,somesequencesofpushandpopoperationsarevalidinthateverycharacterofthewordisbothpushedandpopped,andfurthermore,noattemptisevermadetopoptheemptystack.Forexample,ifthewordFOOisinput,thenthesequence:
iioioo
isvalid,but
iio
isnot(it'stooshort),neitheris
iioooi
(there'sanillegalpopofanemptystack)
Validsequencesyieldrearrangementsofthelettersinaninputword.Forexample,theinputwordFOOandthesequenceiioiooproducetheanagramOOF.Soalsowouldthesequenceiiiooo.Youaretowriteaprogramtoinputpairsofwordsandoutputallthevalidsequencesofiandowhichwillproducethesecondmemberofeachpairfromthefirst.
SampleInput
madam
adamm
bahama
bahama
long
short
eric
rice
SampleOutput
[
iiiioooioo
iiiiooooio
iioioioioo
iioioiooio
]
[
ioiiiooiiooo
ioiiioooioio
ioioioiiiooo
ioioioioioio
]
[
]
[
iioioioo
]

很明显这是一个要用到栈与回溯的题。
因为不想用STL,我最初设计了一个简单的栈类,存储源字符串,目标字符串和中间临时的字符串,后来想到由于临时字符串需要有记忆步骤的功能,于是为了练习C++的概念,添加了一个新类,让它继承前面简单的栈类,又附加了记录I/O步骤的功能以及相应的数据结构。记录I/O步骤是为了在遍历后找到和目标字符串对应的结果后,能直接输出所有步骤。
但是很遗憾,遍历并且筛选出合适组合的时间超出了我的想象,当输入为6个字符时,时间已经长达2-3秒,所以我点了Edit栏里的SelectAll,然后按下Backspace…..

因为懒得再重新写一遍栈类,所以还是用了STL,其实也只用到了pop(),push()和empty(),top()这4个成员函数,写一遍也花不了多长时间,以后还是自己写的好,多写多熟练思路也就开阔了。

下面这个最终Accpeted的程序结构非常清晰。在函数
voidresult(stack<char>&s)

中,用了3个IF以实现递归回溯求解,这3个IF的顺序很重要,判断是否输出结果在第一,另外输入判断if(sp<n)在输出判断if(!s.empty())前,既是思考上的顺序,同时也保证了题目中所要求的"dictionaryorder"。

if(tp==n)

if(sp<n)

if(!s.empty())


对于sword和tword字符数组,其实也可以用指针或栈来实现,不过我选择了用数组下标实现。其实栈说白了
就是对数组及其下标的活用。

我在这道题的收获大概有两点:
1.对于思路的考虑逻辑上一定要清晰严密,并且对于编程来讲具有可操作性。
2.温习了栈与回溯的实现。

说到底,解所有题都是两个过程
1.审题,得出解决问题的思路
2.将大脑里的思路以程序代码的方式表达出来。

#include<iostream>

#include<string.h>

#include<stack>

usingnamespacestd;


charsword[11];//来源字符串

chartword[11];//目标字符串

charstep[100];//记录步骤的字符数组

intsteplen,sp,tp,n;

//steplen:步骤长度

//sp:记录当前操作的字符在sword中的位置

//tp:记录当前操作的字符在tword中的位置

//n:被赋为字符串长度



voidresult(stack<char>&s)

{

charch;

inti;

if(tp==n)//与目标字符串校对完成,所以step必然是正确的

{

for(i=0;i<steplen;i++)

{

cout<<step[i]<<"";

}

cout<<endl;

return;

}


if(sp<n)//对于源字符串挨个push进栈s产生输入i

{

s.push(sword[sp++]);

step[steplen++]='i';

result(s);

s.pop();

steplen--;

sp--;

}


if(!s.empty())//栈s不为空时,对比栈头和当前目标字符

{//如果相等,便产生输出o

ch=s.top();

if(ch==tword[tp])

{

s.pop();

tp++;

step[steplen++]='o';

result(s);

steplen--;

tp--;

s.push(ch);

}

}

}


intmain()

{

stack<char>strtemp;

while(cin>>sword>>tword)

{

cout<<"["<<endl;

n=strlen(sword);

if(n==strlen(tword))

{

sp=0;tp=0;

steplen=0;

result(strtemp);

}

cout<<"]"<<endl;

}

return0;

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: