一直想要吐槽泥电的icoding平台,题目说明像坨💩,没有详细的错误返回说明,有的题目连自身验证逻辑都有问题。。。怪不得泥电平时只敢和211相比(bushi
但是这次的块链串是真的蚌埠住了
铁打的简略描述,让人感觉多写一点题目详细要求,维护的麻麻就要成👼了
这种描述无异于给下面写作业埋雷:
1.块链串是怎么初始化的?
2.头节点存不存数据?
3.pos第一次提及被称为“下标”,怎么第二次提及又称“第pos个字符起...”,pos到底是下标还是字符的位置?
4.指定的字串长度若在截取时越过了主串末尾,是算参数正确还是不正确?该返回true还是false?该不该不向串sub装载截断的子串?
5.某个块空白的位置到底是全部填上#,还是只填上第一个#?
这些玩意题目描述都™没有提及,合着布置题目的都是谜语人是吧
--------------------------------------------------------------
经过测试,这些未提及的细节如下:
1.题目会自行创造形如
BLString* test = (BLString*)malloc(sizeof(BLString));
的语句来初始化测试的串
2.头结点存数据
3.pos当作下标,子串包括下标为pos的字符
4.若截取子串时越过了主串的末尾,则截断子串,将截断的子串赋给sub,返回true(即视为成功执行
5.创建的每一个块的空白位置全部填上#,否则
根据这些要求,这里分享一个可以通过的版本(截至22/04/05):
#include <stdlib.h>
#include <stdio.h>
#include "dsstring.h" // 请不要删除,否则检查不通过
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#define MAX_SUB_STR_LEN 100
//为块链串装载字符串
void blstr_assign(BLString *T, const char *src_str)
{
blstr_init(T);
T->head = (Block *)malloc(sizeof(Block));
assert(T->head);
//下面的循环是为了把新分配给头节点的内存空间的数据域全填上'#'
for (int j = 0; j < BLOCK_SIZE; j++)
{
T->head->ch[j] = BLS_BLANK;
}
T->tail = T->head;
//下面的循环为块链串装载指定的字符串
//这里默认字符串以'\0'结尾
for (int i = 0; i < strlen(src_str) && *(src_str + i) != '\0'; i++)
{
if (i != 0 && i % 4 == 0) //每装4个字符就分配新节点
{
T->tail->next = (Block *)malloc(sizeof(Block));
assert(T->tail->next);
T->tail = T->tail->next;
T->tail->next = NULL;
//下面的循环用于给新分配的节点的字符数据域全部填上'#'
for (int j = 0; j < BLOCK_SIZE; j++)
{
T->tail->ch[j] = BLS_BLANK;
}
}
T->tail->ch[i % 4] = *(src_str + i);
T->tail->ch[i % 4 + 1] = BLS_BLANK;
}
T->len = strlen(src_str);
}
//取出src中第pos个字符开始的len长度的子串, 然后用sub返回
bool blstr_substr(BLString src, int pos, int len, BLString *sub)
{
assert(sub);
//icoding似乎没测试len为0的情况,这里(按照题目意思)该返回true还是false有待商榷
if (len == 0)
{
return false;
}
Block *current_block = src.head;
int src_cursor = 0;
for (; src_cursor <= pos && current_block != NULL && current_block->ch[src_cursor % 4] != BLS_BLANK; src_cursor++)
{
if (src_cursor != 0 && src_cursor % 4 == 0)
{
current_block = current_block->next;
if (current_block == NULL)
{
return false;
}
}
}
src_cursor -= 1;
char __sub[MAX_SUB_STR_LEN];
for (int sub_cursor = 0; sub_cursor < len; src_cursor++, sub_cursor++)
{
//下面这个if似乎有点多余,不过能过就不管了:),有兴趣可以去掉这个if分支试试
if (current_block != NULL)
{
if (sub_cursor != 0 && src_cursor % 4 == 0)
{
current_block = current_block->next;
//如果主串指针的下一个节点为空(即到达末尾),则截断子串并装载给sub
if (current_block == NULL)
{
blstr_assign(sub, __sub);
return true;
}
}
//如果主串指针在子串长度小于len之前就遇到'#'(即到达末尾),则截断子串并装载给sub
if (current_block->ch[src_cursor % 4] == BLS_BLANK)
{
blstr_assign(sub, __sub);
return true;
}
__sub[sub_cursor] = current_block->ch[src_cursor % 4];
__sub[sub_cursor + 1] = '\0';
}
else
{
return false;
}
}
blstr_assign(sub, __sub);
return true;
}
这个代码结构毫无美感(笑,不过实在是没有动力重构icoding的作业了
欢迎指正