• 全部
  • 问答

算法高手请进

pkukevin 2008-04-24 11:02:02
题目:求一个字符串中连续出现次数最多的子串, 请给出分析和代码。
...全文
161 点赞 收藏 5
写回复
5 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
poson 2008-04-24
是不是要用后缀树之类的东西。先把所有的字串找出来。然后看那些字串出现了多少次。
或者考虑压缩算法中找相同字串相关的算法
回复
rushman 2008-04-24
频率最高的子串中必然有长度为 1 的子字符串。
如此可以简化问题。
回复
pkukevin 2008-04-24
是这个意思, 没有要求子串的长度,长度可以是1。而且结果可能有几个子串都是相同的次数。
回复
njurain 2008-04-24
题目是这个意思吧
abcbcbcabc
那就是bc连续出现了3次 是连续最多的子串

-------------

Mark 一下 中午休息再看
回复
rushman 2008-04-24
算法:
--------
找到文本中的出现次数最高的单个字符组成的子串,放入一个队列中,
从队列的头部开始,对结果集中的每一个子串 S 进行处理

1. 找到文本中该子串出现的任意一个位置 P,
2. 判断文本中紧随 S 之后的字符 C 是否的出现次数是最多的,
3. 如果 C 的出现次数不是最多的,结束。
4. 如果 C 的出现次数是最多的,搜索文本中的每一个 S 并判断紧随其后的字符是否是 C,
5. 如果文本中的每一个 S 之后都存在字符 C ,将 S + C 生成的子串放入结果集中,
6. 如果文本中出现 S 之后的字符不是 C ,结束。

如此,直至到达队列尾。

#pragma warning(disable : 4786)
#include <iostream>
#include <string>
#include <deque>

#define BUFFSIZE 1024

using std::cout;
using std::endl;
using std::string;
using std::deque;

typedef deque<string> strlist;

const string::size_type npos = -1;
const string ignoreChars(" \t\n\r");

inline bool IgnoreChar(char c){
return (ignoreChars.find(c) != npos);
}

/*
* 统计字符出现次数
*/
unsigned CharSummary(const string& text, unsigned usecount[], int tbllen){
unsigned count, i;

memset(usecount, 0, tbllen * sizeof(unsigned));
for(i = 0;i < text.length();usecount[unsigned(text[i++])]++);

for(count = i = 0;i < 256;i++){
if(IgnoreChar(i))continue;
if(usecount[i] > count)count = usecount[i];
}

return count;
}

/*
* 试着增长字符串
*/
char TryGrowthString(const string& text, const string& str, int maxcount, unsigned* usecount){
int count;
string::size_type pos;
char c = 0;

pos = text.find(str);
if(pos == npos)
return 0;

/* 不是出现次数最多的字符 */
c = text[pos + str.length()];
if(usecount[unsigned(c)] < maxcount)
return 0;

/* 检查文本中的出现次数 */
for(count = 0; pos + str.length() + 1 < text.length();pos += str.length()){
pos = text.find(str, pos);
if(pos == npos) break;
if(c != text[pos + str.length()]) return 0;
}

return c;
}

void PrintResult(const strlist& result){
strlist::const_iterator citer;

cout<<endl<<"The result substrings :"<<endl;
cout<<"-------------------------------------"<<endl;
for(citer = result.begin(); citer != result.end(); citer++){
cout<<'"'<<*citer<<'"'<<endl;
}
cout<<"-------------------------------------"<<endl;
cout<<"Total : "<<result.size()<<endl;
}

void main(void){
unsigned usecount[256];
char buffer[BUFFSIZE], c;
unsigned count, i;
string text;
strlist result;

/*
* 从 stdin 读入文本
*/
while(!feof(stdin)){
if(fgets(buffer,sizeof(buffer),stdin))
text += buffer;
}

/*
* 统计字符出现次数
*/
count = CharSummary(text, usecount, sizeof(usecount) / sizeof(*usecount));
cout<<"Max count :"<<count<<endl;

if(0 == count){
cout<<"There is empty string!"<<endl
<<"Bye!"<<endl;
}

/*
* 将出现次数最多的字符作为子串放入结果中
*/
for(i = 0;i < sizeof(usecount) / sizeof(*usecount);i++){
if(usecount[i] == count)
result.push_back(string(1,char(i)));
}

/*
* 查找更多的子串
*/
for(strlist::iterator iter = result.begin();iter != result.end();iter++){
c = TryGrowthString(text, *iter, count, usecount);
if(c)
result.push_back(*iter + string(1, c));
}

PrintResult(result);
cout<<"Bye!"<<endl;
}

测试输入:
abcdefg
bcdef
hijklmnopqrstabcdefg

输出:
Max count :3

The result substrings :
-------------------------------------
"
"
"b"
"c"
"d"
"e"
"f"
"bc"
"cd"
"de"
"ef"
"bcd"
"cde"
"def"
"bcde"
"cdef"
"bcdef"
-------------------------------------
Total : 16
Bye!
回复
相关推荐
发帖
数据结构与算法
创建于2007-08-27

3.2w+

社区成员

数据结构与算法相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2008-04-24 11:02
社区公告
暂无公告