zoukankan      html  css  js  c++  java
  • [校招] 压缩算法

    压缩算法 - 腾讯2020校招

    小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
    

    思路:

    由内向外替换,right 代表从左侧第一个开始的 ']' 的位置, left 代表与当前 ']' 对应的 '[' 位置。

    k 记录 '|' 位置。替换结束后 left 回到 right 的位置开始新一轮替换。

    优化:

    经评论区dalao提醒,可以在遍历时将 ' [ ' 和 ' |' 的位置分别入栈

    当读到 ' ] ' 时弹出,替换完毕后根据 left 的位置和串s2的长计算新的 right 的位置。省去了不必要的遍历。感谢dalao。

    代码(优化后):

    #include <iostream>
    #include <string>
    #include <stack>
    using namespace std;
    
    int main() {
    	string str;
    	cin >> str;
    	stack<int> s;
    	for (int right = 0; right < str.length(); right++){
    		//遇到 '[' 或 '|' 时入栈
    		if (str[right] == '[' || str[right] == '|')
    			s.push(right);
    		if (str[right] == ']'){
    			//出栈
    			int k    = s.top(); s.pop();
    			int left = s.top(); s.pop();
    			int num = stoi(str.substr(left + 1, k- left));
    			string s1 = str.substr(k + 1, right - k - 1);
    			string s2;
    			for (int i = 0; i < num; i++)
    				s2 += s1;
    			str = str.replace(left, right - left + 1, s2);
    			//计算新的right的位置
    			right = left+s2.size()-1;
    		}
    	}
    	cout << str;
    }
    

    代码(优化前):

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
    	string str;
    	cin >> str;
    	for (int right = 0; right < str.length(); right++) 
    	{
    		if (str[right] == ']') 
    		{
    			int k = 0;
    			int left = right;
    			for (; str[left] != '['; left--) 
    				if (str[left] == '|')
    					k = left;
    			int num = stoi(str.substr(left + 1, k - left));
    			string s1 = str.substr(k + 1, right - k - 1);
    			string s2;
    			for (int i = 0; i < num; i++)
    				s2 += s1;
    			str = str.replace(left, right - left + 1, s2);
    			right = left;
    		}
    	}
    	cout << str;
    }
    
  • 相关阅读:
    畅通工程续 (dijkstra)
    最短路径问题 HDU 3790
    【基础算法-模拟-例题-玩具谜题】-C++
    【基础算法-模拟-例题-金币】-C++
    【动态规划例题-数塔问题】-C++
    【基本数据结构之'图'】
    【最小生成树之Kruskal例题-建设电力系统】-C++
    【最短路算法例题-升降梯上】-C++
    【基本数据结构之栈】
    【栈-例题】网页跳转-C++
  • 原文地址:https://www.cnblogs.com/eisuto/p/12464469.html
Copyright © 2011-2022 走看看