2013级测试赛 - F 播放器

Description

shadow喜欢听音乐,于是v11自己写了个播放器送给了shadow,这个播放器有一个播放列表,一个“下一首”按钮,一个“上一首”按钮,还有一个播放记录。

一开始播放器会播放播放列表中的第一首歌,当按下“下一首”按钮时,它会播放当前歌曲在播放列表中的下一首歌,若当前歌曲就是播放列表中的最后一首歌时,它仍会播放播放列表中的最后一首歌;当按下“上一首”按钮时,它会清除播放记录中的最后一首歌,并播放清除后播放记录中的最后一首歌,若清除后播放记录为空,则播放播放列表中的第一首歌;当按下播放列表中的某一首歌曲,它会播放该首歌曲。

任何时候,当播放器播放一首歌时,如果该歌曲与播放记录中的最后一首不同或者播放记录为空,便将该歌曲添加到播放记录中成为最后一首。

现在shadow对播放器进行了一系列操作,那么你能告诉我shadow进行每一个操作后,播放器在播放哪首歌吗?

Input

输入数据第一行包含一个整数T,表示测试数据的组数。对于每组测试数据:

第一行包含两个整数n( 0 < n <= 500 )、m( 0 < m <= 10000),分别表示播放列表中有n首歌曲,shadow进行了m项操作,播放列表中歌的编号依次为1,2,3……n 。

接下来m行,每行为以下三种形式之一:

PRE 表示按下了“上一首”按钮。

PLAY x 其中x为一个整数( 0 < x <= n ),表示按下了播放列表中的第x首歌。

NEXT 表示按下了“下一首”按钮。

Output

对于每组数据:输出m行,每行一个整数,表示执行了一项操作后播放器正在播放的歌曲。

Sample Input

1
5 10
PRE
NEXT
PLAY 5
NEXT
PLAY 5
PLAY 3
NEXT
PRE
PRE
PRE

Sample Output

1
2
5
5
5
3
4
3
5
2

Hint

 

  这个题也算我对链表的第一次应用,首先摆出开始回馈编译错误的代码

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

typedef struct
{
    int play;
    struct lis *next;
    struct lis *last;
} lis;

int main()
{
    int ii = 0,nn = 0;
    int n = 0,m = 0;
    int len = 0,mp3 = 0,quan = 0;
    char c[10],*p;
    lis *head = NULL;
    lis *ne,*t;  //NEW


    freopen ("1.txt","r",stdin);

    scanf ("%d",&nn);
    for (ii = 0; ii < nn; ii++)
    {
        head = malloc (sizeof (lis) * 1);
        ne = head;
        ne->play = 1;
        ne->next = NULL;
        ne->last = NULL;

        scanf ("%d %d",&n,&m);
        getchar ();
        while(m--)
        {
            gets (c);
            p = c;
            len = 0;
            while (*p != '\0')
            {
                len++;
                p++;
            }

            if(len >= 6)
            {
                p--;
                quan = 1;
                mp3 = 0;
                while (*p != ' ')
                {
                    mp3 += ((int)*p - 48) * quan;
                    quan *= 10;
                    p--;
                }

                if (mp3 != t->play)
                {
                    t = malloc (sizeof (lis) * 1);
                    ne->next = t;
                    t->last = ne;
                    ne = ne->next;
                    ne->play = mp3;
                    ne->next = NULL;
                }
            }
            else if (len == 4)
            {
                if (ne->play < n)
                {
                    t = malloc (sizeof (lis) * 1);
                    t->play = ne->play + 1;
                    ne->next = t;
                    t->last = ne;
                    ne = ne->next;
                    ne->next = NULL;
                }
            }
            else if (len == 3)
            {
                if (ne != head)
                {
                    free (ne);
                    ne = ne->last;
                    ne->next = NULL;
                }
            }
            printf ("%d\n",ne->play);
        }
    }

    return 0;
}


 

回馈是这个样子的

修改之后,我发现问题出在了结构体上,我一般定义结构体为了省事都是typedef struct,这样在main函数中声明变量可以直接写结构体名而不用写struct,但是用C++编译行不通,即使是在CB中,也无法编译成功,可以归结为C和C++的差异,在语法上,还有一个问题属于其差异,就是“t = malloc (sizeof (lis) * 1);”,在C中可以这样写,而在C++中不可以,在《C P P》中讲内存管理的时候虽然只是强调在C中最好加上(lis*)强制转换以加强对C++的可移植性,但对于C++的程序来讲,就一定要加上了,这个还需要养成习惯。

对于上述,我把typedef去掉并把所有lis换为struct lis,加上强制转换类型,终于没有了语法错误,但WA也来了。(从构建链表到WA已经用了一个多小时,事实证明,链表对于我还算很陌生)

 

 

学长修改

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct lis
{
    int play;
    struct lis *next;
    struct lis *last;
};

int main()
{
    int ii = 0,nn = 0;
    int n = 0,m = 0;
    int len = 0,mp3 = 0,quan = 0;
    char c[10],*p;
    struct lis *head = NULL;
    struct lis *ne,*t;  //NEW


    //freopen ("1.txt","r",stdin);

    scanf ("%d",&nn);
    for (ii = 0; ii < nn; ii++)
    {
        head = (struct lis *)malloc (sizeof (struct lis) * 1);
        ne = head;
        ne->play = 1;
        ne->next = NULL;
        ne->last = NULL;

        t = NULL;//将t指空

        scanf("%d %d%*c",&n,&m);
        //getchar ();
        while(m--)
        {
            gets (c);
            p = c;
            len = 0;
            //这里可以用 strlen()
            //或者换一个思路 用strcmp()
            //在课本上貌似都有 可以去看一下
            while (*p != '\0')
            {
                len++;
                p++;
            }
            //if(strcmp("PLAY",c) == 0)
            if(len >= 6)
            {
                p--;
                quan = 1;
                mp3 = 0;
                while (*p != ' ')
                {
                    mp3 += ((int)*p - 48) * quan;
                    quan *= 10;
                    p--;
                }
                //scanf("%d",&mp3);
                if (mp3 > n)
                    mp3 = n;

                //printf("mp3 = %d\n",mp3);

                //此处t有可能没有分配内存
                //比如第一组输入即为 PLAY 5
                //if (mp3 != t->play)
                if(mp3 != ne->play)//逻辑或与 的 短路原则
                {
                    t = (struct lis *)malloc (sizeof (struct lis) * 1);
                    ne->next = t;
                    t->last = ne;
                    ne = ne->next;
                    ne->play = mp3;
                    ne->next = NULL;
                }
            }
            else if (len == 4 || c[0] == 'N')
            //else if(strcmp("NEXT",c) == 0)
            {
                if (ne->play < n)
                {
                    t = (struct lis *)malloc (sizeof (struct lis) * 1);
                    t->play = ne->play + 1;
                    ne->next = t;
                    t->last = ne;
                    ne = ne->next;
                    ne->next = NULL;
                }
            }
            else if (len == 3 || c[0] == 'P')
           // else if(strcmp("PRE",c) == 0)
            {
                if (ne != head)
                {
                    t = ne;
                    ne = ne->last;
                    free (t);
                    ne->next = NULL;
                }
            }
            printf ("%d\n",ne->play);
           // printf ("\t%#x\n",&ne);
        }
    }
    return 0;
}


 

反思后修改

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

struct lis
{
    int play;
    struct lis *next;
    struct lis *last;
};

int main()
{
    int ii = 0,nn = 0;
    int n = 0,m = 0;
    int len = 0,mp3 = 0,quan = 0;
    char c[10],*p;
    struct lis *head = NULL;
    struct lis *ne,*t;  //NEW


    //freopen ("1.txt","r",stdin);

    scanf ("%d",&nn);
    for (ii = 0; ii < nn; ii++)
    {
        head = (struct lis *)malloc (sizeof (struct lis) * 1);
        ne = head;
        ne->play = 1;
        ne->next = NULL;
        ne->last = NULL;
        //第一个错误没有把t初始化
        t = head;

        scanf ("%d %d",&n,&m);
        getchar ();
        while(m--)
        {
            gets (c);
            p = c;
            len = 0;
            while (*p != '\0')
            {
                len++;
                p++;
            }

            if(len >= 6)
            {
                p--;
                quan = 1;
                mp3 = 0;
                while (*p != ' ')
                {
                    mp3 += ((int)*p - 48) * quan;
                    quan *= 10;
                    p--;
                }
                if (mp3 > n)
                    mp3 = n;
                    
                if (mp3 != ne->play)
                {
                    t = (struct lis *)malloc (sizeof (struct lis) * 1);
                    ne->next = t;
                    t->last = ne;
                    ne = ne->next;
                    ne->play = mp3;
                    ne->next = NULL;
                }
            }
            else if (len == 4)
            {
                if (ne->play < n)
                {
                    t = (struct lis *)malloc (sizeof (struct lis) * 1);
                    t->play = ne->play + 1;
                    ne->next = t;
                    t->last = ne;
                    ne = ne->next;
                    ne->next = NULL;
                }
            }
            else if (len == 3)
            {
                if (ne != head)
                {
                    t = ne;
                    ne = ne->last;
                    free (t);
                    ne->next = NULL;
                }
            }
            printf ("%d\n",ne->play);
        }
    }

    return 0;
}


其实我WA的本质就是没有清楚上一个链节与当前链节的关系,主要表现就是在PLAY X中判断是否重复出现了问题。

通过这个题,明显感觉到当大量指针涌来时,让我十分混沌,但是链表就是由指针串起来的,链表的操作基本都是指针完成的,指针指向那里?其空间代表的意义是什么?对其操作的目的以及最终会达到什么效果,一定要明了。比如此题中ne指向是当前链节,t可能是上一个链节(t需要初始化以免在就一个链节的情况下指向不明了),也可能是当前链节(初始化后指向第一个链节)。

不仅仅是链表什么的,在判断以及strcmp的使用上还不够熟悉,需要专门学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值