程序员代码面试指南:IT名企算法与数据结构题目最优解-字符串问题:C/C++语言实现

程序员代码面试指南-字符串问题:C/C++语言实现

以下程序运行环境:VC6++

看到左老师出的书:程序员代码面试指南:IT名企算法与数据结构题目最优解,都是Java实现,为了刷题,但是职位是C/C++,以下是我用C/C++实现的代码
题目介绍略简单,以后补上

/*

//程序员代码面试指南-字符串问题

//1.判断两个字符串是否互为变形词

bool isDeformation(string str1,string str2)
{
	if(str1.length() !=str1.length())
		return false;	
	const char *chas1=str1.c_str();
	const char *chas2=str2.c_str();
	int *map = new int[256];//字符的ASC在0-255之间
	for(int i=0;i<str1.length();i++)
		map[chas1[i]]++;//字符对应的asc码值所在的数组数值++
	for(int j=0;j<str2.length();j++)
		if(map[chas2[j]]-- == 0)//先判断再--
			return false;
	return true;
}
int main()
{
	string str1,str2;
	getline(cin,str1);
	getline(cin,str2);
	(isDeformation(str1,str2)==true)? cout<<"yes\n" : cout<<"no\n" ;
	return 0;
}

*/

/*
//2.字符串中数字子串的求和:给定一个字符串,求其中全部数字串所代表的数字之和
//eg:a1cd-2ef33  ==1-2+33=21
int numSum(string str)
{
	const char *str1=str.c_str();
	int num=0;//提取出的当前数字
	int sum=0;//最后的和
	int cur=0;//当前数值
	bool posi=true;
	for(int i=0;i<str.length();i++)
	{
		cur=str1[i]-'0';//转换为数字
		if(cur<0 || cur>9)//不是数字
		{
			sum+=num;//不是数字后计算和
			num=0;
			if(str1[i] == '-')
			{
				if(i-1>-1 && str1[i-1]=='-')//如果前一个也是-则取反
					posi=!posi;
				else
					posi=false;
			}
			else posi=true;//+
		}
		else
		{
			num=num*10+((posi)? cur : -cur );
		}
	}
	sum+=num;//当最后一个字符是数字的话在这里加上,因为sum是在不为数字时候计算的
	return sum;
}
int main()
{
	string str;
	getline(cin,str);
	cout<<numSum(str);
}

*/
/*
//3.去掉字符串中连续出现K个0的子串
string removeKZeros(string str,int k)
{
	 char *str1=new char[str.length()];
	 strcpy(str1,str.c_str());
	int start=-1,count=0;
	for(int i=0;i<str.length();i++)
	{
		if(str1[i]=='0')
		{
			count++;
			start=((start==-1)? i:start);
		}
		else
		{
			if(count==k)
				while(count--!=0)
					str1[start++]=0;
			count=0;
			start=-1;
		}
	}
	if(count==k)//如果最后一个字符是0的情况
		while(count--!=0)
			str1[start++]=0;
	return str=str1;
}
int main()
{
	string str;
	int k;
	cin>>k;
	cin.ignore();//不忽略剩余的回车会导致getline无效
	getline(cin,str);//输入两个回车是因为VC6的bug
	cout<<removeKZeros(str,3);
	return 0;
}

*/
/*
//4.判断两个字符串是否互为旋转词:思路:在b+b中看是否包含a
bool isRotation(string a,string b)
{
	if(a.length()!=b.length())
		return false;
	string b2=b+b;
	return strstr(b2.c_str(),a.c_str())!=NULL;
}
int main()
{
	string a,b;
	getline(cin,a);
	getline(cin,b);
	isRotation(a,b)? cout<<"yes"<<endl : cout<<"no"<<endl;
	return 0;
}

*/
/*
//5.将整数字符串转成整数值:符合日常形式eg"012"不符合,32位不能溢出
//判断是否符合日常形式函数
bool isValid(const char chas[],int len)
{
	if(chas[0] !='-' && (chas[0]<'0' || chas[0]>'9'))//首位不是-和数字不符合
		return false;
	if(chas[0]=='-' && (len==1 || chas[1]=='0'))
		return false;
	if(chas[0]=='0' && len>1)
		return false;
	for(int i=0;i<len;i++)
		if(chas[i]<'0' || chas[i]>'9')
			return false;
	return true;
}
//转换函数
int convert(string str)
{
	const char* chas=str.c_str();
	if(isValid(chas,str.length())!=true)//不符合
		return 0;
	bool posi= chas[0]=='-'? false:true;
	int minq=-(2147483648/10);//下面计算中如果还小于此数就是溢出了
	int minr=-(2147483648%10);//如果等于上数后且余数小于次数就是溢出了,因为都是负数所以才是小于
	int res=0;
	int cur=0;
	for(int i=0;i<str.length();i++)
	{
		cur='0'-chas[i];//负数
		if(res<minq || (res==minq && cur<minr))
			return 0;
		res=res*10+cur;
	}
	if(posi && res==-2147483648)//整数最大是2147483647
		return 0;
	return posi? -res:res;
}
int main()
{
	string str;
	getline(cin,str);
	cout<<convert(str);
	return 0;
}

*/
/*
//6.替换字符串,将str中from替换为to  eg:str=123abc  from=abc  to=4567  返回1234567   str=123abcabc  from=abc to=x 返回123x:只有一个x注意
//想法:将原字符串中from字符替换为0,然后碰到0的地方str相加
string replace(string str,string from,string to)
{
	char *str1=new char[str.length()+1];
	strcpy(str1,str.c_str());
	const char *from1=from.c_str();
	int match=0;
	for(int i=0;i<str.length();i++)//查找from后添0
	{
		if(str1[i]==from1[match++])
		{
			if(match==from.length())//是from
				while(match)
				{
					str1[i-match+1]=0;;
					match--;
				}
		}
		else
		{
			match=0;
		}
	}
	string res="";
	string cur="";
	for(int j=0;j<str.length();j++)//在0的地方补to
	{
		if(str1[j]!=0)
			cur+=str1[j];//一个个的排起来
		if(str1[j]==0 && (j==0 || str1[j-1]!=0))
		{
			res+=cur+to;
			cur="";
		}
	}
	if(cur.c_str()!="")
		res+=cur;//最后一部分
	delete[] str1;
	return res;
}
int main()
{
	string str,from,to;
	getline(cin,str);
	getline(cin,from);
	getline(cin,to);
	cout<<replace(str,from,to);
	return 0;
}

*/
/*
//7.统计字符串eg:aaabbadddffc   a_3_b_2_a_1_d_3_f_2_c_1
#include <sstream>//字符串流,作字符串int转换用的
string getCountString(string str)
{
	const char *str1=str.c_str();
	string res="";
	res+=str1[0];//char转string直接赋值
	stringstream ss;
	string tmp;
	int num=1;
	for(int i=1;i<str.length();i++)
	{
		if(str1[i]!=str1[i-1])
		{
			ss.clear();
			ss<<num;//int转字符串
			ss>>tmp;
			res+="_"+tmp+"_"+str1[i];
			num=1;
		}
		else
			num++;
	}
	ss.clear();
	ss<<num;
	ss>>tmp;
	return res+="_"+tmp;
}
int main()
{
	string str;
	getline(cin,str);
	cout<<getCountString(str);
	return 0;
}

*/
/*
//8.给定一个index返回上题统计字符串中第index个原始字符eg:a_1_b_100  index=50 返回b
char getCharAt(string str,int index)
{
	const char *str1=str.c_str();
	bool stage=true;//当前在遍历字符还是数字标志,true字符
	int num=0,sum=0;
	char cur;
	for(int i=0;i<str.length();i++)
	{
		if(str1[i]=='_')
			stage=!stage;
		else if(stage)
		{
			sum+=num;
			if(sum>index)
				return cur;
			num=0;
			cur=str1[i];
		}
		else num=num*10+str1[i]-'0';
	}
	return sum+num>index ? cur:0;
}
int main()
{
	string str;
	int index;
	cin>>index;
	cin.ignore();
	getline(cin,str);
	cout<<getCharAt(str,index);
	return 0;
}

*/
/*
//9.判断字符数组中是否所有的字符都只出现过一次,未规定空间复杂度
bool isUniquel(const char *buf,int len)
{
	bool map[256]={0};
	for(int i=0;i<len;i++)
	{
		if(map[buf[i]])
		{
			cout<<map[buf[i]];
			return false;
		}
		map[buf[i]]=true;
	}
	return true;
}
int main()
{
	string str;
	getline(cin,str);
	isUniquel(str.c_str(),str.length())==true ? cout<<"true" : cout<<"false";
	return 0;
}

*/
/*
//10.上题中要求空间复杂度为O(1)时间复杂度尽量低
//思路:排序后查找是否大于1,关键在与排序算法的选择,堆排序 O(1)空间,时间O(nlogn)
void HeapAdjust(char a[],int s,int n)
{
	//调整为小根堆,从小到大
	int rc=a[s];
	for(int j=2*s;j<=n;j*=2)
	{
		if(j<n && a[j]>a[j+1])//判断左右子数大小
			j++;
		if(rc<=a[j])
			break;
		a[s]=a[j];
		s=j;
	}
	a[s]=rc;
}
//第一步:建初堆
void CreatHeap(char a[],int n)
{
	//小根堆
	for(int i=n/2;i>0;i--)
		HeapAdjust(a,i,n);
}
//整合
void HeapSort(char a[],int n)
{
	CreatHeap(a,n);//第一步,建立初堆
	for(int i=n;i>1;i--)
	{
		int x=a[1];//堆顶与最后一个元素互换
		a[1]=a[i];
		a[i]=x;
		HeapAdjust(a,1,i-1);
	}


}
//查找方法
bool isUnique2(char a[],int n)
{
	//调用排序算法
	HeapSort(a,n);
	for(int i=1;i<n;i++)
		if(a[i]==a[i-1])
			return false;
	return true;
}
int main()
{
	string str;
	getline(cin,str);
	char *a=new char[str.length()+1];
	strcpy(a,str.c_str());
	cout<<(isUnique2(a,str.length())==true ? "true":"false");
	delete[] a;
	return 0;
}

*/
/*
//11.在从小到大排序但含有null的字符串中查找字符串出现的位置,eg:{a,null,b,c,null,d,c..}中查找c出现最左的位置3
//思路:二分查找,因为是已经有序的了
//下面程序其实不对了:下面意思是从排序但含有空格的字符串中查找字符出现的位置 (空格和NULL不是一回事,空格是' 'asc=32,null是指针其值为0,结束符是'\0'ASC=0)
//所以真正的程序这里应该用字符串数组
int getIndex(string str,char c)
{
	int res=-1;
	int left=0;
	int right=str.length()-1;
	int mid=0;
	int i=0;
	const char *buf=str.c_str();
	while(left<=right)
	{
		mid=(left+right)/2;
		if(buf[mid]!=' ')
		{
			if(buf[mid]==c)//正好就是,不一定是最左,还要在左侧找
			{
				res=mid;
				right=mid-1;
			}
			else if(buf[mid]<c)//在右侧
				left=mid+1;
			else right=mid-1;  //在左侧
		}
		else 
		{
			i=mid;
			while(str[i]==' ' && --i>=left);//依次向左找
			if(i<left || str[i]<c)//如果左侧都是空或者左侧中的最右一个非空字符<c,则从右侧找
				left=mid+1;
			else //在左侧中
			{
				res=(str[i]==c? i:res);
				right=i-1;
			}
		}


	}
	return res;


}
int main()
{
	string str;
	char c;
	getline(cin,str);
	cin>>c;
	cout<<getIndex(str,c);
	return 0;
}

*/
/*
//11.1字符串调整与替换:将空格替换为%20,注意空格是一字节,%20是三字节,数组不能越界
//思路:遍历一遍,看看数组中有多少个字符,多少个空格,然后重新计算替换后的数组长度,从右向左替换转换位置
void replace(char buf[])
{
	int len=0;//buf多少字符
	int num=0;//空格个数
	int size=0;//替换后长度
	for(len=0;buf[len]!='\0';len++)
		if(buf[len]==' ')
			num++;
	size=len+2*num-1;
	for(int i=len-1;i>=0;i--)
	{
		if(buf[i]!=' ')
			buf[size--]=buf[i];
		else {buf[size--]='0';buf[size--]='2';buf[size--]='%';}
	}
}
int main()
{
	string str;
	getline(cin,str);
	char *buf=new char[256];//这里用定长表示的足够大
	strcpy(buf,str.c_str());
	replace(buf);
	cout<<buf;
	delete[] buf;
	return 0;
}

*/
/*
//11.2字符串调整与替换:字符只有数字和*,将所有*移到数字左侧,且不能改变数字之前顺序eg12**45   **1245
//思路:从右往左遍历,是数字就从右到左放,不怕将*覆盖了,没有数字了后将剩下的区域全部复制成*就好了,因为不是数字就是*
void modify(char buf[],int len)
{
	int j=len-1;
	for(int i=j;i>=0;i--)
	{
		if(buf[i]!='*')
			buf[j--]=buf[i];
	}
	while(j>=0)
		buf[j--]='*';
}
int main()
{
	string str;
	getline(cin,str);
	char *buf=new char[str.length()+1];
	strcpy(buf,str.c_str());
	modify(buf,str.length());
	cout<<buf;
	delete[] buf;
	return 0;
}

*/

你可能感兴趣的:(算法,程序员,字符串,cc++,代码面试指南)