鱼C论坛

 找回密码
 立即注册
查看: 297|回复: 7

[已解决]栈相关

[复制链接]
发表于 2023-10-18 22:46:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
4. 判断堆栈操作的合法性

(1)输入说明:第一行给出两个正整数N和M,其中N是待测序列的个数,M(<=50)是栈的最大容量。随后N行,每行中给出一个仅由S和X构成的序列。序列保证不为空,且长度不超过100.

(2)输出说明:对每个序列,若该序列是合法的堆栈操作序列,在一行中输出YES,否则输出NO。

(3)测试用例:


输入                             输出

4,10

SSSXXSXXSX                YES

SSSXXSXXS                  NO

SSSSSSSSSSXSSXXXXXXXXXXX            NO

SSSXXSXXX                   NO


说明:NO的情形包括堆栈非空、X空栈、S满栈,非法操作发生在序列中间及结尾
下面是我写的代码。
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define stack_init_size 100
  4. #define stackincrement 10
  5. typedef int selemtype;
  6. typedef int elemtype;
  7. typedef struct{
  8.         selemtype *base;
  9.         selemtype *top;
  10.         int stacksize;
  11. }sqstack;
  12. typedef struct snode{
  13.         elemtype data;
  14.         struct snode *next;
  15. }snode,*linkstack;
  16. void initlist1(linkstack &l)//链栈入栈
  17. {
  18.         elemtype e;
  19.         int n,i;
  20.         l=(linkstack)malloc(sizeof(snode));
  21.         l->next=NULL;
  22.         printf("\n请输入创建栈的长度:");
  23.         scanf("%d",&n);
  24.         for(i=0;i<n;i++){
  25.                 scanf("%d",&e);
  26.             linkstack p=(snode*)malloc(sizeof(snode));
  27.             p->data=e;
  28.             p->next=l->next;
  29.             l->next=p;
  30.         }
  31. }
  32. void input(linkstack &l)//链栈输出
  33. {
  34.         linkstack p=l->next;
  35.         while(p!=NULL)
  36.         {
  37.                 printf("%d ",p->data);
  38.                 p=p->next;
  39.         }
  40.         printf("\n");
  41. }
  42. void pop1(linkstack &l)//链栈出栈
  43. {
  44.         int n,i;
  45.         elemtype x;
  46.         linkstack p;
  47.         printf("\n请输入要出栈的个数:");
  48.         scanf("%d",&n);
  49.         printf("出栈的数为:");
  50.         for(i=0;i<n;i++)
  51.         {
  52.                 p=l->next;
  53.                 l->next=p->next;
  54.                 x=p->data;
  55.                 free(p);
  56.                 printf("%d ",x);
  57.         }
  58. }
  59. void initstack(sqstack &s)
  60. {
  61.         s.base=(selemtype*)malloc(stack_init_size*sizeof(selemtype));
  62.         s.top=s.base;
  63.         s.stacksize=stack_init_size;
  64. }
  65. void push(sqstack &s,selemtype e)//入栈
  66. {
  67.         if(s.top-s.base>=s.stacksize){
  68.                 s.base=(selemtype*)realloc(s.base,(s.stacksize+stack_init_size)*sizeof(selemtype));
  69.                 if(!s.base)  
  70.                        printf("error");
  71.                            s.top=s.base+s.stacksize;
  72.                            s.stacksize+=stack_init_size;
  73.         }
  74.         *s.top=e;
  75.         s.top++;
  76. }
  77. void pop(sqstack &s)//出栈
  78. {
  79.         selemtype *e=s.top-1;
  80.         int i=0;
  81.         if(s.base==s.top){
  82.                 printf("栈为空");
  83.         }
  84.         printf("%d ",*e);
  85.         s.top--;
  86. }
  87. void gettop(sqstack &s)//取栈顶元素
  88. {
  89.         if(s.top!=s.base){
  90.                    printf("\n此时栈顶元素为:");
  91.         printf("%d\n",*(s.top-1));
  92.         }
  93.        
  94. }
  95. void print(sqstack &s)//输出
  96. {
  97.         selemtype *e=s.base;
  98.         int i=0;
  99.         while(i<(s.top-s.base))
  100.         {
  101.                 printf("%d ",*e);
  102.                 i++;
  103.                 e++;
  104.         }
  105. }
  106. void judge(selemtype q)
  107. {
  108.         int i,flag=0,a[100];
  109.         sqstack s2;
  110.         selemtype e,f;
  111.         initstack(s2);
  112.         for(i=0;i<q;i++){
  113.             scanf("%d",&f);
  114.             a[i]=f;
  115.     }
  116.         for(i=0;i<q/2;i++){
  117.                 push(s2,a[i]);
  118.         }
  119.         if (q % 2 == 0) {
  120.         i = q / 2;
  121.     } else {
  122.         i = q / 2 + 1;
  123.     }
  124.         while(i<q&&flag==0)
  125.         {
  126.                 if(*(s2.top-1)!=a[i]){
  127.                         flag=1;
  128.                 }
  129.                 s2.top--;
  130.                 i++;
  131.         }
  132.         if(flag==0){
  133.                 printf("是回文序列!");
  134.         }
  135.         else {
  136.                 printf("不是回文序列");
  137.         }
  138. }
  139. void hefa(int N,int M)
  140. {
  141.         int i,j=0;
  142.         selemtype e=0;
  143.         sqstack s1;
  144.         char y,S,X;
  145.         for(i=0;i<N;i++){
  146.                 while(j<M)
  147.                 {
  148.                         scanf("%c",&y);
  149.                         if(y=='S'){
  150.                                 e=1;
  151.                                 push(s1,e);
  152.                         }
  153.                         else if(y=='X'){
  154.                                 if(s1.top==s1.base){
  155.                                         e=0;
  156.                                 }
  157.                                 s1.top--;
  158.                         }
  159.                         j++;
  160.                 }
  161.                 if(e==1){
  162.                         printf("YES");
  163.                 }
  164.                 else
  165.                 {
  166.                         printf("NO");
  167.                 }
  168.                
  169.         }
  170. }
  171. int main()
  172. {
  173.         int n,i,m,a[100],M,N;
  174.         sqstack s,s1;
  175.         linkstack l;
  176.         selemtype e,q,f;
  177.         initstack(s);
  178.         printf("请输入进栈的数量:\n");
  179.         scanf("%d",&n);
  180.         printf("请输入进栈的数字:\n");
  181.         for(i=0;i<n;i++)
  182.         {
  183.                 scanf("%d",&e);
  184.         push(s,e);
  185.         }
  186.         printf("请问你想出栈几次:\n");
  187.         scanf("%d",&m);
  188.         if(m>n){
  189.                 printf("error");
  190.         }
  191.         else
  192.         {
  193.                 for(i=0;i<m;i++){
  194.                 pop(s);
  195.         }
  196.         }
  197.     gettop(s);
  198.     if(s.top==s.base){
  199.             printf("栈为空。\n");
  200.     }
  201.     else{
  202.             printf("栈内元素为:");
  203.             print(s);
  204.     }
  205.     printf("\n请输入你想要判断是否为回文的字符序列的长度:");
  206.     scanf("%d",&q);
  207.     judge(q);
  208.     initlist1(l);
  209.     pop1(l);
  210.     printf("\n栈内元素为:");
  211.     input(l);
  212.     scanf("%d,%d",&N,&M);
  213.     hefa(N,M);
  214.     return 0;
  215. }
复制代码
最佳答案
2023-10-18 22:47:44
你的代码看起来已经很复杂了,但是我注意到你的代码并没有完全解决问题。你的代码中的\"hefa\"函数是用来判断堆栈操作的合法性的,但是它并没有正确地处理所有的情况。这个函数需要考虑的情况有:

1. 当输入为'S'时,需要将元素压入栈中。如果栈已满(即栈的大小等于M),则该操作是非法的。

2. 当输入为'X'时,需要从栈中弹出元素。如果栈为空(即没有元素可以弹出),则该操作是非法的。

你的代码没有正确地处理这些情况。你需要修改你的代码,以便正确地处理这些情况。以下是一个简化的版本的代码,它只包含了处理这个问题的部分:

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. void hefa(int N, int M) {
  4.     int i, j;
  5.     char *seq = (char*)malloc(101 * sizeof(char)); // 序列长度不超过100
  6.     for(i = 0; i < N; i++) {
  7.         scanf("%s", seq);
  8.         int stackSize = 0;
  9.         for(j = 0; seq[j] != '\\0'; j++) {
  10.             if(seq[j] == 'S') {
  11.                 if(stackSize == M) {
  12.                     printf("NO\
  13. ");
  14.                     break;
  15.                 }
  16.                 stackSize++;
  17.             } else if(seq[j] == 'X') {
  18.                 if(stackSize == 0) {
  19.                     printf("NO\
  20. ");
  21.                     break;
  22.                 }
  23.                 stackSize--;
  24.             }
  25.         }
  26.         if(seq[j] == '\\0') {
  27.             printf("YES\
  28. ");
  29.         }
  30.     }
  31.     free(seq);
  32. }

  33. int main() {
  34.     int N, M;
  35.     scanf("%d %d", &N, &M);
  36.     hefa(N, M);
  37.     return 0;
  38. }
复制代码


这个代码首先读取N和M的值,然后对每一个序列进行检查。对于每一个序列,它首先读取序列,然后对序列中的每一个字符进行检查。如果字符是'S',它会检查栈是否已满。如果字符是'X',它会检查栈是否为空。如果在任何时候发现一个非法的操作,它会立即停止检查该序列,并输出\"NO\"。如果它成功地检查了整个序列而没有发现任何非法的操作,它会输出\"YES\"。
请注意,本回答来自GPT-4
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-10-18 22:47:44 | 显示全部楼层    本楼为最佳答案   
你的代码看起来已经很复杂了,但是我注意到你的代码并没有完全解决问题。你的代码中的\"hefa\"函数是用来判断堆栈操作的合法性的,但是它并没有正确地处理所有的情况。这个函数需要考虑的情况有:

1. 当输入为'S'时,需要将元素压入栈中。如果栈已满(即栈的大小等于M),则该操作是非法的。

2. 当输入为'X'时,需要从栈中弹出元素。如果栈为空(即没有元素可以弹出),则该操作是非法的。

你的代码没有正确地处理这些情况。你需要修改你的代码,以便正确地处理这些情况。以下是一个简化的版本的代码,它只包含了处理这个问题的部分:

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. void hefa(int N, int M) {
  4.     int i, j;
  5.     char *seq = (char*)malloc(101 * sizeof(char)); // 序列长度不超过100
  6.     for(i = 0; i < N; i++) {
  7.         scanf("%s", seq);
  8.         int stackSize = 0;
  9.         for(j = 0; seq[j] != '\\0'; j++) {
  10.             if(seq[j] == 'S') {
  11.                 if(stackSize == M) {
  12.                     printf("NO\
  13. ");
  14.                     break;
  15.                 }
  16.                 stackSize++;
  17.             } else if(seq[j] == 'X') {
  18.                 if(stackSize == 0) {
  19.                     printf("NO\
  20. ");
  21.                     break;
  22.                 }
  23.                 stackSize--;
  24.             }
  25.         }
  26.         if(seq[j] == '\\0') {
  27.             printf("YES\
  28. ");
  29.         }
  30.     }
  31.     free(seq);
  32. }

  33. int main() {
  34.     int N, M;
  35.     scanf("%d %d", &N, &M);
  36.     hefa(N, M);
  37.     return 0;
  38. }
复制代码


这个代码首先读取N和M的值,然后对每一个序列进行检查。对于每一个序列,它首先读取序列,然后对序列中的每一个字符进行检查。如果字符是'S',它会检查栈是否已满。如果字符是'X',它会检查栈是否为空。如果在任何时候发现一个非法的操作,它会立即停止检查该序列,并输出\"NO\"。如果它成功地检查了整个序列而没有发现任何非法的操作,它会输出\"YES\"。
请注意,本回答来自GPT-4
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-18 22:47:54 | 显示全部楼层
你的代码有一些问题。首先,你定义了一个链栈  linkstack ,但是你没有使用它来判断堆栈操作的合法性。其次,你在判断回文序列的函数中,使用了一个堆栈  s2 ,但是你没有正确地实现入栈和出栈的操作。最后,在判断堆栈操作的合法性的函数中,你没有正确地处理每个序列的输入和判断。

下面是我对你的代码进行修改后的版本:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define MAX_SIZE 100

  4. typedef struct {
  5.     int top;
  6.     int capacity;
  7.     char *stack;
  8. } Stack;

  9. Stack* createStack(int capacity) {
  10.     Stack* stack = (Stack*)malloc(sizeof(Stack));
  11.     stack->top = -1;
  12.     stack->capacity = capacity;
  13.     stack->stack = (char*)malloc(capacity * sizeof(char));
  14.     return stack;
  15. }

  16. void push(Stack* stack, char ch) {
  17.     stack->stack[++stack->top] = ch;
  18. }

  19. char pop(Stack* stack) {
  20.     return stack->stack[stack->top--];
  21. }

  22. char peek(Stack* stack) {
  23.     return stack->stack[stack->top];
  24. }

  25. int isEmpty(Stack* stack) {
  26.     return stack->top == -1;
  27. }

  28. int isFull(Stack* stack) {
  29.     return stack->top == stack->capacity - 1;
  30. }

  31. void destroyStack(Stack* stack) {
  32.     free(stack->stack);
  33.     free(stack);
  34. }

  35. int isSequenceValid(char* sequence, int capacity) {
  36.     Stack* stack = createStack(capacity);
  37.    
  38.     int i = 0;
  39.     while (sequence[ i] != '\0') {
  40.         if (sequence[ i] == 'S') {
  41.             if (isFull(stack)) {
  42.                 destroyStack(stack);
  43.                 return 0;
  44.             }
  45.             push(stack, sequence[ i]);
  46.         } else if (sequence[ i] == 'X') {
  47.             if (isEmpty(stack)) {
  48.                 destroyStack(stack);
  49.                 return 0;
  50.             }
  51.             pop(stack);
  52.         }
  53.         i++;
  54.     }
  55.    
  56.     int isValid = isEmpty(stack);
  57.     destroyStack(stack);
  58.     return isValid;
  59. }

  60. int main() {
  61.     int N, M;
  62.     scanf("%d,%d", &N, &M);
  63.    
  64.     for (int i = 0; i < N; i++) {
  65.         char sequence[MAX_SIZE];
  66.         scanf("%s", sequence);
  67.         
  68.         int isValid = isSequenceValid(sequence, M);
  69.         if (isValid) {
  70.             printf("YES\n");
  71.         } else {
  72.             printf("NO\n");
  73.         }
  74.     }
  75.    
  76.     return 0;
  77. }
复制代码


这个修改后的代码使用了一个数组实现堆栈,并且修复了判断回文序列和判断堆栈操作合法性的函数。在主函数中,我们首先读取输入的序列个数和栈的最大容量。然后,我们循环读取每个序列,并调用  isSequenceValid  函数来判断序列是否合法。如果合法,输出 "YES",否则输出 "NO"。

希望这个修改后的代码能够帮助到你。如果你有任何问题,请随时向我提问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-18 22:48:13 | 显示全部楼层
栈相关 数据结构与算法

*判断堆栈操作的合法性*

输入说明:第一行给出两个正整数N和M,其中N是待测序列的个数,M(<=50)是栈的最大容量。随后N行,每行中给出一个仅由S和X构成的序列。序列保证不为空,且长度不超过100.

输出说明:对每个序列,若该序列是合法的堆栈操作序列,在一行中输出YES,否则输出NO。

测试用例:

[/code]
输入                输出
4,10
SSSXXSXXSX           YES
SSSXXSXXS            NO
SSSSSSSSSSXSSXXXXXXXXXXX            NO
SSSXXSXXX            NO
[/code]

以下是我的代码实现(Python 3):
  1. class Stack:
  2.     def __init__(self, max_size):
  3.         self.__max_size = max_size
  4.         self.__stack = []
  5.    
  6.     def is_empty(self):
  7.         return len(self.__stack) == 0
  8.    
  9.     def is_full(self):
  10.         return len(self.__stack) == self.__max_size
  11.    
  12.     def push(self, val):
  13.         if self.is_full():
  14.             return False
  15.         self.__stack.append(val)
  16.         return True
  17.    
  18.     def pop(self):
  19.         if self.is_empty():
  20.             return None
  21.         return self.__stack.pop()
  22.    
  23.     def top(self):
  24.         if self.is_empty():
  25.             return None
  26.         return self.__stack[-1]
  27.    
  28.     def size(self):
  29.         return len(self.__stack)
  30. def is_valid_seq(seq, max_size):
  31.     stack = Stack(max_size)
  32.     for i in range(len(seq)):
  33.         if seq[i] == "S":
  34.             if not stack.push(1):
  35.                 return False
  36.         elif seq[i] == "X":
  37.             if stack.is_empty():
  38.                 return False
  39.             stack.pop()
  40.     return stack.is_empty()
  41. if __name__ == "__main__":
  42.     N, M = map(int, input().split(","))
  43.     for i in range(N):
  44.         seq = input().strip()
  45.         if is_valid_seq(seq, M):
  46.             print("YES")
  47.         else:
  48.             print("NO")
复制代码

主要实现思路是,利用一个自定义的栈类 Stack 来模拟堆栈操作。遍历每个序列,遇到字符 "S" 则将一个元素压入栈中,遇到字符 "X" 则将一个元素弹出栈。如果此时栈为空,则表明序列不合法;如果栈已满,则表明序列不合法;如果遍历完整个序列后栈不为空,则表明序列不合法。最后判断栈是否为空,如果为空则表明序列合法,否则不合法。

希望能对您有所帮助!

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-10-18 23:10:25 | 显示全部楼层
陶远航 发表于 2023-10-18 22:47
你的代码看起来已经很复杂了,但是我注意到你的代码并没有完全解决问题。你的代码中的\"hefa\"函数是用来判 ...

你好,这个算法第一个答案不正确,第一个用例应该输出为YES
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-19 18:45:04 | 显示全部楼层
为啥用链栈,把代码搞得这么长,而且你完全不用去栈里面模拟,只要根据SX操作来判断就行了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-19 18:52:15 | 显示全部楼层
本帖最后由 yinda_peng 于 2023-10-19 18:54 编辑

只需要管栈的长度就行了,你这样反而简单题复杂化
思路:
while (length在合理范围):
    获取一个字符;
    根据字符判断对length++还是--还是'\n'退出循环;
if (length == 0)
{printf('Y')}

printf('N')
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-10-20 08:47:25 | 显示全部楼层
yinda_peng 发表于 2023-10-19 18:52
只需要管栈的长度就行了,你这样反而简单题复杂化
思路:
while (length在合理范围):

好像确实是,我再去试试,谢谢你
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 10:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表