展開字符串
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1265 Accepted Submission(s): 563
該問題的描述是這樣的:常用紗線的品種一般不會超過25種,所以分別可以用小寫字母表示不同的紗線,例如:abc表示三根紗線的排列;重複可以用數字和括號表示,例如:2(abc)表示abcabc;1(a)=1a表示a;2ab表示aab;如果括號前面沒有表示重複的數字出現,則就可認爲是1被省略了,如:cd(abc)=cd1(abc)=cdabc;這種表示方法非常簡單緊湊,也易於理解;但是計算機卻不能理解。爲了使計算機接受,就必須將簡單緊湊的表達方式展開。某ACM隊接受了此項任務。現在你就是該ACM隊的一員,請你把這個程序編寫完成。
已知條件:輸入的簡單緊湊表達方式的長度不超過250個字符;括號前表示重複的數不超過1000;不會出現除了數字、括號、小寫字母以外的任何其他字符;不會出現括號不配對等錯誤的情況(錯誤處理已由ACM其他隊員完成了)。
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Main {
static int n,len;
static String sa,str;
static char s[],c;
static int[]keep = new int[1];
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(new InputStreamReader(System.in));
// BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = sc.nextInt();//不知爲何在hdu oj上不能用BufferedReader中的br.readLine()/sc.nextLine()一用就錯>_<!!
while(T-->0){
sa = sc.next();
len = sa.length();
s = (sa+" ").toCharArray();//防止下面的指針超出數組界限溢出
keep[0]=0;//記錄遞歸一次訪問最遠的位置
System.out.println(dfs(0));
}
}
private static String dfs(int i){
String stemp="";//每個遞歸中都有一個stemp,記錄該層裏的字符串,再將其返回
String digt = "";//,每層都有一個記錄數字的字符串
int w = 1;
boolean flag = true;
for(c=s[i++] ; i<=len && c!=')'; c=s[i++] ){
w = 1;//默認爲的字母前參數爲 1
for( ;c>='0'&&c<='9'; c=s[i++]){//記錄數字
digt +=c;
flag = false;
}
if(!flag){//記錄數字
w = Integer.parseInt(digt);
digt = "";
flag = true;
}
if(c>='a'&&c<='z'){
while(w-->0)
stemp =stemp+""+c;
}
else if(c=='('){
String k = dfs(i);//臨時變量
while(w-->0)
stemp = stemp + "" + k;
i = keep[0];//字符串從遞歸最遠處,再開始進行
}
}
if(c==')')
keep[0]=i;//標記遞歸到的位置
return stemp;
}
}
他人C/CC++代碼,供參考:#include <iostream>
#include <cctype>
#include <cstring>
#include <string>
using namespace std;
string s;
int fun(int ith)
{
int k,e;
char c;
for(c=s[ith++];ith<s.size()&&c!=')';c=s[ith++])//遞歸結束的條件是字符串結束或遇到右括號
{
for(k=0;isdigit(c);c=s[ith++])
k=k*10+c-'0';
if(!k) k=1;
if(c=='('){
while(k--)
e=fun(ith);
ith=e;//重置ith的值,到下層遞歸結束的位置
}
else
{
while(k--)
putchar(c);
}
}
if(c==')') return ith;//返回本次讀到結尾的位置
}
int main()
{
int i,j,k,T;
cin>>T;
while(T--)
{
s.clear();
cin>>s;
fun(0);//進入遞歸
cout<<endl;
}
return 0;
}