这篇文章中用到的栈和队列均使用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;
}