SXU-数据结构与算法实验二(栈和队列)

 这篇文章中用到的栈和队列均使用c++的STL容器实现

1、判断字符串是否为回文

编写一个程序,判断一个字符串是否为“回文”(顺读和倒读都一样的字符串称为“回文”)。

【输入形式】长度小于100的任意字符串

【输出形式】如果输入字符串是回文,则输出“yes”;如果字符串不是回文,则输出“no”

#include<iostream>
#include<stack>
#include<string>
using namespace std;

bool isPalindrome(string & str){
	stack<char>stk;
	int length = str.length();
	for (int i = 0; i < length; i++){
		stk.push(str[i]);
	}
	for (int i = 0; i < length; i++){
		if (str[i] != stk.top()){
			return false;
		}
		stk.pop();	
	}
	return true;
}
int main(){
	string str;
	cin >> str;
	bool flag=isPalindrome(str);
	if (flag)
		cout << "yes" << endl;
	else
		cout << "no" << endl;
	return 0;
}

2、括号匹配问题

假设一算术表达式中包括三种括号:圆括号'('和')'; 方括号'[' 和']'; 花括号'{' 和'}',且三种括号可按任意次序嵌套使用,试编写程序判定输入的表达式所含的括号是否正确配对出现(已知表达式已存入数据元素为字符的顺序表中)。所有括号均为半角符号。若匹配,则返回1,否则返回0.

#include<iostream>
#include<string>
#include<stack>
using namespace std;

void Match(string s) {
	string str = "{[()]}";
	stack<char>stk;
	for (int i = 0; i < s.length(); i++) {
		int index = str.find(s[i]);//获取字符在字符串数组str中的下标
		if (index>=0&&index<=2) {//所有左括号入栈
			stk.push(s[i]);
		}
		else if (index >= 3 && index <= 5) {//若字符是右括号
			if (!stk.empty()&&str.find(stk.top()) + index == 5)//检验当前符号是否与栈顶符号匹配
				stk.pop();//若匹配,栈顶元素出栈
            else if (stk.empty()){//若栈为空,出现右括号,一定不匹配,循环直接结束
				stk.push(s[i]);
				break;
			}
		}

	}
	if (stk.empty()) {//若栈为空,则成功匹配
		cout << 1 << endl;
	}
	else {//否则匹配失败
		cout << 0 << endl;
	}
}
int main() {
	string str;
	cin >> str;
	Match(str);
	return 0;
}

3、十进制转八进制

【问题描述】对于输入的任意一个非负十进制整数,打印输出与其等值的八进制数

【输入形式】非负十进制整数

【输出形式】相应十进制整数转换后的八进制正整数,若输入不符合要求,提示错误,重新输入

#include<iostream>
#include<stack>
using namespace std;
void Conversion(int num){
	if (num == 0){
		cout << num;
	}
	stack<int>stk;
	int m = num;//商
	int n = 0;//余数
	while (m != 0){
		m = num / 8;
		n = num % 8;
		stk.push(n);
		num = m;
	}
	int length = stk.size();
	for (int i = 0; i < length; i++){
		cout << stk.top();
		stk.pop();
	}
	cout << endl;
}

int main(){
	int num;
	cin >> num;
	Conversion(num);
	system("pause");
	return 0;
}

4、中缀表达式转后缀表达式

【问题描述】 输入一个中缀表达式,表达式中有+、-、*、/四种运算以及(、),表达式中的其他符号为大写的字母, 所有符号均为半角。实现一个算法,得到相应的后缀表达式。

【输入形式】 一个式子的中缀表达式,以#结束

【输出形式】 相应的后缀表达式

#include<iostream>
#include<stack>
#include<string>
using namespace std;
void Consversion(string s) {
	stack<char>stk;
	string signal = "+-*/()";
	int flag = 0;
	int weight[6] = { 1,1,2,2,0,3 };//定义每个符号的权值,用权值大小表示优先级大小
	for (int i = 0; i < s.length()-1; i++) {
		int index = signal.find(s[i]);//为了方便找到当前符号的权值,得到当前符号下标
		if (index >= 0 && index <= 5) flag = 1;
		//单独处理左括号,直接将其入栈
		if (s[i] == '(') {
			stk.push(s[i]);
			continue;
		}
		//特殊处理右括号,出栈,直到“(”出栈
		else if (s[i] == ')') {
			while (stk.top() != '(') {
				cout << stk.top();
				stk.pop();
			}
			stk.pop();
			continue;
		}
		//栈为空,直接将符号入栈
		else if (stk.empty() && flag) {
			stk.push(s[i]);
			continue;
		}
		else if (!stk.empty()&&flag){
			//当前符号优先级小于栈顶符号优先级,出栈直到优先级相等
			int top = signal.find(stk.top());
			while (!stk.empty() && weight[index] <= weight[top]) {
				cout << stk.top();
				stk.pop();
			}
		    stk.push(s[i]);
			continue;
		}
		else 
			cout << s[i];//不是符号,直接输出
	}
	//弹出栈中剩余符号
	while (!stk.empty()) {
		cout << stk.top();
		stk.pop();
	}
}
int main() {
	string s;
	cin >> s;
	Consversion(s);
	return 0;
}

5、数对之差最大

【问题描述】在数组中,数字减去它右边的数字得到一个数对之差。求所有数对之差的最大值。例如 在数组{2, 4, 1, 16, 7, 5, 11, 9}中,数对之差的最大值是11,是16减去5的结果。

【输入形式】第一个整数是数组元素个数N>1, 接下来是整数数组,空格隔开

【输出形式】数对之差的最大值,一个数字

方法一:(笨办法)双层循环遍历数组,时间复杂度为n^2

#include<iostream>
using namespace std;
void Max(){
	int max = 0;
	int n;
	cin >> n;
	int *array=new int[n];
	//输入
	for (int i = 0; i < n; i++){
		int num = 0;
		cin >> num;
		array[i] = num;
	}
	//找数对之差最大值
	for (int i = 0; i < n-1; i++){
		for (int j = i + 1; j < n; j++){
			if ((array[i] > array[j]) && (array[i] - array[j]>max))
				max = array[i] - array[j];//更新当前最大数对之差
			else continue;
		}
	}
	//输出
	cout << max << endl;
}

int main(){
	Max();
	system("pause");
	return 0;
}

方法二:动态规划,只需遍历一遍数组,时间复杂度为n

#include<iostream>
#include<algorithm>
using namespace std;

void findMax() {
	int n;
	cin >> n;
	int* a = new int[n];
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	int maxdiff = a[0] - a[1];
	int maxnum = max(a[0],a[1]);
	for (int i = 2; i < n; i++) {
		maxnum = max(maxnum, a[i]);//更新当前最大数
		maxdiff = max(maxdiff, maxnum - a[i]);//更新当前最大diff
	}
	cout << maxdiff << endl;
}
int main() {
	findMax();
	return 0;
}

6、连续整数之和

【问题描述】某些整数能分解成若干个连续整数的和的形式,例如:

15 = 1 + 2+3+4+5 

15 = 4 + 5 + 6

15 = 7 + 8

某些整数不能分解为连续整数的和,例如:16

【输入形式】一个整数N(N <= 10000)

【输出形式】整数N对应的所有分解组合,如果没有任何分解组合,则输出NONE

#include<iostream>
using namespace std;

int main() {
	int n;
	int flag = 0;
	cin >> n;
	int* a = new int[n+1];
	for (int i = 1; i <= n; i++) {
		a[i] = i;
	}
	for (int i = 1; i <= n/2; i++) {
		int begin = i;
		int end = 0;
		int sum = 0;
		for (int j = i; j <= n / 2 + 1; j++) {
			sum = sum + a[j];
			if (sum == n) {
				flag = 1;
				end = j;
				for (int k = begin; k <= end; k++) {
					cout << k << " ";
				}
				cout << endl;
			}
		}
	}
	if (flag == 0) cout << "NONE" << endl;
	return 0;
}

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值