• 数据结构——栈与队列


    目录

     1. 中缀表达式转换为后缀表达式

     2. 括号匹配问题

    3. 栈实现队列

    4. 约瑟夫环


     1. 中缀表达式转换为后缀表达式

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

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

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

    【样例输入】

     A*(B-C)/D+E#

    【样例输出】

     ABC-*D/E+

    【评分标准】
     请大家在程序中写出必要的注释,如果程序没有必要的注释,将酌情扣分

    1. #include
    2. #include
    3. #define MAX_SIZE 100
    4. typedef struct {
    5. char data[MAX_SIZE];
    6. int top;
    7. }Stack;
    8. void init(Stack *stack){
    9. stack->top=-1;
    10. }
    11. int isEmpty(Stack *stack){
    12. return stack->top==-1;
    13. }
    14. int isFull(Stack *stack){
    15. return stack->top==MAX_SIZE-1;
    16. }
    17. void push(Stack *stack,char c){
    18. if(isFull(stack)){
    19. printf("Stack overflow\n");
    20. return;
    21. }
    22. stack->data[++stack->top]=c;
    23. }
    24. char pop(Stack *stack){
    25. if(isEmpty(stack)){
    26. printf("Stack underflow\n");
    27. return '\0';
    28. }
    29. return stack->data[stack->top--];
    30. }
    31. int getPriority(char c){
    32. if(c=='+'||c=='-'){
    33. return 1;
    34. }
    35. else if(c=='*'||c=='/'){
    36. return 2;
    37. }
    38. else{
    39. return 0;
    40. }
    41. }
    42. void infixToPostfix(char *infix, char *postfix){
    43. Stack s;
    44. init(&s);
    45. int i=0, j=0;
    46. while(infix[i]!='#'){
    47. if(infix[i]>='A'&&infix[i]<='Z'){
    48. postfix[j++]=infix[i];
    49. }
    50. else if(infix[i]=='('){
    51. push(&s, infix[i]);
    52. }
    53. else if(infix[i]==')'){
    54. while(!isEmpty(&s) && s.data[s.top]!='('){
    55. postfix[j++]=pop(&s);
    56. }
    57. if(!isEmpty(&s) && s.data[s.top]=='('){
    58. pop(&s);
    59. }
    60. }
    61. else{
    62. while(!isEmpty(&s) && getPriority(infix[i])<=getPriority(s.data[s.top])){
    63. postfix[j++]=pop(&s);
    64. }
    65. push(&s, infix[i]);
    66. }
    67. i++;
    68. }
    69. while(!isEmpty(&s)){
    70. postfix[j++]=pop(&s);
    71. }
    72. postfix[j]='\0';
    73. }
    74. int main(){
    75. char infix[MAX_SIZE];
    76. scanf("%s", infix);
    77. char postfix[MAX_SIZE];
    78. infixToPostfix(infix, postfix);
    79. printf("%s\n", postfix);
    80. return 0;
    81. }

     2. 括号匹配问题

    【问题描述】

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

    含括号的算数表达式
    【输出形式】

    1或者0

    【样例输入】

    3+(44*[5-{6*[7*(45-10)]}])

    【样例输出】

    1

    【样例说明】

    判断括号是否匹配涉及两方面,括号个数和出现次序的判定。
    【评分标准】

    1. #include
    2. #include
    3. #define MAX_SIZE 100
    4. typedef struct {
    5. char data[MAX_SIZE];
    6. int top;
    7. } Stack;
    8. void init(Stack *stack) {
    9. stack->top = -1;
    10. }
    11. int isEmpty(Stack *stack) {
    12. return stack->top == -1;
    13. }
    14. int isFull(Stack *stack) {
    15. return stack->top == MAX_SIZE - 1;
    16. }
    17. void push(Stack *stack, char c) {
    18. if (isFull(stack)) {
    19. printf("Stack overflow\n");
    20. return;
    21. }
    22. stack->data[++stack->top] = c;
    23. }
    24. char pop(Stack *stack) {
    25. if (isEmpty(stack)) {
    26. printf("Stack underflow\n");
    27. return '\0';
    28. }
    29. return stack->data[stack->top--];
    30. }
    31. int isMatching(char left, char right) {
    32. if (left == '(' && right == ')') {
    33. return 1;
    34. } else if (left == '[' && right == ']') {
    35. return 1;
    36. } else if (left == '{' && right == '}') {
    37. return 1;
    38. } else {
    39. return 0;
    40. }
    41. }
    42. int isParenthesesMatching(char *expression) {
    43. Stack stack;
    44. init(&stack);
    45. int i;
    46. int length = strlen(expression);
    47. for ( i = 0; i < length; i++) {
    48. char c = expression[i];
    49. if (c == '(' || c == '[' || c == '{') {
    50. push(&stack, c);
    51. } else if (c == ')' || c == ']' || c == '}') {
    52. if (isEmpty(&stack)) {
    53. return 0;
    54. }
    55. char top = pop(&stack);
    56. if (!isMatching(top, c)) {
    57. return 0;
    58. }
    59. }
    60. }
    61. return isEmpty(&stack);
    62. }
    63. int main() {
    64. char expression[MAX_SIZE];
    65. fgets(expression, MAX_SIZE, stdin);
    66. int result = isParenthesesMatching(expression);
    67. printf("%d\n", result);
    68. return 0;
    69. }

    3. 栈实现队列

    【问题描述】

    请使用栈类实现队列的类。

    【输入形式】

    第一行一个整数n,

    接下来n行,每行一个整数,依次表示已经在队列中的数。

    接下来一行,一个整数m。

    接下来m行,有两种情况:1. 一个整数,请将其入列。2. 字符串"D",表示出列操作。

    【输出形式】

    若干行,每行一个出列的输出。

    【样例输入】

    3
    1
    2
    3
    2
    4
    D

    【样例输出】

    1

    【样例说明】

    队列中原来有1,2,3三个数,第一个操作使4入列,第二个操作出列,弹出队头的1
    【评分标准】

    通过所有数据

    1. #include
    2. #include
    3. #define MAX_SIZE 100
    4. typedef struct {
    5. int data[MAX_SIZE];
    6. int top;
    7. } Stack;
    8. void init(Stack *stack) {
    9. stack->top = -1;
    10. }
    11. int isEmpty(Stack *stack) {
    12. return stack->top == -1;
    13. }
    14. int isFull(Stack *stack) {
    15. return stack->top == MAX_SIZE - 1;
    16. }
    17. void push(Stack *stack, int num) {
    18. if (isFull(stack)) {
    19. printf("Stack overflow\n");
    20. return;
    21. }
    22. stack->data[++stack->top] = num;
    23. }
    24. int pop(Stack *stack) {
    25. if (isEmpty(stack)) {
    26. printf("Stack underflow\n");
    27. return 0;
    28. }
    29. return stack->data[stack->top--];
    30. }
    31. int main() {
    32. int n, m;
    33. scanf("%d", &n);
    34. Stack s1, s2;
    35. init(&s1);
    36. init(&s2);
    37. int i;
    38. for (i = 0; i < n; i++) {
    39. int num;
    40. scanf("%d", &num);
    41. push(&s1, num);
    42. }
    43. scanf("%d", &m);
    44. for (i = 0; i < m; i++) {
    45. char temp_str[2];
    46. scanf("%s", temp_str);
    47. if (strcmp(temp_str, "D") == 0) {
    48. if (isEmpty(&s2)) {
    49. while (!isEmpty(&s1)) {
    50. int num = pop(&s1);
    51. push(&s2, num);
    52. }
    53. }
    54. int result = pop(&s2);
    55. printf("%d\n", result);
    56. n--;
    57. } else {
    58. int num = atoi(temp_str);
    59. push(&s1, num);
    60. n++;
    61. }
    62. }
    63. return 0;
    64. }

    4. 约瑟夫环

    【问题描述】

    n个人围成一个圈,按顺时针方向一次编号1、2、3、……、n,从第一个人开始顺时针方向依次报数1、2、3、……,报数m的人被淘汰,然后下一个人再从1开始报数,一直重复该过程。由于人数是有限的,因此最后一定只会剩下一个人,求这个人的编号。

    【输入形式】

    第一行,一个整数n,表示约瑟夫环的总人数。

    第二行,一个整数m,表示报到m的人被淘汰。

    【输出形式】

     一行,一个整数,约瑟夫环最终剩下的人的编号。

    【样例输入】

    5
    2

    【样例输出】

    3

    【样例说明】

    5个人围成一圈,编号1,2,3,4,5;

    第一轮,2号淘汰,剩下1,3,4,5;

    第二轮,从3开始报数,4号淘汰,剩下1,3,5;

    第三轮,从5开始报数,1号淘汰,剩下3,5;

    第四轮,从3开始报数,5号淘汰,剩下3。
    【评分标准】

    通过所有数据

    1. #include
    2. #include
    3. typedef struct Node {
    4. int data;
    5. struct Node* next;
    6. } Node,*LinkList;
    7. LinkList createNode(int data) {
    8. LinkList newNode = (LinkList)malloc(sizeof(Node));
    9. newNode->data = data;
    10. newNode->next = NULL;
    11. return newNode;
    12. }
    13. void appendNode(LinkList* head, int data) {
    14. LinkList newNode = createNode(data);
    15. if (*head == NULL) {
    16. *head = newNode;
    17. newNode->next = *head;
    18. } else {
    19. LinkList temp = *head;
    20. while (temp->next != *head) {
    21. temp = temp->next;
    22. }
    23. temp->next = newNode;
    24. newNode->next = *head;
    25. }
    26. }
    27. void deleteNode(LinkList* head, int m) {
    28. if (*head == NULL) {
    29. return;
    30. }
    31. LinkList current = *head;
    32. LinkList prev = NULL;
    33. while (current->next != *head) {
    34. prev = current;
    35. current = current->next;
    36. }
    37. if (current == *head && current->next == *head) {
    38. *head = NULL;
    39. free(current);
    40. return;
    41. }
    42. int i;
    43. for ( i = 1; i <=m; i++) {
    44. prev = current;
    45. current = current->next;
    46. }
    47. prev->next = current->next;
    48. free(current);
    49. *head = prev->next;
    50. }
    51. int josephus(int n, int m) {
    52. LinkList head = NULL;
    53. int i;
    54. for (i = 1; i <= n; i++) {
    55. appendNode(&head, i);
    56. }
    57. while ( head!=head->next) {
    58. deleteNode(&head, m);
    59. }
    60. return head->data;
    61. }
    62. int main() {
    63. int n, m;
    64. scanf("%d%d", &n, &m);
    65. int result = josephus(n, m);
    66. printf("%d\n", result);
    67. return 0;
    68. }

  • 相关阅读:
    【linux】自定义nameserver
    JS解混淆
    CDN:网站性能的加速器 —— 选择最适合你的CDN服务商
    医院各领域榜单。22个科室、100种常见疾病
    类和对象(上)
    数组和List相互转化(摒弃循环)
    2022.8.2-----leetcode.622
    Mathtype问题汇总
    VR全景广告:让消费者体验沉浸式交互,让营销更有趣
    Vue中事件总线EventBus的应用(三)定义全局事件——实例之main.js-创建事件总线、$emit-发布事件、$on-订阅事件、$off-去除事件
  • 原文地址:https://blog.csdn.net/timberman666/article/details/134016814