您的位置:首页 > 其它

山东省第七届ACM省赛——Memory Leak

2016-07-22 10:14 483 查看
第七届省赛已经结束很久了,当时比赛时最让我惋惜的那个题,却迟迟没有补上,快开始暑假集训了,这几天有点时间,就把这个题目给补上。点击打开链接

这个题目,当时一是时间不够,我们在之前浪费的时间太多了,最后只给这个题剩下了十几分钟的时间;二是理解的稍有偏差,导致虽然急急忙忙的敲了一发,但交上却没有过。

原题是英文,我的英语水平极差,这里就不放原题了。大概写一下这个题目的意思:就是说,要求我们模拟一下输入输出在内存中的体现,开头申请的那些空间在内存中是连续的,这样就会导致,如果两个相连变量里的数据首尾相连之后,输出前面的变量,会一起输出后面的内容,直到碰到'\0'为止,而后面的输入,有可能会覆盖前面末尾的'\0'。要求我们模拟这个过程,并在输入为cout的时候输出对应变量的内容,不过要注意的是,单个变量的输入,长度最多不会超过给这个变量定义的长度,我在比赛的时候就卡在这里了,补完题之后发现,只要在我当时的代码每个边界处加个'\0'就是正确的。不过当时确实已经没有时间来让我调试了,也是留了一个遗憾。

这个题,只要明白了题意,其实就是个模拟题。只要申请一段连续的空间,把题目中的变量分别输入就行了。不过因为我刚开始理解有一点偏差,虽然最后通过问和十一发WA发现了错误所在,但是,理解正确之后没有重新写一遍代码,而是直接在原来的代码上进行填补,代码已经被我改的惨不忍睹。这里就同时放上我和开始就理解正确的一位大神的代码。

我的代码:

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

char s[111111];
char name[1111];
int N, Len;
struct str
{
char name[1111];
int Begin, len;
}a[111111];

int chuli(char * s)
{
int l = strlen(s);
int i;
a
.Begin = Len;
for (i = 0; i < l; i++)
{
if (s[i] != '[')
{
a
.name[i] = s[i];
}
else
{
a
.name[i] = '\0';
break;
}
}
int h = 0;
for (i += 1; i < l; i++)
{
if (s[i] != ']')
{
h *= 10;
h += s[i] - '0';
}
else
{
break;
}
}
a
.len = h;
Len += h;
//printf("h=%d\n", h);
N++;
if (s[l-1] == ';') return 1;
return 0;
}

int Search(char *name)
{
for (int i = 0; i < N; i++)
if (strcmp(a[i].name, name) == 0) return a[i].Begin;
return -1;
}

int Search2(char *name)
{
for (int i = 0; i < N; i++)
if (strcmp(a[i].name, name) == 0) return a[i].len;
return -1;
}

int main()
{
int T;
scanf("%d", &T);
char o[33];
while (T--)
{
memset(s, 0, sizeof s);
N = 0;
Len = 0;
while (scanf("%s", o), strcmp(o, "return"))
{
//printf("%s\n", o);
if (strcmp(o, "char") == 0)
{
while (scanf("%s", name))
{
if (chuli(name)) break;
}
}
else if (strcmp(o, "gets") == 0)
{
scanf("%s%*c", name);
int i = Search(name);
char ss[1111];
gets(ss);
int e = Search2(name);
for (int r = 0; r < e; r++)
s[i+r] = '\0';
for (int r = 0; r < e && r < strlen(ss); r++)
{
s[i+r] = ss[r];
}
//printf("name=%s\n", name);
//printf("i=%d\n", Search(name));
}
else if (strcmp(o, "cout") == 0)
{
s[Len] = '\0';
scanf("%s", name);
//printf("name=%s\n", name);
//printf("i=%d\n", Search(name));
int i = Search(name);
printf("%s\n", s+i);
}
}
scanf("%*s");
}
return 0;
}


大神的代码:

#include <cstdio>
#include <cstring>
using namespace std;

struct info {
int len;
char name[10001];
char str[10001];
bool has_end;
} a[10001];
int cnt;

int GetIndex(char *name) {
for(int i=0; i<cnt; ++i) {
if(!strcmp(a[i].name, name)) return i;
}

return cnt;
}

int main(int argc, char const *argv[]) {
char op[7], name[10001], str[10001];
int t;
scanf("%d", &t);
while(t--) {
cnt = 0;
while(scanf("%s", op)) {
if(!strcmp(op, "char")) {
while(scanf("%s", str)) {
int len = strlen(str);
int flag = 1;
int tmp_cnt = 0, tmp_len = 0;
for(int i=0; i<len; ++i) {
if(flag==1 && str[i]!='[')
name[tmp_cnt++] = str[i];
if(str[i] == '[') {
name[tmp_cnt] = 0;
flag = 2;
continue;
}
if(flag==2 && str[i]!=']')
tmp_len = tmp_len*10 + str[i]-'0';
if(str[i] == ']') {
strcpy(a[cnt].name, name);
a[cnt].len = tmp_len;
a[cnt].str[0] = 0;
a[cnt].has_end = true;
cnt++;
continue;
}
}
if(str[len-1] == ';') break;
}
}
if(!strcmp(op, "gets")) {
scanf("%s%*c", name);
gets(str);
int idx = GetIndex(name);
int len = strlen(str);
if(len >= a[idx].len) {
str[a[idx].len] = 0;
a[idx].has_end = false;
}
else a[idx].has_end = true;
strcpy(a[idx].str, str);
}
if(!strcmp(op, "cout")) {
scanf("%s", name);
int idx = GetIndex(name);
for(int i=idx; i<cnt; ++i) {
printf("%s", a[i].str);
if(a[i].has_end) break;
}
printf("\n");
}
if(!strcmp(op, "return")) {
scanf("%*s");
break;
}
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: