53
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;
}
发表于 2020-03-21 11:50:44
回复(8)
19
//源代码思路参考某大神
#include
#include
using namespace std;
int main(){
string s;
cin>>s;
int i = 0;
while(i
if(s[i] == ']'){
int j = i;//j用来向前寻找与]相匹配的[
int k = 0;//k用来记录'|'所在位置
while(s[j] != '['){
if(s[j] == '|')
k = j;
j--;
}
int len = stoi(s.substr(j+1,k-j));
string s1 = s.substr(k+1,i - k - 1);
string s2;
for(int si = 0; si
s2 += s1;
}
s = s.replace(j,i-j+1,s2);
i = j;//替换后i所指向的内容变化,从替换部分的头开始再寻找
}
i++;
}
cout<
}
编辑于 2020-01-21 10:28:55
回复(9)
40
使用递归的思路非常清晰,每次解码最内层的中括号内容即可
import sys
def decode(s):
i = 0
x, y, z = -1, -1, -1
while i
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='')
编辑于 2020-03-17 22:00:12
回复(4)
38
if __name__=='__main__':
s=input()
i=0
while(i
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)
发表于 2020-01-11 23:13:38
回复(7)
4
#include
using namespace std;
//LeetCode解法 双栈
int main()
{
string s;
cin >> s;
stack numStk;
stack strStk;
int cnt = 0;
string ans;
for(int i = 0; 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 <
return 0;
}
发表于 2020-05-28 17:51:54
回复(0)
6
刚学正则,试写了三种语言的正则解法以体会区别:
Python:
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
#include
#include
#include
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 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
chs += cur[2];
}
int len = cur[0].length(); // 匹配字串的长度
int pos = tmp.position(); // 匹配字串在原字串中的起始位置
line.replace(pos, len, chs);
}
cout <
} 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
chs += m.group(2);
}
line = m.replaceFirst(chs);
m = pc.matcher(line);
}
System.out.println(line);
}
}
编辑于 2020-03-02 18:43:01
回复(5)
3
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
str2 += splits[1];
}
str = str.replace("[" + tmp + "]", str2);//HG[3|BCACA]F]
}
System.out.println(str);
}
}
编辑于 2020-08-20 14:53:57
回复(1)
3
栈
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])
发表于 2020-07-02 18:05:44
回复(0)
3
//递归解决,C++
#include
using namespace std;
string decode(string str)
{
int x=-1,y=-1,z=-1;
int i=0;
while(i
{
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<
for(int j=0;j
{
num=num*10+(num_s[j]-'0');
}
//cout<
string sstr=str.substr(y+1,z-y-1);
//cout<
string ssstr="";
while(num--)
{
ssstr=ssstr+sstr;
}
//cout<
str=str.substr(0,x)+ssstr+str.substr(z+1);
//cout<
return decode(str);
}
return str;
}
int main()
{
string str;
cin>>str;
cout<
//cout<
return 0;
}
发表于 2020-04-26 00:05:32
回复(0)
3
这题考的应该是“栈”这个知识点,碰到过原题,这里给出迭代的写法,栈用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
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
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());
}
}
编辑于 2020-03-08 14:36:35
回复(1)
2
JavaScript(Node) RegExp + slice 😎
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
mid += midStr
}
str= before+mid+after
}
console.log(str)
}
})
发表于 2020-02-18 12:30:27
回复(1)
1
让我来个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)
}
发表于 2021-02-23 00:43:15
回复(0)
1
直接用正则表达式求解,每次都去匹配“[数字|字母串]”的模式,但要注意每次进行解压替换的时候只能替换一个,否则abc[3|hb]s[5|tsq]就会把两个附和模式的地方都解压成同一个字符串的重复abchbhbhbshbhbhbhbhb,而不是abchbhbhbstsqtsqtsqtsqtsq。
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
// 将原字符串中的重复模式替换为重复的字符串
str = m.replaceFirst(repeatStr);
// 这次匹配替换完了再按同一个模式匹配下一个子串
m = p.matcher(str);
}
System.out.println(str);
}
}
发表于 2021-02-04 10:44:15
回复(0)
1
Python版本的双栈法:
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)
编辑于 2020-11-26 19:23:44
回复(0)
1
参考top1递归的做法,十分简洁,改用javascript实现,全ac
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
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));
编辑于 2020-08-24 11:04:53
回复(0)
1
#include
#include
// 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
{
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
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 <
return 0;
}
发表于 2020-08-20 15:15:34
回复(0)
1
//用正则
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)
}
编辑于 2020-08-20 11:33:11
回复(0)
1
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))
发表于 2020-07-03 13:47:19
回复(0)
1
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
sb.append(x[1]);
return sb.toString();
}
// 上面if都不执行,说明既有[又有|,说明没有递归到最里层
char a[] = s.toCharArray();
// 用来存储完全解压后的字符串
StringBuffer sb = new StringBuffer();
for (int i = 0; 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();
}
}
发表于 2020-01-12 13:51:15
回复(1)
1
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String next = scanner.next();
scanner.close();
System.out.println(replace(next));
}
private static String replace(String str) {
if (str.contains("]")) {
int i =0;
while (i<=str.length()){
if ("]".charAt(0) == str.charAt(i++)){
break;
}
}
int j = i-1;
while (0 <= j) {
char c = str.charAt(j--);
if ("[".charAt(0) == c) {
String repeatStr = str.substring(j + 2, i - 1);
String[] split = repeatStr.split("\\|");
Integer num = Integer.parseInt(split[0]);
String compress = split[1];
StringBuilder builder = new StringBuilder();
while (0
builder.append(compress);
num--;
}
str = replace(str.replace("["+repeatStr+"]",builder.toString()));
}
}
}
return str;
}
发表于 2020-02-07 16:42:54
回复(0)