【笔试面试】字符串相关操作

/*2015.08.07*/   //未开始
//2015.08.12开始
/************字符串相关操作************
** 1 字符相关函数的使用,memset,memcpy,memcmp;strcmp,strcpy,strlen
** 2 编写string类
** 3 字符串公共子串
** 4 字符串模式匹配 strstr
** 5 两个自字符串的相似度
** 6 字符串转换为整数
** 7 字符串中第一个不重复的字符
** 8 字符串中第一个只出现一次的字符
****************************************/
#include <string>
#include <sstream>
#include <vector>

using namespace std;
 
//求字符串中第一次只出现一次的字符  ===我的方法只需要遍历一次,还有遍历两次的做法
char searchCharFirstOnce(const string & str)
{
	int count[256] = {-1};
	int pos[256]={-1};
	for (int i=0;i<256;++i)
	{
		count[i] = 0;
		pos[i]=-1;
	}
	istringstream fin(str);
	char temp;
	int k=0;
	char result;
	int position = 256;
	while(fin>>temp)//此处实际有问题:未考虑char为负的情况
	{
		++count[temp];
		if (pos[temp]==-1)
			pos[temp] = k++;
	}
	for (int i=0;i<256;++i)
	{
		if (count[i]==1 && pos[i] < position)
		{
			result = i;
			position = pos[i];
		}
	}
	return result;
}

//字符串包含问题,主串和模式串
bool  stringMatch(const string & str1,const string & str2,int & pos)
{
	int i=0,j=0;
	int len1 = str1.size();
	int len2 = str2.size();
	while(i<len1 && j<len2)
	{
		if (str1[i]==str2[j])
		{
			++i;++j;
		}
		else
		{
			i = i-j+1;
			j = 0;
		}
	}
	if (j==len2)
	{
		pos = i-j;
		return true;
	}
		
	else 
		return false;
}

//求一个字符串中出现次数最多的字符,及其次数
char maxAppearChar(const string & str, int & count)
{
	const int dimen = 256;
	int hashChar[dimen];
	for (int i=0;i<dimen;++i)
		hashChar[i] = 0;
	//法一:
	for(unsigned i=0;i<str.size();++i)
		++hashChar[str[i]];
	//法二:和第一题类似,把字符当做一个流,从中读取数据   略
	
	char result = 0;
	count = hashChar[0];
	for(int i=1;i<dimen;++i)
	{
		if (hashChar[i] > count)
		{
			count = hashChar[i];
			result = i;
		}
	}
	return result;
}

//字符交换
//要求交换后,小写字母排在前面,大写字母排在后面
void exchangeChar(string & str)
{
	int i=0;
	int j= str.size()-1;
	int len = str.size();
	while(1)
	{
		while(i<len && str[i]>='a' && str[i]<='z') ++i;
		while(j>=0 && str[j]>='A' && str[j]<='Z') --j;
		if (i<j)
		{
			char temp = str[i];
			str[i] = str[j];
			str[j] = temp;
			++i;--j;
		}
		else
			break;
	}
}

//字符部分排序
int partSort(string & str)
{
	int i=str.size()-1;
	int j= str.size()-1;
	int len = str.size();
	while(1)
	{
		while(j>=0 && str[j]!='*') --j;
		i = j;
		while(i>=0 && str[i]=='*') --i;
			swap(str[i--],str[j--]);
		if(i==-1) break;
	}
	return j+1;
}

//删除字符串中的数字
char * deleteDigits(char * str)
{
	char * result = str;
	char * j = str;
	//while(str)  //此处留意了
	while(*str!=NULL)  //此处留意了
	{
		if (*str>='0' && *str<='9')
		{
			str++;
		}
		else
		{
			*j = *str;
			j++;str++;
		}
	}
	*j='\0';
	return result;
}

//删除特定字符
char * removeChar(char * str,char * remove)
{
	const int dimen = 256;
	char * result = str;
	int hashChar[dimen];
	for(int i=0;i<dimen;++i)
		hashChar[i] =0;
	for (int i=0;remove[i];++i)
		hashChar[remove[i]]=1;
	int k=0;
	for (int i=0;str[i];++i)
	{
		if (!hashChar[str[i]])
		{
			//continue;
			result[k++] = str[i];
		}
// 		else
// 		{
// 			result[k++] = str[i];
// 		}
	}
	result[k]='\0';
	return result;
}

//编写字符串与整数和浮点数互相转换的函数   考点:考察各种特殊情况
//字符串转换为整数,考虑正负号
bool  str2int(const string & str,int &result)
{
	//int flag = true;
	if (!str.size())
	{
		//flag = false;
		return false;
	}
	char temp;
	int symbol = 1;
	result =0;
	istringstream fin(str);
	fin>>temp;
	if (temp=='-')
	{
		symbol = 0;
	}
	else if(temp>='0' && temp<='9')
	{
		result = temp-'0';
	}
	while(fin>>temp)
	{
		if (temp>='0' && temp<='9')
		{
			result = result*10 + temp-'0';
		}
		else
		{
			//flag = false;
			return false;
		}
	}
	if (!symbol)
	{
		result = 0 - result;
	}
	return true;
}

//整型转换为字符串
void int2str(int num,string & str)
{
	if (!num)
	{
		return ;
	}
	int2str(num/10,str);
	str = str+(char)('0'+num%10);
}
string int2str(int num)
{
	string str="";
	if (!num)
	{
		str = str+'0';
		return str;
	}
	int symbol =1;
	if (num < 0)
	{
		symbol =0;
		num = -num;
		str = str+ '-';
	}
	
	int2str(num,str);
	return str;
}

//翻转句子中单词的顺序
void reverse(string & str,int i,int j)
{
	while(i<j)
		swap(str[i++],str[j--]);
}
void reverseStr(string & str)
{
	int i=0,j=0;
	int len = str.size();
	while(j<len)
	{
		while(i<len && str[i]==' ') ++i;
		j = i;
		while(j<len && str[j]!=' ') ++j;//左开右闭区间
		reverse(str,i,j-1);
		i = j;
	}
	reverse(str,0,len-1);
}

//求两个字符串的最长公共子串 DP解法  //特点:子串连续
int maxLengthSubString(string & str1,string & str2)
{
	int len1 = str1.size();
	int len2 = str2.size();
	vector<vector<int>> subNum;
	subNum.resize(len1+1);
	for (int i=0;i<len1+1;++i)
		subNum[i].resize(len2+1);
	for (int i=0;i<len1+1;++i)
		subNum[i][0]=0;
	for (int i=0;i<len2+1;++i)
		subNum[0][i]=0;
	for(int i=1;i<len1+1;++i)
	{
		for (int j=1;j<len2+1;++j)
		{
			if (str1[i-1] == str2[j-1])
			{
				subNum[i][j] = subNum[i-1][j-1]+1;
			}
			else subNum[i][j] = 0;
		}
	}
	//ceshi
// 	for (int i=0;i<len1+1;++i)
// 	{
// 		for (int j=0;j<len2+1;++j)
// 		{
// 			cout<<subNum[i][j]<<" ";
// 		}
// 		cout<<endl;
// 	}

	int maxN =0;
	int end = 0;
	for (int i=1;i<len1+1;++i)
	{
		for(int j=1;j<len2+1;++j)
		{
			if (subNum[i][j] > maxN)
			{
				maxN = subNum[i][j];
				end = j;
			}
		}

		
	}
	cout<<str1<<"和"<<str2<<"的最长公共子串是:"<<ends;
	for (int i=end-maxN;i<end;++i)
	{
		cout<<str2[i];
	}
	cout<<endl;
	return maxN;
}

//找出字符串的最长子串,要求子串所有字符相同
string maxContinueSubStr(const string &str)
{
	//char result;
	int pos =0;
	int count=1;
	int maxK=0;
	for (unsigned i=1;i<str.size();++i)
	{
		if (str[i]==str[i-1])
		{
			count++;
			if (count>maxK)
			{
				maxK = count;
				pos = i;
			}
		}
		else
			count =1;
	}
	cout<<"最长连续相同字符的子串长度为"<<maxK<<",子串为";
	string str1="";
	while(maxK--)
	{
		str1 = str1 + str[pos];
	}
	cout<<str1<<endl;
	return str1;
}


//删除字符串中重复的字符---保留第一次出现的
char * deleteRepeatChar(char * str)
{
	char * temp = str;
	const int demen = 256;
	int hashChar[demen];
	for (int i=0;i<demen;++i)
		hashChar[i] =0;
	char * result = str;
	while(*str!=NULL)
	{
		if (!hashChar[*str])
		{
			hashChar[*str] = 1;
			*result++ = *str++;
		}
		else
			str++;
	}
	*result  = '\0';
	return temp;
}

//输出一个字符串的字符的全部排列
//回溯一把
bool isValidChr(const string & str,vector<char> & strchr,int pos)
{
	for(unsigned i=0;i<str.size();++i)
	{
		if (strchr[i]==str[pos])
		{
			return false;
		}
	}
	return true;
	
}

void backTraking(const string & str,vector<char> & strChr,int pos,int & count)
{
	if (pos == str.size())
	{
		for (unsigned i=0;i<strChr.size();++i)
		{
			cout<<strChr[i]<<" ";  
		}
		cout<<endl;

		count ++;

		strChr[pos-1] = '*';
		return;
	}
	for (unsigned i=0;i<str.size();++i)
	{
		if (isValidChr(str,strChr,i))
		{
			strChr[pos] = str[i];
			//break;
			backTraking(str,strChr,pos+1,count);
		}
	}
	if (strChr[pos]=='*')
	{
		if (pos==0)
		{
			return;
		}
		strChr[pos-1] = '*';
	}

}

void backTraking(const string & str)
{
	vector<char> strChr;
	strChr.resize(str.size());
	for (unsigned i=0;i<strChr.size();++i)
	{
		strChr[i] = '*';
	}
	int len = str.size();
	int count =0;
	backTraking(str,strChr,0,count);
}

//求字符串的最长重复子串

//求字符串的最长的没有重复字符的子串

//求字符串中连续出现字数最多的子串

//求包含字符集合的最短的子串





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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值