给女朋友的题解专栏

括号匹配

/*
由题意可知这个题我们只关注三种括号即可
如果字符串是这样的{}((SK* )()),那么可以去掉其他字符变成这样——{}(()())
为了方便描述,每个字符的对应位置如下
0 1 2 3 4 5 6 7
{ } ( ( ) ( ) )
那么模拟一下代码流程,一共有八个字符,将分成八个步骤来讲解。
0、我们首先遇到的是'{’
此时栈当中没有元素,可知左括号是无法与其他括号匹配的,所以将‘{’塞入栈当中,此时栈的元素有一个——‘{’,此时栈的内容是这样的【‘{’】。
1、第二个字符为‘}’,
我们可以知道的是右括号可以与左括号匹配,而字符'}'可以匹配的字符是'{'。此时可以看到的是栈尾元素是'{',那么这两个括号是可以匹配的,就像消消乐一样,我们可以将其消除掉,此时栈的内容是这样的【】,什么都没有
2、遇到括号'(',与0步骤一样,将其填入栈中,栈内容是这样的【'('】
3、同上,栈内容为【'(','('】
4、遇到括号')',可以看到栈尾元素为'(',消除,栈内容变为【'('】
5、同步骤2,栈内容变为【'(','('】
6、遇到')',栈尾元素为‘(',消除,栈内容变为【'('】
7、遇到')',栈尾元素为‘(',消除,栈内容变为【】
最后我们可以看到栈内容为空,说明所有括号都匹配上了,输出yes
*/
#include<iostream>
#include<stdio.h>
using namespace std;
int main(){
    cout<<(0x70)<<endl;
    char str[1050];
    while(gets(str)){
        char stack[1004];
        int num = 0;
        for (int i = 0; str[i]; i++){
            if(str[i] == ')'){              //当前元素为’)'
                if(num > 0 && stack[num-1] == '('){//栈不为空,并且栈尾元素为'('
                    num --;                            //可以匹配,将栈尾元素消除
                }else stack[num ++] = str[i];//否则说明无法匹配,将此字符压入栈中
            }
            if(str[i] == ']'){              //当前元素为’]'
                if(num > 0 && stack[num-1] == '['){//栈不为空,并且栈尾元素为'['
                    num --;                            //可以匹配,将栈尾元素消除
                }else stack[num ++] = str[i];//否则说明无法匹配,将此字符压入栈中
            }
            if(str[i] == '}'){              //思路同上
                if(num > 0 && stack[num-1] == '{'){
                    num --;
                }else stack[num ++] = str[i];
            }
            if(str[i] == '(' || str[i] == '[' || str[i] == '{'){//遇到左括号则直接将其压入栈中
                stack[num ++] = str[i];
               }
        }
        if(num == 0){               //栈的内容为空,说明所有括号都已经匹配上了
            printf("yes\n");
        }else {                     //栈内容不为空,说明右括号没有匹配到
            printf("no\n");
        }
    }
}
View Code

链表插入删除

#include<stdio.h>
#include<stdlib.h>
typedef struct node{
    int data;
    struct node *next;
}Node,*LinkList;

/*创建一个新链表*/
void CreatList_L(LinkList &L,int n)
{
    int a;
    L = (LinkList)malloc(sizeof(Node));
    L->next = NULL;//建立一个带头结点的单链表
    Node *q = L;
    for(int i=0;i<n;i++)
    {
        Node *p = (LinkList)malloc(sizeof(Node));
        scanf("%d",&a);
        p->data = a;
        q->next = p;
        p->next=NULL;
        q = q->next;
    }
}

/*在链表的第i处插入一个元素*/
void Push_L(LinkList &L, int data, int i)
{
    Node *p = L;
    int j = 1;
    while(p&&j<i)
    {
        p=p->next;
        ++j;
    }
    Node *q = (LinkList)malloc(sizeof(Node));
    q->data = data;
    q->next = p->next;
    p->next = q;
}

/*删除第i个元素*/
void Delete_L(LinkList &L,int i)
{
    Node *p = L;
    if(i<0)
    printf("INFEASIBLE");
    int j = 1;
    while(p&&j<i)
    {
        p=p->next;
        ++j;
    }
    Node *q = p->next;
    p->next = p->next->next;
    free(q);
}
void Traverse_L(LinkList &L)
{
    LinkList p = L->next;
    while(p!=NULL){
        printf("%d ",p->data);
        p = p->next;
    }
    printf("\n");
}//正序遍历整个链表

int main()
{
    LinkList L;
    int n;
    printf("输入要创建的链表中的元素个数:\n");
    scanf("%d",&n);
    printf("输入%d个元素:\n",n);
    CreatList_L(L,n);
    printf("遍历整个链表\n");
    Traverse_L(L);

    int push_data,push_i;
    printf("输入你想要插入的元素和它的插入位置:\n");
    {
        scanf("%d%d",&push_data,&push_i);
    }
    Push_L(L, push_data, push_i);
    printf("插入后的链表遍历为:\n");
    Traverse_L(L);

    int del_i;
    printf("输入要删除链表中的第几个元素:\n");
    scanf("%d", &del_i);
    Delete_L(L, del_i);

    printf("删除后的链表遍历为:\n");
    Traverse_L(L);
    return 0;
}
View Code

进制转换

//进制转换
#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 80
typedef struct
{
    //栈的数据结构,采用数组
    char data[MAX_SIZE];
    int top;
} stack;
int isfull(stack s)
{
    //判断栈是否已满
    return (++s.top==MAX_SIZE);
}
int isempty(stack s)
{
    //判断栈为空
    return s.top==-1;
}
void push(stack * s,char in_data)
{
    //进栈
    if(isfull(*s))
    {
        printf("栈已满,不能执行操作!\n");
        exit(1);
    }
    s->data[++s->top]=in_data;
}
void pop(stack *s)
{
    //出栈
    if(isempty(*s))
    {
        printf("栈已空,不能执行操作!\n");
        exit(1);
    }
    s->top--;
}
char top_value(stack *s)
{
    //取栈顶元素
    if(isempty(*s))
    {
        printf("栈已空,不能执行操作!\n");
        exit(1);
    }
    return s->data[s->top];
}
int main(int argc,char** argv)
{
    int number;
    stack result;
    result.top=-1;
    int r_range;
    printf("输入转换的数据和对应的进制:");
    scanf("%d%d",&number,&r_range);
    printf("%d对应的%d进制为:",number,r_range);
    while(number!=0)
    {
        char input;
        if(number%r_range>=10)
            input=((number%r_range)-10)+'a';
        else
            input=((number%r_range)+'0');
        push(&result,input);
        number=number/r_range;
    }
    while(!isempty(result))
    {
        putchar(top_value(&result));
        pop(&result);
    }
    return 0;
}
View Code

顺序表操作

//这道题是考验顺序表操作的基础题
//每次遍历到一个元素,我们就可以找一下这个元素在之前出没出现过,如果出现过,就可以删除。
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main(){
    int num1[2005];
    int num2[2005];
    int n1 = 0;
    while(cin >> n1){                  //输入数组长度
                int n2 = 0;

        for(int i = 0; i < n1; i++){        //输出元素
            cin>>num1[i];
        }
        for(int i = 0 ; i< n1; i++){            //遍历数组
            bool exist = false;                 //这个值表示此元素在之前出没出现过,false为没出现过。
            for(int k = 0; k < i; k++){         //遍历之前的元素
                if(num1[i] == num1[k]){         //相等表示出现过
                    exist = true;               //将exist置为true,表示此元素在之前出现过
                }
            }
            if(exist == false){                 //如果此元素在之前没有出现过,那么将其塞入num2顺序表中。
                num2[n2++] = num1[i];
            }
        }
        cout<<n2<<endl;                         //输出num2顺序表的长度
        for(int i = 0; i < n2; i++){            //输出num2顺序表
            cout << num2[i];
            if(i != n2 - 1){
                cout<<" ";
            }
        }cout<<endl;
    }
}
View Code

 约瑟夫环

/*
题目描述
n个人想玩残酷的死亡游戏,游戏规则如下:

n个人进行编号,分别从1到n,排成一个圈,顺时针从1开始数到m,数到m的人被杀,剩下的人继续游戏,活到最后的一个人是胜利者。

请输出最后一个人的编号。
输入
输入n和m值。
输出
输出胜利者的编号。
*/

//经典的约瑟夫环问题,我们可以用链表来实现它。
//从第一个数开始查,每到m的倍数就可以将此人删掉
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
using namespace std;
class node
{
public:
    int data;
    node *next;
};
int main()
{
    int n,m,w;
    while(cin>>n>>m){    //输入n个人,每m个退出一人
        int i;
        node *head,*p,*tail,*q;
        head=new node;              //链表头
        head->next=NULL;            //初始化链表头,第一个人编号十一
        head->data=1;
        tail=head;                  //rail表示链表的尾部
        for(i=2;i<=n;i++)           //依次插入2,3,4,5。。。。
        {
            p=new node;             //新建一个节点
            p->data=i;              //i表示此人的编号,初始化此节点
            p->next=NULL;
            tail->next=p;           //将链表尾部的指针指向此节点
            tail=p;                 //现在链表的尾部变成了此节点(第i个人的节点)
        }
        tail->next=head;            //将尾部的指针指向头部,这样形成了一个环
        q=head;
        while(q->next!=q)//从头开始遍历链表,当q的下一个节点等于q的时候,说明只有q一个元素了,退出循环
        {
            for(i=1;i<m-1;i++)         //遍历到第m-1个节点,下一个节点就是我们要删除的节点
            {
                q=q->next;
            }
            q->next=q->next->next;      //删除q->next这个节点
            q=q->next;                 //下次遍历从新的q这个节点开始遍历
        }
        printf("%d\n",q->data);           //输出结果
    }
    return 0;
}
/*
题目描述
n个人想玩残酷的死亡游戏,游戏规则如下:

n个人进行编号,分别从1到n,排成一个圈,顺时针从1开始数到m,数到m的人被杀,剩下的人继续游戏,活到最后的一个人是胜利者。

请输出最后一个人的编号。
输入
输入n和m值。
输出
输出胜利者的编号。
*/

//经典的约瑟夫环问题,我们可以用链表来实现它。
//从第一个数开始查,每到m的倍数就可以将此人删掉
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
using namespace std;
class node
{
public:
    int data;
    node *next;
};
int main()
{
    int n,m,w;
    while(cin>>n>>m){    //输入n个人,每m个退出一人
        int i;
        node *head,*p,*tail,*q;
        head=new node;              //链表头
        head->next=NULL;            //初始化链表头,第一个人编号十一
        head->data=1;
        tail=head;                  //rail表示链表的尾部
        for(i=2;i<=n;i++)           //依次插入2,3,4,5。。。。
        {
            p=new node;             //新建一个节点
            p->data=i;              //i表示此人的编号,初始化此节点
            p->next=NULL;
            tail->next=p;           //将链表尾部的指针指向此节点
            tail=p;                 //现在链表的尾部变成了此节点(第i个人的节点)
        }
        tail->next=head;            //将尾部的指针指向头部,这样形成了一个环
        q=head;
        while(q->next!=q)//从头开始遍历链表,当q的下一个节点等于q的时候,说明只有q一个元素了,退出循环
        {
            for(i=1;i<m-1;i++)         //遍历到第m-1个节点,下一个节点就是我们要删除的节点
            {
                q=q->next;
            }
            q->next=q->next->next;      //删除q->next这个节点
            q=q->next;                 //下次遍历从新的q这个节点开始遍历
        }
        printf("%d\n",q->data);           //输出结果
    }
    return 0;
}
View Code

 

大数相加

//首先输入两个字符串。假如分别为12345和23456
//首先将这两个字符串倒过来,分别变成54321和65432
//现在,新的字符循环从前到后分别是个位,十位,百位。。。。
//首先将两个字符串的第0个位置相加,可知5+6为11,那么也就是说,相加之后的数字个位是1,进位为1
//之后将十位相加,可知4+5=9,而个位有一个进位,加上进位之后为10,可知相加数字的十位为0,进位为1,依此类推
#include <string.h>
#include<iostream>
#include<stdio.h>

using namespace std;
const int AX = 1e5+666;
const int maxn = 1e4+666;
char s1[maxn];
char s2[maxn];
int a[maxn];
int b[maxn];
int c[maxn];
int main(){
    int T;
    cin>>T;
    while(T--){
        scanf("%s%s",s1,s2);//输入两个数,以字符串的形式
        int len1 = strlen(s1);//计算第一个数的长度
        int len2 = strlen(s2);//计算第一个数的长度
        memset(a,0,sizeof(a));//清空a数组
        memset(b,0,sizeof(b));//清空b数组
        memset(c,0,sizeof(c));//清空c数组,存的是相加的结果
        for(int i=len1-1;i>=0;i--){//将字符串倒过来,比如原来是12345,现在就变成54321
            a[len1-i-1] = s1[i]-'0';//第0个位置存个位,第一个位置存十位,第二个位置存百位。。。。。
        }

        for(int i=len2-1;i>=0;i--){//同上,将第二个数字倒过来
            b[len2-i-1] = s2[i]-'0';
        }

        int i,up;
        int k = max(len1,len2);//计算两个字符串的最大长度
        for(i=0,up=0;i<k;i++){//从低位到高位,up是进位
            c[i] = a[i] + b[i] + up;//计算当前位相加的结果,要加上进位,之后结果比如是13,那么当前位就是3,进位为1
            up = c[i]/10;//计算进位
            c[i]%=10;//计算当前
        }
        if(up) c[k] += up;//如果最后发现进位是1,那么说明出现a了例如500+600这种情况,进位为最高位
        for(int i=k;i>=0;i--){//倒着将结果字符串输出,
            if(i==k && c[k] == 0) continue;//如果最高位是零,那么不输出最高位
            cout<<c[i];
        }
        cout<<endl;
    }

    return 0;
}
View Code
posted @ 2018-10-19 16:47  icodefive  阅读(423)  评论(1编辑  收藏  举报