概述
问题 A: 出栈合法性
题目描述
已知自然数1,2,…,N(1<=N<=100)依次入栈,请问序列C1,C2,…,CN是否为合法的出栈序列。
输入
输入包含多组测试数据。
每组测试数据的第一行为整数N(1<=N<=100),当N=0时,输入结束。
第二行为N个正整数,以空格隔开,为出栈序列。
输出
对于每组输入,输出结果为一行字符串。
如给出的序列是合法的出栈序列,则输出Yes,否则输出No。
样例输入
5
3 4 2 1 5
5
3 5 1 4 2
0
样例输出
Yes
No
思路
入栈顺序是从小到大,所以设一个计数,监测入栈到第几个了,例如出栈顺序第一个是3,则ptr=3;
再看下一个出栈顺序,先和ptr比较,大于ptr,将ptr之后直到出栈顺序之前的数据压入栈,ptr=新出栈值
若小于ptr,和栈顶元素比较,若相等则弹出栈顶元素,ptr值不改变,若小于栈顶元素则错误输出no
代码
#include<iostream>
#include<stdlib.h>
#include<assert.h>
using namespace std;
struct LinkNode{
int data;
LinkNode* next;
LinkNode(LinkNode*p=NULL){next=p;}
LinkNode(int x,LinkNode*p=NULL){data=x;next=p;}
};
class LinkedStack{
public:
LinkedStack():top(NULL){}
~LinkedStack() { makeEmpty(); }
void Push(const int &x);
bool Pop(int &x);
bool getTop(int &x)const; //返回最上面的值
bool IsEmpty() const { return (top == NULL) ? true : false; }
int getSize() const;
void makeEmpty();
//friend ostream &operator<<(ostream &os, LinkedStack &s);
private:
LinkNode *top;
};
void LinkedStack::makeEmpty(){
LinkNode *p;
while(top!=NULL){
p = top;
top = top->next;
delete p;
}
}
void LinkedStack::Push(const int & x){
top = new LinkNode(x,top);
assert(top != NULL);
}
bool LinkedStack::Pop(int& x){
if(IsEmpty()==true)
return false;
LinkNode *p = top;
x = top->data;
top = top->next;
delete p;
return true;
}
bool LinkedStack::getTop(int& x)const{
if(IsEmpty()==true)
return false;
x = top->data;
return true;
}
int LinkedStack::getSize()const{
int count = 0;
LinkNode *p = top;
while(p!=NULL){
p = p->next;
count++;
}
return count;
}
int main(){
LinkedStack s1;
/*int n=0;
cin>>n;
s1.Push(n);
int m=0;
s1.Pop(m);
cout<<m;*/
int n=0;
cin>>n;
int ptr=1;
int c1=0;
int top=0;s1.Pop(top);
while(n!=0){
//cout<<"in"<<endl;
while(n!=0){
cin>>c1;
if((c1>top)||(c1>ptr)){
//cout<<n<<"f1"<<endl;
for(int i=ptr;i<c1;i++){
s1.Push(i);
}
ptr=c1+1;
s1.getTop(top);
//cout<<top<<endl;
n--;
}else if(c1==top){
//cout<<n<<"f2"<<endl;
s1.Pop(c1);s1.getTop(top);n--;
}else if(c1<top){
//cout<<n<<"f3"<<endl;n--;
break;
}
}
s1.makeEmpty();
if(n==0){
cout<<"Yes"<<endl;
}
else {
//cout<<n<<endl;
for(int j=1;j<n;j++){
cin>>c1;
}
cout<<"No"<<endl;}
cin>>n;
ptr=0;
top=0;s1.Pop(top);
}
return 0;
}/*cin>>c1;
ptr=c1;
for(;ptr<c1;ptr++){
s1.Push(ptr);
}
s1.getTop(top);
cin>>c1;
if((c1>top)&&(c1>ptr)){
for(;ptr<c1;ptr++){
s1.Push(ptr);
}s1.getTop(top);
}else if(c1==top){
s1.Pop(c1);s1.getTop(top);
}else if(c1<top){
cout<<"No"<<endl;
cin>>n;
break;
}*/
问题 B: 算法3-1:八进制数
题目描述
将十进制数转换为八进制,并输出。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8DTo8AGd-1624035589325)(http://192.168.173.163/JudgeOnline/upload/pimg1324_1.jpg)]
图:将十进制数转换为八进制并输出
输入
输入包含若干十进制正整数。
输出
输出相应的八进制数,每个占一行。
样例输入
1
2
3
7
8
9
19
10020345
样例输出
1
2
3
7
10
11
23
46162771
提示
书上有相应的算法,需要补充缺失的函数。
总结:
1、数值转换使用到堆栈,但是用函数调用(系统的堆栈)将会更为方便。
2、书中的算法实际上只能处理正整数,你有更好的方法还能够处理0和负整数么?
思路
传统思路,除数倒取余,用数组存余数,直至商为零
代码
#include<iostream>
using namespace std;
void fun10_8(int& x);
int main(){
int n=0;
while(scanf("%d",&n)!=EOF){
fun10_8(n);
cout<<n<<endl;}
return 0;
}
void fun10_8(int& x){
int i=x,j=0;
int array[100];
while(i){
array[j]=i%8;
j++;
i=i/8;
}
j--;
x=array[j];
j--;
for(;j>=0;j--){
x=array[j]+x*10;
}
}
问题 C: 算法3-2:行编辑程序
题目描述
一个简单的行编辑程序的功能是:接收用户从终端输入的程序或数据,并存入用户的数据区。由于用户在终端上进行输入时,不能保证不出差错,因此,若在编辑程序中,“每接收一个字符即存入用户数据区”的做法显然不是很恰当。较好的做法是,设立一个输入缓冲区,用以接收用户输入的一行字符,然后逐行存入用户数据区。允许用户输入出差错,并在发现有误时可以及时更正。例如,当用户发现刚刚键入的一个字符是错的时,可补进一个退格符“#”,以表示前一个字符无效;如果发现当前键入的行内错误较多或难以补救,则可以键入一个退行符“@”,以表示当前行中的字符均无效。例如假设从终端接收了这样的两行字符:
whil##ilr#e(s#*s)
outcha@ putchar(*s=#++);
则实际有效的是下列两行:
while(*s)
putchar(*s++);
为此,可设这个输入缓冲区为一个栈结构,每当从终端接收了一个字符之后先作如下判别:如果它不是退格符也不是退行符,则将该字符压入栈顶;如果是一个退格符,则从栈顶删去一个字符;如果它是一个退行符,则将字符栈清为空栈。上述处理过程可用下面算法描述之:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qRMwJucq-1624035589327)(http://192.168.173.163/JudgeOnline/upload/pimg1325_1.jpg)]
图:行编辑程序算法
输入
若干行程序或者数据,每行不超过200个字符。
输出
经过行编辑程序处理过后的输出。
样例输入
whil##ilr#e(s#*s)
outcha@ putchar(*s=#++);
样例输出
while(*s)
putchar(*s++);
思路
题目讲的很清楚,照着做就行
但是比较坑的是在oj上如果第一位输入的是‘#’则下一位输入的也要删除
因此提供两种代码
代码1,只删除’#'之前的字符
#include<iostream>
#include<stdlib.h>
#include<assert.h>
using namespace std;
struct LinkNode{
char data;
LinkNode* next;
LinkNode(LinkNode*p=NULL){next=p;}
LinkNode(char x,LinkNode*p=NULL){data=x;next=p;}
};
class LinkedStack{
public:
LinkedStack():top(NULL){}
~LinkedStack() { makeEmpty(); }
void Push(const char &x);
bool Pop(char &x);
bool getTop(char &x)const; //返回最上面的值
bool IsEmpty() const { return (top == NULL) ? true : false; }
int getSize() const;
void makeEmpty();
//friend ostream &operator<<(ostream &os, LinkedStack &s);
private:
LinkNode *top;
};
void LinkedStack::makeEmpty(){
LinkNode *p;
while(top!=NULL){
p = top;
top = top->next;
delete p;
}
}
void LinkedStack::Push(const char & x){
top = new LinkNode(x,top);
assert(top != NULL);
}
bool LinkedStack::Pop(char& x){
if(IsEmpty()==true)
return false;
LinkNode *p = top;
x = top->data;
top = top->next;
delete p;
return true;
}
bool LinkedStack::getTop(char& x)const{
if(IsEmpty()==true)
return false;
x = top->data;
return true;
}
int LinkedStack::getSize()const{
int count = 0;
LinkNode *p = top;
while(p!=NULL){
p = p->next;
count++;
}
return count;
}
int main(){
char ch=NULL;
LinkedStack chs,cs;
ch=getchar();
while(ch!=EOF){
//cout<<1<<endl;
while(ch!=EOF&&ch!='n'){
//cout<<2<<endl;
switch(ch){
case '#':chs.Pop(ch);
ch=getchar();
break;
case '@':
chs.makeEmpty();
ch=getchar();
break;
default:chs.Push(ch);
ch=getchar();break;
}
}
if(chs.IsEmpty()==true){//cout<<6<<endl;
ch=getchar();
}
else{//cout<<7<<endl;
while(!chs.IsEmpty()){//cout<<8<<endl;
chs.Pop(ch);
cs.Push(ch);
}
while(!cs.IsEmpty()){
cs.Pop(ch);
cout<<ch;
}
chs.makeEmpty();
cs.makeEmpty();
cout<<endl;
ch=getchar();
}
}
return 0;
}
代码2,首位输入‘#’删除下一位字符
#include<iostream>
using namespace std;
int main(){
char s[500];
char x;
int top=-1;
while(scanf("%c",&x)!=EOF){
while(x!=EOF&&x!='n'){
switch(x){
case '#':top--;break;
case '@':top=-1;break;
default:
s[++top]=x;
break;
}
x=getchar();
}
if(top>=0){
for(int i=0;i<=top;i++){
putchar(s[i]);
}
cout<<endl;
}
top=-1;
puts("");
}
}
答案代码
#include<stdio.h>
int main()
{
char s[450],s1[450];
int i,j;
while(gets(s))
{
j=0;
for(i=0;s[i]!='