回 帖 发 新 帖 刷新版面

主题:关于双向链表的程序,等待解救

C多D若E米F发G骚A拉B稀
用ABCDEFG定义七个音符,每个音节可以有3个,4个,5个等等若干个节拍,每个节拍可以是一个音符,或者是一个休止符,一个乐谱可以是这样的
|C C C D|E _ D _|C E D D|

下面就是程序了 
1.设计一个光标,可以由左向右移动,此光标可以选择一个小节或者一个音符。
2.通过光标可以修改音符
3.可以插入一个空白小节,这个小节或者是在原来两个小节之中,或者是在最后一个小节之后
4.实现一个或者几个小节的复制,剪切,粘贴
为了实现复制粘贴,我们将光标移至要复制的第一个音节,然后指出要复制的音节数,之后再将光标移动,我们选择是要插入光标之前还是之后
5.为了实现取消剪切和粘贴命令,我们利用在一个堆栈的缓存

关于乐谱的显示:同时显示三行,这三行分别是光标所在行,和光标所在前一行和后一行,一行最多显示24个音符,每小节必须在一行完成

可预见的补充方程
1.光标可垂直移动
2.读乐谱是能够按周一定的速度自动读取,光标可根据一定的速度自动移动
3.可以保存乐谱在某个文件夹下,并且可以打开一个我们存储的乐谱
4.管理取消修改音符,之后取消剪切粘贴 


我是这么想的,乐谱是一个指针,指向一个双向链表,每个小节就是一个双向的链表(包括三部分,第一部分是指向前一个音节,第二部分是音符,第三部分是指向后一个音节)

现在令我想不明白的几点
1.移动光标完全迷茫
2.我将光标移至某处,如何显示出来我要进行的操作?
3.还有关于显示三行完全迷茫,怎么就显示三行,显示24个音符了?

我知道如果求程序的话会很无耻。。。先解决了这两个问题也好。。能加扣扣点播一下更是感激不尽。。。

我是这么设置这个乐谱的种类的 typedef struct par {char note[]; struct par *prece, *next; }partition,*Partition;

回复列表 (共2个回复)

沙发

看来楼主思考了很多,我说一下自己的想法。

1、先想想自己到底要做出什么样的功能。什么是核心功能,什么是外围功能。
程序的功能不外乎三种,输入数据,处理数据,输出数据。通常,可以把“处理数据”这一部分作为核心,先把它搞定,然后再来解决输入、输出的问题。相信一点:作为一个软件来说,输入、输出不管再怎么复杂,始终是程序的外围,不会影响整个程序的核心。把核心部分搞好,就成功了一半。
具体的说,凡是涉及到“显示音符”“光标移动”“保存到文件”“从文件读取”“复制粘贴”,这些都是输入输出的问题,并非核心问题,可以先放一边。然后从数据的角度来分析:
“显示音符”要求能够显示指定位置附近三行的所有音符,抛开显示不管,现在其实只需要“能够取得一个音符附近三行的所有音符”。坚信一点:只要取得了音符,总有办法显示的。
类似的:
“从文件读取”其实是要求在一段长度为零的音符后面添加一段指定的音符,
“保存到文件”其实是要求能够按顺序的获取每一个音符,
“复制粘贴”其实是要求获取指定位置的一段音符,然后再添加到另一个指定位置。
最后,“光标移动”其实就是设置一个位置而已,显示光标属于输出问题,并非核心,先不考虑。向右移动,其实就是移动到下一个位置,向下移动,其实就是移动到下24个位置(如果是最后一行,则需要考虑结束符;另外,如果乐谱可以换行,则还需要考虑换行符)。

2、设计程序的逻辑结构。
在大型软件中,逻辑结构可能很复杂,可能分为若干个子系统。但在这里,逻辑结构其实很简单,稍微分析一下,就发现其实只需要解决两个问题。第一,如何在内存中保存一个乐谱?第二,如何表示乐谱中的一个位置?第一个问题其实是一个数据结构问题,而根据第一个问题的答案其实很快就能推出第二个问题的答案。
说穿了,其实只要设计一个数据结构即可。根据第1步的分析,这个数据结构要求:
(1) 可以遍历每一个音符。
(2) 可以取出指定位置相邻的三行。
(3) 指定的位置可以上下左右移动。
(4) 可以在指定位置进行添加删除。

我觉得双向链表并不是一个特别好的选择。
如果只是简单的程序,用线性表就够了。一个表就能保存所有的音符,用索引来表示位置,虽然添加删除的性能较低,但是只要乐谱不是太长,问题也不大。
如果要做得好,可以参考文本编辑软件。我的想法是做一个线性表,乐谱的一行音符就是线性表的一个元素。一行音符其实又是一个线性表。这样就成了二维的。
typedef struct Note { /* ... */ } Note;   --> 表示一个音符
typedef struct NoteLine {
    Node* notes;
    int count;
} NoteLine; /* 线性表,表示一行音符 */
typedef struct MusicBook {
    NodeLine* lines;
    int count;
} MusicBook; --> /* 线性表,表示一个乐谱 */
如此一来,用行号、列号就可以表示一个位置。从而处理光标的左右移动。

3、前面全部搞定之后,外围的问题就可以各个击破了。
文件的保存,很简单,相信对楼主来说不是难事。难点在于界面。
先定一个基调,要把程序做成命令行形式的,还是有窗口界面的?以窗口界面来说,可以供选择的技术也很多。微软有MFC,.NET,其他的还有QT,WxWidgets等。根据不同的选择,你需要不同的工具和不同的知识。看个人喜好具体处理了。
说明一下,很多同学重视数据结构,而轻视界面设计和制作,其实这个不太对。界面虽然是“外围问题”,但不等于不重要。因为这些“外围问题”其实是你的程序给人的第一印象,不能马虎。另外,这些“外围问题”也成为了很多程序员的饭碗,而能够靠数据结构等核心知识吃饭的,很少。

基本就是这些,楼主自己也多想想吧。想好了再开始写代码,这样比较好。

板凳

学习到了!

我来回复

您尚未登录,请登录后再回复。点此登录或注册