话说最近,帮老总的儿子做一份作业,此君在英国留学,学计算机,几年级的就不知道了。
他说怕得F,需要我们帮忙。那就做吧,正好对老外的计算机课程也挺感兴趣,看看别人是怎么出题的。
从需求来看,主要是想考验学生对链表的了解,定义一个结构体,有两个成员,分别为名称、编号;
然后从另外一个文件读入命令,根据命令对链表进行操作,如排序、删除元素、插入等。
一句话虽然简单,但有蹩脚E文的我,愣是啃了好长一会。并且提供一个脚本自动编译及测试,
这一点还是要赞一下,而且需求里面,把我考虑到的没考虑到的都说得很详细,比说,文件格式约定为良好等。并有完善的评分标准。
数据文件data_1.txt:
-------------------------
John
2
Bill
1
Kim
3
Christos
3
Alex
4
Jo
8
Jo
6
Alex
9
命令文件1: -------------------------
r
1
w
1
r:即读取,后面接1,意思是读取文件名为[data_1.txt]
w:即写出,后面接1,存为文件名[output_1.txt]
命令文件15[command_15.txt] -------------------------
r
1
s
d
Alex
d
John
i
Kim
-10
i
Fu
100
i
Zu
50
d
Katerina
d
Bill
w
15
d:删除名称为Alex的item
i:插入名称为Kim,编号为-10
其实最让我不爽的是,我用vs2005调试很完美的程序,然后在cygwin下面跑测试脚本,居然一个输出文件都没有生成。
后来发现是由于std::getline读取的字符串有一个'\r'(在这里真想骂MS,明明出来比别人晚,为什么不跟unix兼容呢?市场策略?)
由于我假设数据文件是完美的,而且根本没有考虑这种情况。最近不得不跟程序才找出原因,
原本想stl是不是有什么机制可以设置环境的换行符是'\r\n',还是'\n',google了一个多小时也没有找到完美的解决方案,
最后不得不用一种用逊的办法解决了。
bool getline(std::ifstream &is,std::string &str){
bool b = std::getline(is,str);
std::string::size_type p = str.find_last_of('\r');
if(p != std::string::npos) str.erase(p);
return b;
}
int list_sort(_list *list){
int count = 0, i = 0, j = 0;
list_item **iter_array;
list_item *iter;
if (list == NULL)
return -1;
//计算元素个数便于分配内存
count = list_count(list);
iter_array = (list_item**)malloc(sizeof(list_item*)*count);
//将链表数据拷贝到数组,便于冒泡排序
iter = list->next;
while(iter != NULL){
iter_array[i++] = iter;
iter = iter->next;
}
for (i = count - 1; i>=0; i--) {
for (j = 0; j < i; j++){
if ((*iter_array[j]).ID > (*iter_array[j+1]).ID){
iter = iter_array[j];
iter_array[j] = iter_array[j+1];
iter_array[j+1] = iter;
}
}
}
//重建链表
list->next = iter_array[0];
for (i = 0; i< count; i++)
{
if(i == count -1){
iter_array[i]->next = NULL;
break;
}
iter_array[i]->next = iter_array[i+1];
}
return 0;
}