小Q想要给他的朋友发送一个神秘字符串,但是他发现字符串的过于长了,于是小Q发明了一种压缩算法对字符串中重复的部分进行了压缩,对于字符串中连续的m个相同字符串S将会压缩为[m|S](m为一个整数且1<=m<=100),例如字符串ABCABCABC将会被压缩为[3|ABC],现在小Q的同学收到了小Q发送过来的字符串,你能帮助他进行解压缩么?
输入第一行包含一个字符串s,代表压缩后的字符串。
S的长度<=1000;
S仅包含大写字母、[、]、|;
解压后的字符串长度不超过100000;
压缩递归层数不超过10层;
输出一个字符串,代表解压后的字符串。
HG[3|B[2|CA]]F
HGBCACABCACABCACAF
HG[3|B[2|CA]]F−>HG[3|BCACA]F−>HGBCACABCACABCACAF
if __name__=='__main__': s=input() i=0 while(i<len(s)): if(s[i]==']'): j=i k=0 while(s[j]!='['): if(s[j]=='|'): k=j j=j-1 s1=s[j:i+1] num=int(s[j+1:k]) sz=s[k+1:i] sz=sz*num s=s.replace(s1,sz,1) i=j i = i + 1 print(s)
#include <bits/stdc++.h>
using namespace std;
//LeetCode解法 双栈
int main()
{
string s;
cin >> s;
stack<int> numStk;
stack<string> strStk;
int cnt = 0;
string ans;
for(int i = 0; i < s.size(); ++i) {
if(s[i] >= '0' && s[i] <= '9') {
cnt = cnt * 10 + s[i] - '0';
}
else if(s[i] == '|') {
numStk.push(cnt);
cnt = 0;
}
else if(s[i] == '[') {
strStk.push(ans);
ans.clear();
}
else if(s[i] == ']') {
int k = numStk.top();
numStk.pop();
while(k--) strStk.top() += ans;
ans = strStk.top();
strStk.pop();
}
else ans += s[i];
}
cout << ans << endl;
return 0;
} import re
line = input()
pattern = r"\[(\d+)\|(\w+)\]"
tmp = re.search(pattern, line)
while tmp:
l, r = tmp.span()[0], tmp.span()[1]
cur = line[l:r]
mid = cur.find("|")
num = int(cur[1:mid])
chs = cur[mid + 1:-1] * num
line = line[:l] + chs + line[r:]
tmp = re.search(pattern, line)
print(line) Cpp: #include <string>
#include <regex>
#include <iostream>
#include <vector>
using namespace std;
int main() {
string line;
getline(cin, line);
string pattern = "\\[(\\d+)\\|(\\w+)\\]";
regex match(pattern);
smatch tmp;
while (regex_search(line, tmp, match)) {
vector<string> cur;
for (auto iter = tmp.begin(); iter != tmp.end(); iter++) {
cur.push_back(iter->str());
}
int num = atoi(cur[1].c_str());
string chs = ""; // 解压的字串
for (int i = 0; i < num; i++) {
chs += cur[2];
}
int len = cur[0].length(); // 匹配字串的长度
int pos = tmp.position(); // 匹配字串在原字串中的起始位置
line.replace(pos, len, chs);
}
cout << line << endl;
}
Java: import java.util.*;
import java.util.regex.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String line = in.next();
String pattern = "\\[(\\d+)\\|(\\w+)\\]";
Pattern pc = Pattern.compile(pattern);
Matcher m = pc.matcher(line);
while (m.find()) {
int num = Integer.valueOf(m.group(1));
String chs = "";
for (int i = 0; i < num; i++) {
chs += m.group(2);
}
line = m.replaceFirst(chs);
m = pc.matcher(line);
}
System.out.println(line);
}
} import java.util.*;
public class Main{
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
String str = scan.next();
while(str.contains("]")) {
int right = str.indexOf("]");
int left = str.lastIndexOf("[",right);
String tmp = str.substring(left+1,right); // 2|CA
String[] splits = tmp.split("\\|");
int n = Integer.parseInt(splits[0]);
String str2 = "";
for(int i = 0; i < n;i++) {
str2 += splits[1];
}
str = str.replace("[" + tmp + "]", str2);//HG[3|BCACA]F]
}
System.out.println(str);
}
} s=input()
substr=[""]
repnum=[""]
n=0
for i in range(0,len(s)):
if s[i]>='A' and s[i]<='Z':
substr[n]+=s[i]
elif s[i]>='0' and s[i]<='9':
repnum[n]+=s[i]
elif s[i]=="[":
substr.append("")
repnum.append("")
n+=1
elif s[i]=="]":
S=substr.pop()
m=repnum.pop()
n-=1
substr[n]+=S*int(m)
print(substr[0]) //递归解决,C++
#include<bits/stdc++.h>
using namespace std;
string decode(string str)
{
int x=-1,y=-1,z=-1;
int i=0;
while(i<str.size())
{
if(str[i]=='[')
{
x=i;
}
if(str[i]=='|')
{
y=i;
}
if(str[i]==']')
{
z=i;
break;
}
i++;
}
if (x!=-1&&y!=-1&&z!=-1)
{
int num=0;
string num_s=str.substr(x+1,y-x-1);
//cout<<num_s<<endl;
for(int j=0;j<num_s.size();j++)
{
num=num*10+(num_s[j]-'0');
}
//cout<<num<<endl;
string sstr=str.substr(y+1,z-y-1);
//cout<<sstr<<endl;
string ssstr="";
while(num--)
{
ssstr=ssstr+sstr;
}
//cout<<ssstr<<endl;
str=str.substr(0,x)+ssstr+str.substr(z+1);
//cout<<str<<endl;
return decode(str);
}
return str;
}
int main()
{
string str;
cin>>str;
cout<<decode(str);
//cout<<str;
return 0;
}
这题考的应该是“栈”这个知识点,碰到过原题,这里给出迭代的写法,栈用LinkedList实现
stack_res用于暂时保存在 ' ] ' 之前记录的结果,保存的形式如[HG],[B],[CA]
mutil_stack保存的是数字,如[3],[2]
在遇到 ' ] ' 时, 从mutil_stack 队尾取出数字N,对当前字符串[CA] 复制N次。并从stack_res取出上一轮暂存的结果[B]拼接[CA CA]-->[B CACA]
import java.util.LinkedList;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner in =new Scanner(System.in);
String str=in.nextLine();
int mutil=0;//乘数
LinkedList stack_res=new LinkedList();//结果暂存
LinkedList mutil_stack=new LinkedList();
StringBuilder temp=new StringBuilder();
for(int i=0;i<str.length();i++) { //toCharArray() 需要O(n)的空间复杂度,不打算使用
if(str.charAt(i)=='[') {
stack_res.addLast(temp.toString());//保存上一次的结果 [HG]
temp=new StringBuilder();//用于接收新的字母[B]
}else if(str.charAt(i)==']') {
StringBuilder temp2=new StringBuilder();
//取出乘数
int num= mutil_stack.removeLast();
for(int j=0;j<num;j++) {
temp2.append(temp);
}
temp=new StringBuilder(stack_res.removeLast()+temp2);
}else if(str.charAt(i)=='|') {//乘数[3]入栈
mutil_stack.addLast(mutil);
mutil=0;//寻找新的乘数比如[2]
}
else if(str.charAt(i)>='0'&&str.charAt(i)<='9') {
//预防数字出现 [ 19 |a]
mutil=mutil*10+Integer.parseInt(str.charAt(i)+"");
}else {
//正常字母
temp.append(str.charAt(i));
}
}
System.out.print(temp.toString());
}
} const readline = require('readline')
const rl = readline.createInterface({
input: process.stdin,
ouput: process.stdout
})
let inArr = []
rl.on('line', line=>{
if(!line) return
inArr.push(line.trim())
if(inArr.length === 1){
const reg1 = /\[\d+\|[A-Z]*\]/ //[num/(A-Z)*]
const reg2 = /\|/ // |
let str = inArr[0] //inArr str
while(true){
let res = reg1.exec(str)
if(!res) {
break
}
let index = res.index
let before = str.slice(0,index)
let midIndex = reg2.exec(res[0]).index+index
let midNum = str.slice(index+1, midIndex)
let midStr = str.slice(midIndex+1,index+res[0].length-1)
let after = str.slice(index+res[0].length)
let mid = ''
for(let i = 0;i<midNum;i++){
mid += midStr
}
str= before+mid+after
}
console.log(str)
}
}) #include <iostream>
using namespace std;
string ans,str;
int pos;
int get_num()
{
int num = 0;
while(str[pos] >= 48 && str[pos] <= 57)
{
num *= 10;
num += str[pos] - '0';
pos++;
}
return num;
}
bool is_it(char ch)
{
if(ch >= 65 && ch <= 90)
return true;
return false;
}
string get_str()
{
int num = get_num();
pos++;
string temp = "";
string ans_temp = "";
while(str[pos] != ']')
{
if(is_it(str[pos])){
temp += str[pos];
pos++;
}
if(str[pos] == '[')
{
pos++;
temp += get_str();
}
}
pos++;
//cout<<num<<endl;
for(int i=0;i<num;i++)
ans_temp += temp;
//cout<<ans_temp<<endl;
return ans_temp;
}
int main()
{
cin>>str;
//cout<<str<<endl;
ans = "";
pos = 0;
for(;pos<str.size();)
{
if(is_it(str[pos])){
ans += str[pos];
pos++;
}
if(str[pos] == '[')
{
pos++;
ans += get_str();
}
}
cout<<ans<<endl;
return 0;
} 使用递归让我来个go语言
package main
import (
"fmt"
"strings"
)
func find(s string) (int, int) {
j := 0
for j < len(s) && s[j] != ']' {
j++
}
i := j - 1
for i >= 0 && s[i] != '[' {
i--
}
return i, j
}
func main() {
var s string
fmt.Scanln(&s)
ans := ""
for {
x, y := find(s) // 找到匹配的[]的位置
if x == -1 && y == len(s) {
break
}
num := 0
k := x + 1
for s[k] != '|' {
num *= 10
num += int(s[k] - '0')
k++
} //计算重复数字
ans = s[:x] + strings.Repeat(s[k + 1:y], num) + s[y + 1:]
s = ans //更新s
}
fmt.Println(s)
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.regex.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine().trim();
// 构建正则表达式模式:压缩后应该为[数字|字母字符串]
String pattern = "\\[(\\d+)\\|(\\w+)\\]";
Pattern p = Pattern.compile(pattern);
// 按模式pattern对str进行匹配
Matcher m = p.matcher(str);
while(m.find()){
// 模式中第一个括号里的东西
int count = Integer.parseInt(m.group(1)); // 字母字符串的重复次数
// 模式中第二个字符串里的东西
String mode = m.group(2); // 重复的字符串
// 解压
String repeatStr = "";
for(int i = 0; i < count; i++) repeatStr += mode;
// 将原字符串中的重复模式替换为重复的字符串
str = m.replaceFirst(repeatStr);
// 这次匹配替换完了再按同一个模式匹配下一个子串
m = p.matcher(str);
}
System.out.println(str);
}
} s = input() numStk, strStk = [], [] ans = "" cnt = 0 for i in range(len(s)): if s[i].isdigit(): cnt = cnt * 10 + int(s[i]) elif s[i] == '[': strStk.append(ans) ans = "" elif s[i] == '|': numStk.append(cnt) cnt = 0 elif s[i] == ']': k = numStk.pop() tmp = strStk.pop() for _ in range(k): tmp += ans ans = tmp else: ans += s[i] print(ans)
let line = readline()
function decode(s) {
let i =0;
let x = -1, y = -1, z = -1;
let times = 0;
let sub = "";
let decodeStr = "";
while(i < s.length){
if(s[i] === '['){
x = i;
} else if (s[i] === '|'){
y = i;
} else if (s[i] === ']'){
z = i;
break;
}
i++;
}
if(x !== -1 && y !== -1 && z !== -1){
times = parseInt(s.slice(x + 1, y));
//console.log("times:", times);
sub = s.slice(y + 1, z);
//console.log("sub:", sub);
decodeStr = s.slice(0, x) + sub.repeat(times) + s.slice(z + 1);
//console.log("decodeStr:", decodeStr);
return decode(decodeStr);
}
return s;
}
console.log(decode(line)); #include <string>
#include <iostream>
// c++ 5 ms python 135ms
// 思路参考大神
using namespace std;
string decode(const string& str)
{
int i = 0;
int x = -1, y = -1, z = -1;
while (i < str.size())
{
if (str[i] == '[')
x = i;
else if (str[i] == '|')
y = i;
else if (str[i] == ']')
{
z = i;
break;
}
i += 1;
}
if (x != -1 && y != -1 && z != -1)
{
int times = atoi(str.substr(x+1, y-x-1).c_str());
string sub = str.substr(y+1, z-y-1);
auto subs = [=]() {string tmp; for (int i = 0; i < times; i++) {tmp += sub;} return tmp;};
string decode_str = str.substr(0, x) + subs() + str.substr(z+1);
return decode(decode_str);
}
return str; // 如果一个中括号都没有,说明没有需要解码的部分
}
int main()
{
string str;
while (cin >> str)
cout << decode(str) << endl;
return 0;
} //用正则
var a = readline();
fn(a);
function fn(str) {
var reg = new RegExp(/\[[^\[\]]*?\]/g);
var arr = reg.exec(str);
while (arr != null) {
let tmp = arr[0];
let record = arr[0];
tmp = tmp.split('');
tmp.pop();
tmp.shift();
tmp = tmp.join('')
tmp = tmp.split('|');
let temp = tmp[1].repeat(Number(tmp[0]));
str = str.replace(record, temp);
var reg = new RegExp(/\[[^\[\]]*?\]/g);
var arr = reg.exec(str);
}
console.log(str)
} import sys
while True:
line = sys.stdin.readline().strip()
if line == "":
break
stack = []
for s in line:
if s != ']':
stack.append(s)
else:
temp = ''
while stack and stack[-1] != '|':
temp = stack.pop() + temp
stack.pop()
times = ''
while stack and stack[-1].isdigit() and stack[-1] != '[':
times = stack.pop() + times
stack.pop()
stack.append(int(times) * temp)
print("".join(stack)) import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
System.out.println(tar(s));
}
// 递归方法
public static String tar(String s) {
// 递归结束的判断,说明全部解压完毕
if (!s.contains("[") && !s.contains("|")) {
return s;
}
// 形如2|cd的变成cdcd
if (!s.contains("[") && s.contains("|")) {
String x[] = s.split("\\|");
int num = Integer.parseInt(x[0]);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < num; i++)
sb.append(x[1]);
return sb.toString();
}
// 上面if都不执行,说明既有[又有|,说明没有递归到最里层
char a[] = s.toCharArray();
// 用来存储完全解压后的字符串
StringBuffer sb = new StringBuffer();
for (int i = 0; i < a.length; i++) {
// 设置栅栏,使得"["与"]"的个数相同,比如HG[3|B[2|CA]]F,会取得[3|B[2|CA]]
int latch = 0;
if (a[i] == '[') {
latch++;
// 指针往前进一位,形如[3|B[2|CA]],需要得到3|B[2|CA],为了去掉最外面的括号
i++;
if (a[i] == ']') {
latch--;
}
// 用来存储部分解压的字符串,比如有字符串HG[3|B[2|CA]]F中的,这次while循环结束 s1会变成3|B[2|CA]
// 这里再次进行'['的判断是存在[[]]的情况
StringBuffer s1 = new StringBuffer();
while (!(a[i] == ']' && latch == 0)) {
if (a[i] == '[') {
latch++;
}
if (a[i] == ']') {
latch--;
if (latch == 0) {
// 说明到了最外层的]了,不进行下面的appen,为了取出最外层的[]
continue;
}
}
s1.append(a[i]);
// 指针后移,再次进入while循环
i++;
}
// 如果有初始字符串HG[3|B[2|CA]]F,此时s1为3|B[2|CA],去除了一层括号,
String s2 = tar(s1.toString());
// 判断里面还有没有未解压的字符串,有就继续解压,会递归到最里面的2|CA,得到CACA,返回到s2=3|BCACA,再次进行解压
while (s2.contains("|")) {
s2 = tar(s2);
}
// 将解压完毕的字符串字符串加到sb后面
sb.append(s2);
} else {
// 如果没有进行压缩的字符串,直接加到末尾就行
sb.append(a[i]);
}
}
return sb.toString();
}
} #include"stdio.h"
#include"string"
#include<iostream>
#include<stack>
#include<vector>
using namespace std;
int end1=0;
string s2(string s){
stack<char> st;
for(int i=0;i<s.length();i++){
if(s[i]=='['){
st.push(s[i]);
}
else if(s[i]==']'){
char tmpc=st.top();
string tmp;
while(tmpc>='A' && tmpc<='Z'){
tmp=tmpc+tmp;
st.pop();
tmpc=st.top();
}
if(!st.empty()){//delete '|'
st.pop();
}
int n=0;
int cntn=1;
while(st.top()>='0' && st.top()<='9'){
n=n+(st.top()-'0')*cntn;
st.pop();
cntn*=10;
}
string to_store;
while(n>0){
to_store+=tmp;
n--;
}
if(!st.empty()){//delete '['
st.pop();
}
for(char tmpc:to_store){
st.push(tmpc);
}
}
else{
st.push(s[i]);
}
}
string res;
while(!st.empty()){
res=st.top()+res;
st.pop();
}
return res;
}
int main(){
string str;
cin>>str;
string res=s2(str);
cout<<res<<endl;
return 0;
} public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String next = scanner.next();
scanner.close();
System.out.println(decode(next));
}
public static String decode(String words){
while (words.contains("]")){
int right = words.indexOf("]");
int left = words.lastIndexOf("[", right);
String repeatStr = words.substring(left+1, right);
String[] split = repeatStr.split("\\|");
words = words.replace("["+repeatStr+"]",
String.join("", Collections.nCopies(Integer.parseInt(split[0]), split[1])));
}
return words;
} import sys def decode(s): i = 0 x, y, z = -1, -1, -1 while i < len(s): if s[i] == '[': x = i elif s[i] == '|': y = i elif s[i] == ']': z = i break i += 1 if x != -1 and y != -1 and z != -1: times = int(s[x + 1:y]) # 次数 sub = s[y + 1:z] # 子串 decode_str = s[:x] + times * sub + s[z + 1:] # 解码 return decode(decode_str) # 递归解码 return s # 如果一个中括号都没有,说明没有需要解码的部分 for s in sys.stdin: print(decode(s), end='')