編程之美一——字符串

    字符串是最常見的面試題目類型,應當分配最大的時間。字符串本身很簡單,但是相關的題目需要更復雜的算法來解決。比如說動態規劃,搜索,等等。

字符串中常用到的函數有(C語言)


#include<string.h>

strlen求字符串長度
strcmp比較2個字符串是否一樣
strcat字符串連接操作
strcpy字符串拷貝操作
strncat字符串連接操作(前n個字符)
strncpy字符串拷貝操作(前n個字符)
strchr 查詢子串
strstr 查詢字串

#include<stdlib.h>
atof
函數原型: double atof(char *str)
函數功能: 將字符串轉換成一個雙精度數值
atoi
函數原型: int atoi(char *str)
函數功能: 將字符串轉換成一個整數值
atol
函數原型: long atol(char *str)
函數功能: 將字符串轉換成一個長整數
itoa
函數原型:char*itoa(int value,char *string,int radix);
功能:將任意類型的數字轉換爲字符串
int value 被轉換的整數,char *string 轉換後儲存的字符數組,int radix 轉換進制數,如2,8,10,16 進制等

memset
void *memset(void *s,int ch,size_t n);
函數解釋:將s中前n個字節 (typedef unsigned int size_t )用 ch 替換並返回 s 。
作用是在一段內存塊中填充某個給定的值,它是對較大的結構體數組進行清零操作的一種最快

面試題一:第一個只出現一次的字符


//解決方案:可以建立一個大小爲256的哈希表,統計每個字符出現的次數
char firstChar(char *pString)
{
	if(pString==NULL)
		return '\0';
	int hashTable[256];
	// memset(hashTable,0,sizeof(hashTable));
	for(int i=0;i<256;i++)
		hashTable[i]=0;

	char *temp=pString;
	while(*temp!='\0')
	{
		hashTable[*temp]++;
		temp++;
	}

	temp=pString;
	while(*pString!='\0')
	{
		if(hashTable[*temp]==1)
			return *temp;
		temp++;
	}
	return '\0';
}

面試題二:輸入兩個字符串,從第一個字符串中刪除第二個字符串中出現過的所有字符

<span style="font-family: Arial, Helvetica, sans-serif;">//在第二個字符中查找,如果是刪除的字符直接在第一個字符中刪掉</span>
//查找可以用哈希表;
//刪除操作最好在O(N)時間內完成;
void deleteChars(char *source,char *deleteStr)
{
	if(source==NULL||deleteStr==NULL)
		return ;
	int hashTable[256];
	memset(hashTable,0,sizeof(hashTable));
	
	char *ptemp = deleteStr;
	
	while(*ptemp!='\0')
	{
		hashTable[*ptemp]=1;
		ptemp++;
	}

	char *pSlow = source;
	char *pFast = source;

	while(*pFast!='\0')
	{
		if(hashTable[*pFast]!=1)
		{
			*pSlow = *pFast;
			++pSlow;
		}
		++pFast;
	}
	*pSlow='\0';
}

面試題三:刪除字符串中重複出現的字符。


//刪除字符串中重複出現的字符
//同上體思路一樣建立哈希表,然後刪除重複字符
void deleteDuplicateChars(char *str)
{
    if(str==NULL)
    return ;

    int hashTable[256];
    memset(hashTable,0,sizeof(hashTable));

    char *temp = str;
    char *delete = str;
    while('\0'!=*temp)
    {
        if(hashTable[*temp]==0)
        {
          hashTable[*temp]=1;
          *delete=*temp;
          delete++;
        }
        temp++;
    }
    *delete='\0';
}

面試題四:字符串的排列


//把字符串分兩部分
//第一部分爲字符串第一個字符
//第二部分爲除了第一個字符外的剩下字符,接下來我們求剩下部分的排列
//拿第一個字符和它後面的字符逐個交換
void Permutation(char *str)
{
	if(str==NULL)
		return ;
	else
		permutation(str,str);
}

void permutation(char *str,char *begin)
{
	if(*begin=='\0')
		printf("%s\n",str);
	else
	{
		for(char *ch=begin;*ch!='\0';++ch)
		{
			char temp=*ch;
			*ch=*begin;
			*begin=temp;
			
			permutation(str,begin+1);

			temp=*ch;
			*ch=*begin;
			*begin=temp;
		}
	}
}

面試題五:將字符串轉換成整數

//寫一個函數將字符串轉換成整數;
//注意考慮空指針,空字符串"",正負號,溢出等測試用例;
//並在寫代碼的時候將對這些特殊的輸入都定義好合理的輸出;
//可以設置一個全局變量,當輸入非法的時候修改全局變量的值;
//最後如果返回值相同,通過檢查全局變量的值來看輸入是否合法;
enum status{inputVaild,inputInvaild}
int strStatus=inputVaild;
int strToInt(const char *str)
{
	strStatus=inputInvaild;
	long long num=0;
	if(str!=NULL&&*str!='\0')
	{
		bool minus = false;
		if(*str=='+')
			str++;
		else if(*str=='-')
		{
			str++;
			minus=true;
		}
			
		if(*str!='\0')
		{
			num = strToIntCore(str,minus);
		}
	}
	return (int)num;
}

long long strToIntCore(const char* digit,bool minus)
{
	long long num=0;
	while(*digit!='\0')
	{
		if(*digit>='0'&&*digit<='9')
		{
			int flag=minus?-1:1;
			num=num*10+flag*(*digit-'0');
			//分兩種情況判斷是否溢出;
			if((!minus&&num>0x7FFFFFFF)||(minus&&num<(signed int)0xB0000000))
			{
				num = 0;
				break;
			}
			digit++;
		}
		//輸出爲0-9以外的字符;
		else
		{
			num=0;
			break;
		}
	}
	if(*digit=='\0')
	{
		strStatus=inputVaild;
	}
	return num;
}

面試題六:將整數轉換成字符串;

<pre name="code" class="cpp">//寫一個函數,將整數轉換成字符串
//整數轉換成字符串可以通過加'0',再逆序的方法。
void intToStr(int n,char s[])
{
	int sign=n;
	char temp;
	//記錄字符串的符號;
	if(sign<0)
		n=-n;
	int i=0,j,k;
	//特殊輸入0時;
	if(n==0)
	{
		s[i]='0';
		return;
	}
	while(n)
	{
		s[i]=n%10+'0';
		i++;
		n=n/10;
	}
	if(sign<0)
		s[i++]='-';
	    s[i]='\0';
	    //將所得字符串逆序;
	for(j=i-1,k=0;j>=k;j--,k++)
		{
			temp=s[j];
			s[j]=s[k];
			s[k]=temp;
		}
}

面試題七:將字符串中的空格替換爲%20

//注意數組從0開始計數;
//注意--和++的使用;
//測試時必須考慮特殊輸入!!!
//要求時間複雜度爲O(n)
void exchangSpace(char string[],int length)
{
	int i=0;
	int newLength = length;
	int newLast;
	if(string==NULL&&length<0)
		return;
//每檢測到一個空格將數組長度增加2
	while(string[i]!='\0')
	{
		if(string[i]==' ')
			newLength += 2;
		i++;
	}
	newLast = newLength ;
	
	if(newLength==length)
		return ;

        length -= 1;
        newLast -= 1;
   //設置兩個指針分別指向新舊字符串的末尾
	while( length >= 0)
	{
		if(string[length]!=' ')
		{
		    string[newLast] = string[length];

		}
		else if(string[length]==' ')
		{
		    string[newLast] = '0';
		    string[--newLast] = '2';
		    string[--newLast] = '%';
		}
		--newLast;
		--length;
	}
}

面試題八:翻轉單詞順序

//輸入一個英文句子,翻轉句子中單詞的順序,單詞中字符的順序不變
//先翻轉句子中的所有字符再翻轉單個單詞
void reverse(char *begin,char *end)
{
	if(begin==NULL||end==NULL)
		return;
	while(begin<end)
	{
		char temp=*begin;
		*begin=*end;
		*end=temp;
		begin++;
		end--;
	}
}

char *reverseSentence(char *str)
{
	if(str==NULL)
		return NULL;
	char *begin=str;
	char *end=str;
	while(*end!='\0')
		end++;
	end--;
    //翻轉整個句子
	reverse(begin,end);

	//翻轉單個單詞
	begin=end=str;
	while(*begin!='\0')
	{
		if(*begin==' ')
		{
			begin++;
			end++;
		}
		else if(*end==' '||*end=='\0')
		{
			reverse(begin,--end);
			begin=++end;
		}
		else
			end++;
	}
	return str;
}

面試題九:刪除字符串中數字並壓縮,要求時間複雜度爲O(N)

//刪除字符串中的數字並壓縮字符串
void deleteNumInStr(char array[],int length)
{
	int i;
	int count =0 ;
	for(i=0;i<=length-1;i++)
	{
		if(array[i]>='0'&& array[i]<='9')
			count++;
		else
			array[i-count] = array[i];
	}
}

面試題十:求兩個串中的第一個最長子串

<span style="font-weight: normal;">//求兩個字符串的第一個最長子串
char *findFirstMaxSubStr(char *str1,char *str2)
{
	if(str1==NULL||str2==NULL)
		return NULL;
	int i,j,k;
	int max=0,index;
	for(i=0;i<strlen(str1);i++)
		for(j=0;j<strlen(str2);j++)
		{
			//連續查找字符是否相同,並記錄最長爲多少個,和在str2中的起始位置
			for(k=0;str1[i+k]==str2[j+k]&&(str1[i+k]||str2[j+k]);k++);
				if(k>max)
				{
					index=j;
					max=k;
				}
		}
		char *strReturn=(char*)malloc(sizeof(char)*(max+1));
		for(i=0;i<max;i++)
			strReturn[i]=str2[index++];
		strReturn[max]='\0';

		return strReturn;
}</span>

面試題十一:實現strstr函數

//實現strstr函數;
//尋找子串在父串中首次出現的位置;
char *strstring(char *str,char *substr)
{
	if(str==NULL||substr==NULL||*substr=='\0')
		return NULL;
	char *tempStr=str;
	char *tempSub;
	char *temp;
	for(;*tempStr!='\0';tempStr++)
	{
		tempSub=substr;
		temp=tempStr;
		while(*tempSub==*temp&&*tempSub!='\0')
		{
			temp++;
			tempSub++;
		}
		if(*tempSub=='\0')
			return tempStr;
	}
	return NULL;
}

面試題十二:不開闢空間反轉字符串

//不開闢空間實現字符串的反轉
void reverse(char *str)
{
	if(str==NULL)
		return;
	for(int i=0,j=strlen(str)-1;i<j;i++,j--)
		str[i]^=str[j]^=str[i]^=str[j];
}



其它簡單的面試題如求迴文串,strcpy函數的實現等。
















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章