算法与数据结构第三次作业——栈
3.1 括号
★实验任务
给你一个长度为 N 的由'('和')'组成的括号序列,你能找出这个序列中最长合法括号子序列么?合法括号序列是指,在这个序列中,所有的左括号都有唯一的右括号匹配;所有的右括号都有唯一的左括号匹配。例如:((()))()()便是一个长度为 10 的合法括号序列,而(()))( 则不是。
★数据输入
输入只有一行,是一个长度为 N(1<=N<=10^6)的由'('和')'组成的括号序列。
★数据输出
输出两行。第 1 行表示最长合法括号序列的长度。第 2 行表示最长合法括号序列的个数。
如果没有合法括号序列输出 0和 1。
输入示例1
)((())))(()())
输出示例1
6
2
输入示例2
))(
输出示例2
0
1
第一次由于审题不清,耽误了好多时间,最后采取了一版比较麻烦的代码
#include<iostream>
#include<stack>
using namespace std;
class Solution {
public:
int num;
public:
int longestValidParentheses(string s) {
int maxans = 0;
int n = s.length();
num = 0;
int* cnt = new int[n];
for (int i = 0; i < n; i++)
{
cnt[i] = 0;
}
stack<int> stk;
for (int i = 0; i < n; i++) {
if (s[i] == '(') {
stk.push(i);
}
else {
if (!stk.empty()) {
int j = stk.top();
stk.pop();
cnt[i] = 1;
cnt[j] = 1;
}
}
}
bool flag = false;
int temp = 0;
for (int i = 0; i < n; i++)
{
if (cnt[i] == 0)
{
// flag = false;
temp = 0;
}
else if (cnt[i] == 1)
{
temp++;
}
if (temp > maxans) {
maxans = temp;
num = 1;
}
else if (temp == maxans) {
num++;
}
}
return maxans;
}
};
int main()
{
Solution Sol;
string s;
cin >> s;
int maxl = Sol.longestValidParentheses(s);
if (maxl == 0)
{
cout << 0 << endl << 1;
}
else
{
cout << maxl << endl << Sol.num;
}
}
这一种方法参考了力扣的解答。参考地址
#include<iostream>
#include<stack>
using namespace std;
class Solution {
public:
int num;
public:
int longestValidParentheses(string s) {
int maxans = 0;
num = 0;
stack<int> stk;
stk.push(-1);
for (int i = 0; i < s.length(); i++) {
if (s[i] == '(') {
stk.push(i);
}
else {
stk.pop();
if (stk.empty()) {
stk.push(i);
}
else {
if(i-stk.top()>maxans)
{
maxans=i-stk.top();
num=1;
}else if(maxans==i-stk.top()){
num++;
}
// maxans = max(maxans, i - stk.top());
}
}
}
return maxans;
}
};
int main()
{
Solution Sol;
string s;
cin >> s;
int maxl = Sol.longestValidParentheses(s);
if (maxl == 0)
{
cout << 0 << endl << 1;
}
else
{
cout << maxl << endl << Sol.num;
}
}
3.9 文档
★实验任务
TonyY 是一个word 小白,今天他对 word 中撤销和恢复功能特别感兴趣,玩耍了一个上午(mdzz~),现在他知道了它们的功能和快捷键:
撤销:ctrl+z,可以撤销最近 1 次之前的恢复和 input 操作。
恢复:ctrl+y,可以恢复最近1 次之前的撤销操作,但是 input 操作之前的撤销操作不能被恢复。
当然,TonyY 还要往里写东西,操作格式为 input str(str中不含空格,str长度为m,1=<m<=30)。
现在他对 word 玩耍了起来,想知道玩耍完的结果,你可以帮助他吗?
★数据输入
输入第一行为一个正整数 n(0<=n<=10000),表示 TonyY 的操作次数。
接下来 n 行,为上述的操作之一。
其中可能有不合法操作,直接跳过即可。
★数据输出
输出 word 中的内容,字符串间用空格隔开,如果 word 为空,输出”No output”
输入示例1
4
input a
ctrl+z
ctrl+y
input b
输出示例1
a b
输入示例2
5
input a
input b
ctrl+z
input d
ctrl+y
输出示例2
a d
这道题目需要注意的是可能存在连续撤销的操作,需要保存的字符串不止一个,不能简单的用一个变量保存撤销的元素。
#include<iostream>
#include<string>
#include<stack>
using namespace std;
int main()
{
string s;
stack <string> str,temp;
int i;
string recover, dreraw;
cin >> i;
for (int j = 0; j < i; j++)
{
cin >> s;
if (s == "input")
{
cin >> s;
str.push(s);
while (!temp.empty())
{
temp.pop();
}
}
else if (s == "ctrl+z")
{
if (!str.empty())
{
temp.push(str.top());
str.pop();
}
}
else if (s == "ctrl+y")
{
if (!temp.empty())
{
str.push(temp.top());
temp.pop();
}
}
}
if (str.empty())
{
cout << "No output";
}
else
{
stack<string> disp;
while (!str.empty())
{
disp.push(str.top());
str.pop();
}
while (!disp.empty())
{
cout << disp.top() << ' ';
disp.pop();
}
}
}