第六章_其他字符串问题

1、第一个只出现一次的字符

在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。

分析:这道题是2006年google 的一道笔试题。它在今年又出现了,不过换了一种形式。即最近的搜狐笔试大题:数组非常长,如何找到第一个只出现一次的数字,说明算法复杂度。

#include<iostream>
#include<cstring>
using namespace std;

char FirstNotRepeatChar(char* cstr)
{
	const int size=256;
	int hashtable[size]={0};
	for(int i=0;cstr[i]!='\0';i++)
	{
		hashtable[cstr[i]]++;
	}
	int j=0;
	while(cstr[j]!='\0')
	{
		if(hashtable[cstr[j]]==1)
		return cstr[j];	
		j++;
	}
	return '\0';	
}
int main()
{
char* cstr="abaccdeff";
char strfirst;
strfirst=FirstNotRepeatChar(cstr);
cout<<cstr<<endl;
cout<<"The First Not Repeat Char is : "<<strfirst<<endl;
return 0;
}


 

2、带通配符的字符串匹配问题

字符串匹配问题:给定一个字符串,按照指定规则对其进行匹配,并将匹配的结果保存至output数组中。多个匹配项用空格间隔,最后一个不需要空格。

要求:

  1. 匹配规则中包含通配符?和*,其中?表示匹配任意一个字符,*表示匹配任意多个(>=0)字符。
  2. 匹配规则要求匹配最大的字符子串,例如a*d,匹配abbdd而非abbd,即最大匹配子串。
  3. 匹配后的输入串不再进行匹配,从当前匹配后的字符串重新匹配其他字符串。

请实现函数:

  char* my_find(char input[], char rule[])

举例说明:

31.1.jpg

注意事项:
 1. 自行实现函数my_find,勿在my_find函数里夹杂输出,且不准用C、C++库,和Java的String对象;
 2. 请注意代码的时间,空间复杂度,及可读性,简洁性;
 3. input=aaa,rule=aa时,返回一个结果aa,即可。

3、对称子字符串的最大长度(参考最大回文长度)

题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。 比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。

分析:可能很多人都写过判断一个字符串是不是对称的函数,这个题目可以看成是该函数的加强版。

4、实现memcpy函数

已知memcpy的函数为: void* memcpy(void dest , const void src , size_t count)其中dest是目的指针,src是源指针。不调用c++/c的memcpy库函数,请编写memcpy。

功能:由src所指内存区域复制count个字节到dest所指内存区域。  

说明:srcdest所指内存区域不能重叠,函数返回指向dest的指针。  

#include<iostream>
#include<cassert>
using namespace std;
void* memcpy(void *dst,const void* scr,size_t count)//内存复制,即一个字节一个字节的复制
{
	assert(dst!=NULL&&scr!=NULL);

	unsigned char* pdst=(unsigned char*)dst;
	unsigned char* pscr=(unsigned char*)scr;
	assert(!(pdst>=pscr&&pdst<pscr+count));
	assert(!(pdst<=pscr&&pdst+count>pscr));

	while(count--)
	{
	*(pdst++)=*(pscr++);
	}

	return dst;
}

int main()
{
char p1[256] = "hello,world!";   
int p2[256] = {0}; 
int* p3=(int*)memcpy(p2,p1,12);
cout<<p1<<endl;
cout<<p2<<endl;
cout<<p3<<endl;

return 0;
}


 

5、实现memmove函数

分析:memmove函数是的标准函数,其作用是把从source开始的num个字符拷贝到destination。
最简单的方法是直接复制,但是由于它们可能存在内存的重叠区,因此可能覆盖了原有数据。 比如当source+count>=dest&&source<dest时,dest可能覆盖了原有source的数据。
解决办法是从后往前拷贝,对于其它情况,则从前往后拷贝。

#include<iostream>
#include<cassert>
using namespace std;
void* memcpy(void *dst,const void* scr,size_t count)//内存复制,即一个字节一个字节的复制
{
	assert(dst!=NULL&&scr!=NULL);
	unsigned char* pdst=(unsigned char*)dst;
	unsigned char* pscr=(unsigned char*)scr;
	if(pdst>=pscr)//反向拷贝
	{
	
		pdst=pdst+count-1;
		pscr=pscr+count-1;
		while(count--)
		{
		*(pdst--)=*(pscr--);
		}	
	
	
	}
	else//正向拷贝
	{
	
		while(count--)
		{
		*(pdst++)=*(pscr++);
		}
	
	
	}
	return dst;
}

int main()
{
char p1[256] = "hello,world!";   
char p2[256] = {0}; 
char* p3=(char*)memcpy(p1+1,p1,5);
cout<<p1<<endl;
cout<<p2<<endl;
cout<<p3<<endl;

return 0;
}


 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值