求字符串中出现次数最多且最长的子串、连续出现次数最多的子串

代码如下:

#include <iostream>
#include <sstream>//字符串流
#include <vector>
using namespace std;
#define MAX_WORD 50

struct s_str
{
	string s;
	size_t len;
	int n;
};

vector<s_str> find_all_substrings(string s)
{
	vector<s_str> v;
	if (s.c_str()=="")
	{
		return v;
	}
	else
	{
		
		for (unsigned int i=1; i<=s.length(); i++)//子串的长度从1开始直至整个字符串的长度
		{
			for (unsigned int j = 0; j<s.length(); j++)//每一种长度的所有子串
			{
				if (j+i>s.length())//剩下的不够了就退出循环
					break;
				string s_temp = s.substr(j, i);//序号为j,长度为i
				vector<s_str>::iterator iter = v.begin();

				//查找该子串是否已经包含在容器当中了
				for (; iter != v.end(); iter++)
				{
// 					const char* p1 = s_temp.c_str();
// 					const char* p2 = (*iter).s.c_str();
// 
// 					while (*p2 && *p1)
// 					{
// 						if (*p2 != *p1)
// 							break;
// 						p1++;
// 						p2++;
// 					}
// 
// 					if (*p1 == '\0' && *p2 == '\0')
// 					{
// 						(*iter).n++;//次数加1
// 						break;
// 					}
// 					
					if (s_temp.substr(0, s_temp.length())==(*iter).s.substr(0, (*iter).s.length()))
					{
						(*iter).n++;//次数加1
						break;
					}
				}

				//如果不在就添加到容器当中去
				if (iter == v.end())
				{
					s_str ss;
					ss.s = s_temp;
					ss.len = s_temp.length();
					ss.n = 1;
					v.push_back(ss);
				}
			}
			
		}
		return v;
	}
}

//找出出现次数最多且最长的子串
string find_most_appear_string(string s)
{
	string s_return;
	vector<s_str> v;
	v = find_all_substrings(s);//找到所有的子串,并统计它们出现的次数
	
	vector<s_str>::iterator iter = v.begin();
	for (vector<s_str>::iterator iter1 = v.begin(); iter1!=v.end(); iter1++)
	{
		if ((*iter1).n>(*iter).n || \
			((*iter1).n==(*iter).n && (*iter1).len>(*iter).len))
		{
			//max = (*iter1).n;
			iter = iter1;
		}
	}
	if (iter==v.end())//v是空的
	{
		s_return = "";
	}
	else
		s_return = (*iter).s;

	return s_return;
}
/******************************************************
 *找出连续出现次数最多的子串
 *原理:假设一个字符串是abcbcbcd,则如此取其子串
 *             abcbcbcd   
 *             bcbcbcd
 *             cbcbcd
 *             bcbcd
 *             cbcd
 *             bcd
 *             cd
 *             d
 *从第一个子串开始找,将第一个子串与下面的其它子串进行比较
 *相隔几个就比较几个字符,例如第一个子串abcbcbcd和第三个
 *子串cbcbcd距离为2,则比较2个字符,如果相等,则继续和第五
 *(3+2=5)个比较
 *****************************************************/
pair<int, string> fun(const string& str)
{
	vector<string> substrings;
	int maxcount = 1, count = 1;
	string substr;

	int i,len = str.length();
	for (i=0; i<len; i++)
	{
		substrings.push_back(str.substr(i, len-i));
	}
	for (i=0; i<len; i++)
	{
		for (int j = i+1; j<len; j++)
		{
			count = 1;
			if (substrings[i].substr(0, j-i) == substrings[j].substr(0, j-i))
			{
				count++;
				for (int k=j + (j-i); k<len; k+=j-i)
				{
					if (substrings[i].substr(0, j-i) == substrings[k].substr(0, j-i))
					{
						count++;
					}
					else
						break;
				}
				if (count > maxcount)
				{
					maxcount = count;
					substr = substrings[i].substr(0, j-i);
				}
			}
		}
	}
	return make_pair(maxcount, substr);
}

int main()
{
	char c_continue;
	do 
	{
		string line,word;
		cout << "please input a string: ";
		cin.clear();
		cin >> word;
		//getline(cin, line);
		//istringstream sstream(line);
		//sstream >> word;
	
		string s_sub = find_most_appear_string(word);//找出出现次数最多且长度最长的子串

		cout << "the most appeared substring is " << "'" << s_sub.c_str() << "'" << endl;

		pair<int, string> rs;
		rs = fun(word);
		cout << "the most appeared substring is " << "'" << rs.second << "'" << endl;

		cout << "do you want to continue? Y/N" << endl;
		//c_continue = getchar();
		cin >> c_continue;

	} while (c_continue=='Y' || c_continue=='y');
	
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值