题目所在的网址是http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3181
写的程序在 vs2008中无问题。但在 gcc中出现 Segmentation Fault错误。不知道是哪错了?
请教高手
本人的代码如下:
// cover.cpp
// 回溯法解决此问题。
// 将问题转换为区间的连续问题。
// 计算各子字符串在目标字符串中的区间,记录在record中。
// 对于子字符串在目标字符串中多次出现的情况,需要分别
// 记录。
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>
// 区间的数据类型
struct pos
{
int left;
int right;
};
/* 读入目标字符串和子字符串,并将子字符串的区间写入record
* 下标从1 计,返回record的大小
*/
int readin(char *target, char **tile, struct pos *record)
{
// read in data
scanf(“%s%*c”, target);
int count;
scanf(“%d%*c”, &count);
int idofrcd = 0;
// build record
for (int i = 0; i < count; ++i)
{
scanf(“%s%*c”, tile);
char *p = target;
while (true)
{
p = strstr(p, tile);
if (p == NULL)
break;
idofrcd += 1; // 下标从1 计
record[idofrcd].left = p -target;
record[idofrcd].right = record[idofrcd].left + strlen(tile) – 1;
p += 1;
}
}
return idofrcd;
}
// return true if ok
bool OK(struct pos *record, int *save, int k)
{
const int BEGIN = 0;
if (k == 1)
{
return (record[save[k]].left == BEGIN) ? true : false;
}
if (record[save[k]].left > record[save[k-1]].left &&
record[save[k]].left <= record[save[k-1]].right &&
record[save[k]].right > record[save[k-1]].right)
return true;
return false;
}
int deal(struct pos *record, int lenofrcd, int endoftrg)
{
//
int count = 0; // 记录解决方案的数量
int *save = (int *) calloc(50, sizeof(int));
int k = 1;
while ( k >= 1)
{
save[k] += 1;
//
while (save[k] <= lenofrcd && !OK(record, save, k))
save[k] += 1;
if (save[k] <= lenofrcd)
{
if (record[save[k]].right < endoftrg)
k += 1;
else if (record[save[k]].right == endoftrg)
count += 1;
}
else
{
save[k] = 0;
k -= 1;
}
}
free(save);
return count;
}
int main()
{
const int LEN_TRG = 100; // 目标字符串的最大长度
const int LEN_TLE = 50; // 子字符串的最大长度
const int COUNT_TLE = 50; // 子字符串的最大个数
int count = 0;
scanf(“%d%*c”, &count);
char target[LEN_TRG] = { 0 };
char **tile = (char **) calloc(COUNT_TLE, sizeof(char *));
tile[0] = (char *) calloc(COUNT_TLE * LEN_TLE, sizeof(char));
for (int i = 1; i < COUNT_TLE; ++i)
tile = tile[i-1] + LEN_TLE;
struct pos *record = (pos *) calloc(COUNT_TLE, sizeof(pos));
//
while (count– > 0)
{
int lenofrcd = readin(target, tile, record);
// 目标字符串最后一个字符的下标
int endoftrg = strlen(target) – 1;
int num = deal(record, lenofrcd, endoftrg);
printf(“%d\n”, num);
memset(tile[0], 0, COUNT_TLE * LEN_TLE);
memset(record, 0, COUNT_TLE * sizeof(pos));
}
free(tile[0]);
free(tile);
free(record);
return 0;
}
-
近期文章
近期评论
- coolker 发表在《打造最快的Hash表》
- struggle 发表在《提供C语言教学课件(适用于初学者)》
- zhanghaibo 发表在《提供C语言教学课件(适用于初学者)》
- zhanghaibo 发表在《提供C语言教学课件(适用于初学者)》
- diys 发表在《C语言编程宝典(王大刚) 1.1 C 语言的产生与发展》
文章归档
- 2022 年十月
- 2014 年一月
- 2013 年十二月
- 2012 年十一月
- 2012 年七月
- 2012 年六月
- 2012 年五月
- 2012 年四月
- 2012 年三月
- 2012 年二月
- 2011 年十二月
- 2011 年十月
- 2011 年九月
- 2011 年八月
- 2011 年七月
- 2011 年六月
- 2011 年五月
- 2011 年四月
- 2011 年三月
- 2011 年二月
- 2011 年一月
- 2010 年十二月
- 2010 年十一月
- 2010 年十月
- 2010 年九月
- 2010 年八月
- 2010 年七月
- 2010 年六月
- 2010 年五月
- 2010 年四月
- 2010 年三月
- 2010 年二月
- 2010 年一月
- 2009 年十二月
- 2009 年十一月
- 2009 年十月
- 2009 年九月
- 2009 年八月
- 2009 年七月
- 2009 年六月
- 2009 年五月
- 2009 年四月
- 2009 年三月
- 2009 年二月
- 2009 年一月
- 2008 年十二月
- 2008 年十一月
- 2008 年十月
- 2008 年九月
- 2008 年八月
- 2008 年七月
- 2008 年六月
- 2008 年五月
- 2008 年四月
- 2008 年三月
- 2008 年二月
- 2008 年一月
- 2007 年十二月
- 2007 年十一月
- 2007 年十月
- 2007 年九月
- 2007 年八月
- 2007 年七月
- 2007 年六月
- 2007 年三月
- 2007 年二月
- 2007 年一月
- 2006 年十二月
- 2006 年十一月
- 2006 年十月
- 2006 年九月
- 2006 年八月
- 2006 年七月
- 2006 年六月
- 2006 年五月
- 2006 年四月
- 2006 年三月
- 2006 年二月
- 2006 年一月
- 2005 年十二月
- 2005 年十一月
分类目录
功能
题目所在的网址是http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3181
写的程序在 vs2008中无问题。但在 gcc中出现 Segmentation Fault错误。不知道是哪错了?
请教高手
本人的代码如下:
// cover.cpp
// 回溯法解决此问题。
// 将问题转换为区间的连续问题。
// 计算各子字符串在目标字符串中的区间,记录在record中。
// 对于子字符串在目标字符串中多次出现的情况,需要分别
// 记录。
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>
// 区间的数据类型
struct pos
{
int left;
int right;
};
/* 读入目标字符串和子字符串,并将子字符串的区间写入record
* 下标从1 计,返回record的大小
*/
int readin(char *target, char **tile, struct pos *record)
{
// read in data
scanf(“%s%*c”, target);
int count;
scanf(“%d%*c”, &count);
int idofrcd = 0;
// build record
for (int i = 0; i < count; ++i)
{
scanf(“%s%*c”, tile);
char *p = target;
while (true)
{
p = strstr(p, tile);
if (p == NULL)
break;
idofrcd += 1; // 下标从1 计
record[idofrcd].left = p -target;
record[idofrcd].right = record[idofrcd].left + strlen(tile) – 1;
p += 1;
}
}
return idofrcd;
}
// return true if ok
bool OK(struct pos *record, int *save, int k)
{
const int BEGIN = 0;
if (k == 1)
{
return (record[save[k]].left == BEGIN) ? true : false;
}
if (record[save[k]].left > record[save[k-1]].left &&
record[save[k]].left <= record[save[k-1]].right &&
record[save[k]].right > record[save[k-1]].right)
return true;
return false;
}
int deal(struct pos *record, int lenofrcd, int endoftrg)
{
//
int count = 0; // 记录解决方案的数量
int *save = (int *) calloc(50, sizeof(int));
int k = 1;
while ( k >= 1)
{
save[k] += 1;
//
while (save[k] <= lenofrcd && !OK(record, save, k))
save[k] += 1;
if (save[k] <= lenofrcd)
{
if (record[save[k]].right < endoftrg)
k += 1;
else if (record[save[k]].right == endoftrg)
count += 1;
}
else
{
save[k] = 0;
k -= 1;
}
}
free(save);
return count;
}
int main()
{
const int LEN_TRG = 100; // 目标字符串的最大长度
const int LEN_TLE = 50; // 子字符串的最大长度
const int COUNT_TLE = 50; // 子字符串的最大个数
int count = 0;
scanf(“%d%*c”, &count);
char target[LEN_TRG] = { 0 };
char **tile = (char **) calloc(COUNT_TLE, sizeof(char *));
tile[0] = (char *) calloc(COUNT_TLE * LEN_TLE, sizeof(char));
for (int i = 1; i < COUNT_TLE; ++i)
tile = tile[i-1] + LEN_TLE;
struct pos *record = (pos *) calloc(COUNT_TLE, sizeof(pos));
//
while (count– > 0)
{
int lenofrcd = readin(target, tile, record);
// 目标字符串最后一个字符的下标
int endoftrg = strlen(target) – 1;
int num = deal(record, lenofrcd, endoftrg);
printf(“%d\n”, num);
memset(tile[0], 0, COUNT_TLE * LEN_TLE);
memset(record, 0, COUNT_TLE * sizeof(pos));
}
free(tile[0]);
free(tile);
free(record);
return 0;
}