牛客网刷题笔记【1】

1、判断两个字符串是否互为旋转词

例如“1234”

旋转词有“1234”, “2341”, “3412”, “4123”

思路:

1、函数的接口设计

      函数参数:两个字符串的地址

      函数的返回值(int)  1:表示是旋转词  0:表示非旋转词

2、先判断两个字符串的长度是否相等,如果不相等则返回false(0),还有字符指针传进来的有效性检测。

3、如果两个字符串长度相等则将其中一个字符串合并成一个大字符串  str1+str1

4、利用KMP算法判断大字符串是否包含str2

注意事项:1、连接字符串时是连接相同字符串,而不是str1, str2

                     2、用C语言的strcat连接同一个字符串的时候要先将str1的字符copy到另外一个地址空间str3中,然后再连接str1和str3

                           否则同时传入str1会造成地址的覆盖。并且str1的空间要足够大容纳拼接后的字符串

                    3、利用KMP算法的时候传进去字符串的长度是合并成大字符串后的长度。

#include <stdio.h>
#include <string.h>

#define TRUE   1
#define FALSE  0

//next数组的计算
void CalNext(char *str, int *next, int len)
{
	int i;
	int k = -1;
	next[0] = -1;
	for(i=1; i<len; i++)
	{
		while(k>-1 && str[k+1]!=str[i])
		{
			k = next[k];	//回溯
		}
		if(str[k+1] == str[i])
		{
			k = k + 1;
		}
		next[i] = k;
	}
}




int KMP(char *src, int lena, char *dest, int lenb)
{
	//计算next数组(长度与lenb相同)
	int next[lenb];
	CalNext(dest, next, lenb);
	int j = 0;
	int k = -1;
	
	for(j=0; j<lena; j++)
	{
		while(k>-1 && dest[k+1]!=src[j])
		{
			k = next[k];
		}
		if(dest[k+1] == src[j])
		{
			k = k + 1;
		}
		if(k == lenb-1)
		{
			return j-lenb+1;
		}
	}
	
	return -1;
}




char *mystrcat(char *src, char *dest)
{
	if(src==NULL || dest==NULL)
	{
		return src;
	}
	char *temp = src;
	//遍历到src结尾
	while(*src != '\0')
	{
		src++;
	}
	
	while((*src++=*dest++) != '\0');
	
	return temp;
}

char *mystrcpy(const char *src, char *dest)
{
	if(src==NULL || dest==NULL || src==dest)
	{
		return dest;
	}
	char *temp = dest;
	while((*dest++=*src++) != '\0');
	
	return temp;
}

int chRotation(char *str1, int lena, char *str2, int lenb)
{
	//判断指针是否有效和长度是否相等
	if(str1==NULL || str2==NULL || lena!=lenb)
	{
		return FALSE;
	}
	
	//将字符串str1连接成大字符串str1+str1
	char temp[lena+1];
	printf("%s\n", mystrcpy(str1, temp));
	
	mystrcat(str1, temp);
	
	printf("%s\n", str1);
	
	//利用KMP算法查找大字符串是否包含字符串str2
	//printf("%d\n", KMP(str1, lena, str2, lenb));
	//将连接成的大字符串的长度传进去
	if(KMP(str1, strlen(str1), str2, lenb) >= 0)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}


int main(void)
{
	char str1[10] = "1234";
	char str2[] = "4123";
	printf("%d\n", chRotation(str1, strlen(str1), str2, strlen(str2)));
	
	return 0;
}

2、给定一个字符串str,请在单词间做逆序调整

举例:“pig loves dog”  逆序成  “dog loves pig”

思路:

1、实现将字符串局部所有字符逆序的函数fun

2、利用f将字符串所有字符逆序

3、找到逆序后的字符串中每一个单词的区域利用f将每一个单词的区域逆序

关键是:单词用空格隔开,然后利用两个标志来记录每个单词的区间。这个要理解。

#include <stdio.h>

int mystrlen(const char *str)
{
    if(str == NULL)
    {
        return 0;
    }

    int count = 0;
    while(*str++ != '\0')
    {
        count++;
    }

    return count;
}

char *Reverse(char *str, int start, int end)
{
    if(str==NULL || start<0 || end<0)
    {
        retur str;
    }

    char temp;
    while(start < end)
    {
        temp = str[start];
        str[start] = str[end];
        str[end] = temp;
        start++;
        end--;
    }

    return str;
}

void ReverseWord(char *str)
{
    if(str==NULL)
    {
        return;
    }

    int len = mystrlen(str);
    int l = -1, r = -1;
    int i = 0;
    for(i=0; i<len; i++)
    {
        l = (i==0 || str[i-1]==' '? i : l;
        r = (i==length-1 || str[i+1]==' '? i : r;
        if(l!=-1 && r!=-1)
        {
            Reverse(str, l, r);
            l = -1;    
            r = -1;
        }
    }
}

int main(void)
{
    char str[] = "dog loves pig";
    /*先对整个字符串做逆序调整*/
    Reverse(str, 0, mystrlen(str)-1);
    /*再对字符串中的每个单词做逆序调整*/
    ReverseWord(str);
}

三、给定一个字符串str, 和一个整数i, i代表str中的位置,将str[0.....i]移到右侧, str[i+1.....N-1]移到左侧

举例:str  = "ABCDE", i=2, 将str调整为 "DEABC"

思路:

1、将str[0...i]的部分做字符逆序调整

2、将str[i+1...N-1]部分做字符逆序调整

3、将str整体的字符做逆序调整

#include <stdio.h>

int mystrlen(const char *str)
{
    if(str == NULL)
    {
        return 0;
    }

    int count = 0;

    while(*str++ != '\0')
    {
        count++;
    }

    return count;
}

char *Reverse(char *str, int start, int end)
{
    if(str==NULL || start<0 || end<0)
    {
        return str;
    }

    char temp;
    while(start < end)
    {
        temp = str[start];
        str[start] = str[end];
        str[end] = temp;
        start++;
        end--;
    }

    return str;
}

char *StrMove(char *str, int i)
{
    Reverse(str, 0, i);
    Reverse(str, i+1, mystrlen(str)-1);
    Reverse(str, 0, mystrlen(str)-1);
}

int main(void)
{
    char str[] = "ABCDEFG";
    printf("%s\n", StrMove(str));
    return 0;
}

4、给定一个字符串类型的数组strs,找到一种拼接顺序,使得将所有字符串拼接起来组成的大字符串是所有可能性中字典顺序最小的,并返回这个大字符串。

方法:如果str1+str2 < str2+str1则str1放在前面,否则str2放在前面

#include <stdio.h>

int mystrlen(const char *str)
{
	if(str == NULL)
	{
		return 0;
	}
	
	int count = 0;
	while(*str++ != '\0')
	{
		count++;
	}
	
	return count;
}

char *mystrcpy(char *dest, const char *src)
{
	if(dest==NULL || src==NULL || src==dest)
	{
		return dest;
	}
	
	char *temp = dest;
	while((*dest++=*src++) != '\0');
	
	return temp;
}


char *mystrcat(char *str1, const char *str2)
{
	if(str1==NULL || str2==NULL)
	{
		return str1;
	}
	char *temp = str1;
	while(*str1 != '\0')
	{
		str1++;
	}
	//printf("test2\n");
	while((*str1++=*str2++) != '\0');
	//printf("test3\n");
	return temp;
		
}

int mystrcmp(const char *str1, const char *str2)
{
	if(str1==NULL || str2==NULL)
	{
		return -1;
	}
	
	while(*str1!='\0' && *str2!='\0' && *str1==*str2)
	{
		str1++;
		str2++;
	}
	
	return (*str1 - *str2);
}
/*拼接两个字符串,使拼接起来的字符串是所有可能性中字典顺序最小的*/
//第一步:将两个字符串str1+str2拼接
//第二步:将两个字符串str2+str1拼接
//第三步: 然后比较两个拼接后的大字符串,返回小的那个字符串
char *StrSort(char *str1, char *str2)
{
	char temp1[mystrlen(str1)+1];
	char temp2[mystrlen(str2)+1];
	mystrcpy(temp1, str1);
	mystrcpy(temp2, str1);
	//printf("test1\n");
	/*str1+str2*/
	printf("str1+str2 = %s\n", mystrcat(str1, str2));
	
	/*str2+str1*/
	printf("str2+str1 = %s\n", mystrcat(str2, temp1));
	
	return mystrcmp(str1, str2)? str2 : str1;
}


int main(void)
{
	char str1[10] = "bbba";
	char str2[10] = "baab";
	
	printf("%s\n", StrSort(str1, str2));

	return 0;
}



猜你喜欢

转载自blog.csdn.net/wllen_/article/details/81239129