首页 > 试题广场 >

压缩算法

[编程题]压缩算法
  • 热度指数:10816 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
小Q想要给他的朋友发送一个神秘字符串,但是他发现字符串的过于长了,于是小Q发明了一种压缩算法对字符串中重复的部分进行了压缩,对于字符串中连续的m个相同字符串S将会压缩为[m|S](m为一个整数且1<=m<=100),例如字符串ABCABCABC将会被压缩为[3|ABC],现在小Q的同学收到了小Q发送过来的字符串,你能帮助他进行解压缩么? 

输入描述:
输入第一行包含一个字符串s,代表压缩后的字符串。
S的长度<=1000;
S仅包含大写字母、[、]、|;
解压后的字符串长度不超过100000;
压缩递归层数不超过10层;


输出描述:
输出一个字符串,代表解压后的字符串。
示例1

输入

HG[3|B[2|CA]]F

输出

HGBCACABCACABCACAF

说明

HG[3|B[2|CA]]F−>HG[3|BCACA]F−>HGBCACABCACABCACAF
function chongfu(arr) {
    // 将最内层的进行字符串转换
    var  count=0
    var str=''
    var num=arr[1]//得到重复次数
    if (arr[0]=='['){
        for(let j=3;j<arr.length;j++){
            str=str+arr[j]//得到字符串
            count++
        }

    }
    // 定义输出字符串,字符串重复的次数
    var restr=''
    for (var k=0;k<num;k++){
        restr = restr+str
    }
    console.log(restr)
    return restr
}

function jieya(str) {
    //双数组模拟链表,主要思想是像链表一样操作
    var arr=str.split('')//字符串转数组
    var arr2=arr//存储正向
    var arr3=[]//存储反向
    for(let i=arr.length-1;i>=0;i--){
        arr3[arr.length-1-i]=arr[i]
    }
    // 解压最内层后的字符串
    let strResult=''
    let i=0
    let j=0
    while (i<arr.length){
        //正向循环
        if (arr2[i]==='['){
            // 遇到第一个[
            console.log('i是'+i)
            while (j<arr3.length){
                console.log()
                if (arr3[j]===']'){
                    //前面的[对应的]
                    console.log('j是'+j)
                    if (arr2.slice(i+2,arr2.length-j-1).indexOf('[')<0){
                        //判断是不是最内层的[]
                        // 如果是取出来进行字符串转换
                        newarr=arr2.slice(i,arr2.length-j-1)
                        // 转化最内层的+数组后面的未经处理的
                        strResult=strResult+chongfu(newarr)+(arr2.slice(arr2.length-j)).join('')
                        // 内层转化后形成新字符串再进行递归
                        return jieya(strResult)
                    }else {
                        j++
                        break
                    }
                }
                j++
            }
        }
        strResult=strResult+arr2[i]
        i++
    }
    return strResult
}
console.log(jieya('HG[3|B[2|CA]]F'))//HGBCACABCACABCACAF

编辑于 2020-04-22 23:59:09 回复(0)
更多回答
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)


发表于 2020-01-11 23:13:38 回复(7)
#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;
}

发表于 2020-05-28 17:51:54 回复(0)
刚学正则,试写了三种语言的正则解法以体会区别:
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 <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);
    }
}




编辑于 2020-03-02 18:43:01 回复(5)
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);
        }
}

编辑于 2020-08-20 14:53:57 回复(1)

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)
//递归解决,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;

}

发表于 2020-04-26 00:05:32 回复(0)

这题考的应该是“栈”这个知识点,碰到过原题,这里给出迭代的写法,栈用LinkedList实现

  1. stack_res用于暂时保存在 ' ] ' 之前记录的结果,保存的形式如[HG],[B],[CA]

  2. mutil_stack保存的是数字,如[3],[2]

  3. 在遇到 ' ] ' 时, 从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());
      }
    }
编辑于 2020-03-08 14:36:35 回复(1)
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<midNum;i++){
                mid += midStr 
            }
            str= before+mid+after   
        }
        console.log(str)
    }
})
发表于 2020-02-18 12:30:27 回复(1)
#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;
}
使用递归

编辑于 2020-02-05 16:54:20 回复(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)
}
发表于 2021-02-23 00:43:15 回复(0)
直接用正则表达式求解,每次都去匹配“[数字|字母串]”的模式,但要注意每次进行解压替换的时候只能替换一个,否则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 < count; i++) repeatStr += mode;
            // 将原字符串中的重复模式替换为重复的字符串
            str = m.replaceFirst(repeatStr);
            // 这次匹配替换完了再按同一个模式匹配下一个子串
            m = p.matcher(str);
        }
        System.out.println(str);
    }
}


发表于 2021-02-04 10:44:15 回复(0)
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)
参考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 < 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));


编辑于 2020-08-24 11:04:53 回复(0)
t_f头像 t_f
#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;
}

发表于 2020-08-20 15:15:34 回复(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)
        }

编辑于 2020-08-20 11:33:11 回复(0)
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)
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();

	}
}

发表于 2020-01-12 13:51:15 回复(1)
C++使用栈解决
#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;
}


发表于 2020-01-14 20:55:13 回复(4)
    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)
使用递归的思路非常清晰,每次解码最内层的中括号内容即可

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='')


编辑于 2020-03-17 22:00:12 回复(4)