5、字符串操作中相对复杂的几个程序

1、编写函数,实现把一个char组成的字符串循环右移n位。如abcdehi,n=2,hiabcde

示例代码

#include "iostream"
using namespace std;

const int MAX_LEN = 20;
void LoopMove(char* cpStr, int iSteps)
{
	//注意,在整个处理过程中,cpStr的最后字符都没有涉及处理
	char cTempArray[MAX_LEN];
	size_t szStrLength = strlen(cpStr);
	size_t in = szStrLength -iSteps;
	memcpy(cTempArray, cpStr + in, iSteps);
	memcpy(cTempArray + iSteps, cpStr, in);
	memcpy(cpStr, cTempArray, szStrLength);
	cTempArray[szStrLength + 1] = '\0';
	cout << cTempArray << endl;
}

int main() 
{
	char ctemp[] = "abcdefghi";
	LoopMove(ctemp, 2);
	cout << ctemp << endl;
	return 1;
}

2、输入一行字符串,找出其中出现的相同且长度最长的字符串,输出它及其首字符的位置。如yyabcdabjcabceg,则输出为abc,3

大体思路:把字符串yyabcdabjcabceg拆解:

yyabcdabjcabceg

yabcdabjcabceg

abcdabjcabceg

...

ceg

eg

g

然后对字符串进行排序,比较相邻字符串的前驱,求最长的共公前驱。

在我们的程序中的体现,我们没有用这种方法,因为这种方法在排序中会用很多时间。我们借用了C++的实现函数find来巧妙的实现。

注:basic_string::substr

basic_string substr(size_type pos = 0, size_type n = npos) const;

    The member function returns an object whose controlled sequence is a copy of up to n elements of the controlled sequence beginning at position pos.

返回一个从指定位置开始,并具有指定长度的子字符串。

参数

pos 必选。所需的子字符串的起始位置。字符串中第一个字符的索引为 0

n 可选项。返回的子字符串中包含的字符数。

备注 如果 n 0 或负数,将返回一个空字符串。如果没有指定该参数,则子字符串将延续到字符串的结尾。

    在VS中测试,如是n是负数或大于主串的总长度,则输出是pos开始到主串末尾的字符。

示例代码

#include "iostream"
#include "string"
using namespace std;


int main() 
{
	string strInput;
	cout << "Input a string: " << endl;
	cin >> strInput;
	string strTemp;
	for (size_t i = strInput.length() - 1; i > 1; i--)
	{
		for (size_t j = 0; j < strInput.length(); j++)
		{
			if ((i + j) <= strInput.length())
			{
				size_t szForw = 0;
				size_t szBacw = 0;
				strTemp = strInput.substr(j, i);
				szForw = strInput.find(strTemp);
				szBacw = strInput.rfind(strTemp);
				if (szBacw != szForw)
				{
					cout << strTemp << " " << szForw + 1 << endl;
					return 0;
				}
			}
		}
	}

	return 1;
}

3、实现strstr()功能。如主串是12345678,子串是234,则返回2345678

示例代码

#include "iostream"
#include "string"
using namespace std;

const char* strstr1(const char* strMainString, const char* strSubString)
{
	for (size_t i = 0; strMainString[i]; i++)
	{
		size_t iTempj = 0;
		size_t iTempi = i;
		if (strMainString[iTempi] == strSubString[iTempj])
		{
			while(strMainString[iTempi++] == strSubString[iTempj++])
			{
				if (strSubString[iTempj] == '\0')
					return &strMainString[i];
			}
		}
	}
	return NULL;
}

int main() 
{
    char str1[] = "12345678";
	char str2[] = "234";
	const char *str3 = strstr1(str1, str2);
	cout << str3 << endl;
	return 1;
}

4、将一句话中的单词倒置,标点符号不倒换。如“i come from tianjin.,倒换后变成“tianjin. from come i”。

大体思路:先把整个字符串调整,再针对每个单词进行调整。

示例代码

#include "iostream"
#include "string"
//#include "functional"
//#include "algorithm"
using namespace std;

int main() 
{
	cout << "Input a string: " << endl;
	string strOfaLine;
	getline(cin, strOfaLine);	
	size_t szStrLength = strOfaLine.length();
	size_t szTempbeg = 0;
	size_t szTempend = szStrLength - 1;
	
	//第一步,全局交换
	while(szTempbeg < szTempend)
	{
		swap<char>(strOfaLine[szTempbeg++], strOfaLine[szTempend--]);
	}

	//第二步,局部交换
	size_t szTempi = 0;
	while (strOfaLine[szTempi])
	{
		if (strOfaLine[szTempi] != ' ')
		{
			szTempbeg = szTempi;
			while(strOfaLine[szTempi] != '\0' && strOfaLine[szTempi] != ' ')
			{
				szTempi++;
			}
			szTempi--;
			szTempend = szTempi;
		}
		while(szTempbeg < szTempend)
		{
			swap<char>(strOfaLine[szTempbeg++], strOfaLine[szTempend--]);
		}
		szTempi++;
	}
	cout << strOfaLine << endl;
	return 1;
}

5、求一个字符串中连续出现次数最多的子串。

大体思路:如abcbcbcabc,则把字符串切割成:

abcbcbcabc

bcbcbcabc

  cbcbcabc

   bcbcabc

    cbcabc

     bcabc

...

        bc

         c

    然后,从第一个子串开始到最后一个子串,将当前串与后面的每个子串进行字符匹配,并统计。

示例代码

#include "iostream"
#include "string"
#include "vector"
//#include "functional"
//#include "algorithm"
using namespace std;

pair<int, string> StaticNum(const string &str)
{
	vector<string> substrs; //存放切割后的子字符串
    string substr;
	int iMaxCount = 1, iCount = 1;
	size_t iTempi, iLen = str.length();
	for (iTempi = 0; iTempi < iLen; iTempi++)
	{
		substrs.push_back(str.substr(iTempi, iLen - iTempi));
	}

	for (iTempi = 0; iTempi < iLen; iTempi++)
	{
		for (size_t iTempj = iTempi + 1; iTempj < iLen; iTempj++)
		{
			iCount = 1;
			if (substrs[iTempi].substr(0, iTempj - iTempi) == substrs[iTempj].substr(0, iTempj - iTempi))
			{
				iCount++;
				//对以后子串每一个都进行比较,iTempj - iTempi 为当前要比较的字符串的长度
				//注意,此时遍历时,步长是iTempj - iTempi
				for (size_t iTempk = iTempj + (iTempj - iTempi); iTempk < iLen; iTempk += iTempj - iTempi)
				{
					if (substrs[iTempi].substr(0, iTempj - iTempi) == substrs[iTempk].substr(0, iTempj - iTempi))
					{
						iCount++;
					}
					else //接下来的字符串已经不连续了
					{
						break;
					}
				}

				if (iCount > iMaxCount)
				{
					iMaxCount = iCount;
					substr = substrs[iTempi].substr(0, iTempj - iTempi);
				}
			}
		}
	}
	return make_pair(iMaxCount, substr);
}

int main() 
{
	string str;
	pair<int, string> rs;
	string strTemp = "abcbcbcabc";
	rs = StaticNum(strTemp);
	cout << rs.first << " " << rs.second << endl;
	return 1;
}
上一篇:【前台 】字符串和js对象的相互转化


下一篇:WPF客户端读取高清图片很卡,缩略图解决方案