天天看点

c/c++整理--字符串(3)一、编程实现字符串中各单词的翻转二、编程判断字符串是否为回文三、编程实现strcmp库函数四、编程实现查找两个字符串的最大公共子串

一、编程实现字符串中各单词的翻转

编写函数实现“I am from Shanghai”倒置为“Shanghai from am I”,即句子中的单词倒置,而不改变单词内部的结构。

#include <stdio.h>
#include <string.h>
#define N 20

void change(char* src)
{
	char static ret[N];
	int i = 0, len = 0;
	while(*src)
	{
		len++;
		src++;
	}
	while(i < len)
	{
		ret[i] = *(--src);
		i++;
	}
	ret[i] = '\0';
	for(i = 0; i < len; i++)		
	{
		src[i] = ret[i];
	}
}

void Revstr(char* src)
{
	char* res = src;
	char* q = src;
	while(*res != '\0')
	{
		if(*res == ' ')
		{
			*res = '\0';
			change(q);
			*res = ' ';
			q = res+1;
		}
		res++;
	}
	change(q);
}

int main()
{
	char p[] = "I am from Shanghai";
	Revstr(p);
	change(p);
	printf("%s\n", p);
	
	return 0;
}
           

  这道题我想了两种方法,其实也是差不多的,1、先将原始字符串的首地址赋给两个指针res、q,一个指针q留在第一位不动,另一个指针res往后遍历,知道遇到了空格,将空格改为‘\0’,然后将q地址传入一个专用于字符串逆序的函数,然后依次遍历逆序,到最后一位的时候跳出循环,这个时候再次逆序,这样就成功的把单词翻转了。 2、第二种方法也是差不多,就是现将字符串整个翻转,再对其中的单词依次翻转,方法和上面类似。

输出:

I am from Shanghai
Shanghai from am I
           

二、编程判断字符串是否为回文

判断一个字符串是否是回文,例如单词‘level’

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

#define YES 1
#define NO  0

int judge(char* str)
{
	if(str == NULL)
	{
		return NO;
	}
	int len = strlen(str);
	char* p = str;
	char* q = str;
	while(*p++);
	p -= 2;
	for(; str != '\0', p != q; str++, p--)
	{
		if(*str != *p)
		{
			return NO;
		}
	}
	return YES;
}

int main()
{
	char str1[] = "12321";
	char str2[] = "12345";
	
	if(judge(str1))
	{
		printf("12321是回文\n");
	}
	else
	{
		printf("12321不是回文\n");
	}
	
	if(judge(str2))
	{
		printf("12345是回文\n");
	}
	else
	{
		printf("12345不是回文\n");
	}
	
	return 0;
}
           

这题的方法也是比较简单的,将字符串的首尾比较,如果每一对都相等,那么就是回文,否则非回文。 输出:

12321是回文
12345是回文
           

三、编程实现strcmp库函数

#include <stdio.h>

#define GREATER 1
#define EQUAL   0
#define LESS   -1

int mystrcmp(char* str1, char* str2)
{
	if(str1 == NULL || str2 == NULL)
	{
		return -2;
	}
	for(; *str1 != '\0', *str2 != '\0'; str1++, str2++)
	{
		if(*str1 > *str2)
		{
			return GREATER;
		}
		else if(*str1 < *str2)
		{
			return LESS;
		}
	}
	return EQUAL;
}

int main()
{
	char str1[] = "abcdef";
	char str2[] = "abcdef";
	char str3[] = "abcdgh";
	
	printf("%d\n", mystrcmp(str1, str2));
	printf("%d\n", mystrcmp(str1, str3));
	
	return 0;
}
           

这里编写了一个mystrcmp函数,来模仿库函数strcmp,实现两字符串的比较功能,若相等,返回0,若str1大于str2,返回1,若str1小于str2,返回-1。

四、编程实现查找两个字符串的最大公共子串

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

#define GREATER 1
#define EQUAL   0
#define LESS   -1

char* my_strstr(char* str1, char* str2)  
{  
    const char* bp;  
    const char* sp;  
    if(str1 == NULL || str2 == NULL)  
    {  
        return str1;  
    }  
    while(*str1)  
    {  
        bp = str1;		              	//用于str1的遍历  
        sp = str2;			            //用于str2的遍历  
        while(*bp++ == *sp++)	        //遍历str2字符串  
        {  
            if(*sp == '\0')	            //找到了str2字符串结束符退出  
            {  
                return str1;  
            }  
        }  
        str1++;  
    }  
	return NULL;
}  

char* mycomstring(char* str1, char* str2)
{
	if(str1 == NULL || str2 == NULL)  
    {  
        return str1;  
    }  
	char* shortstr;
	char* longstr;
	char* substr;
	int i, j;
	if(strlen(str1) <= strlen(str2))
	{
		shortstr = str1;
		longstr = str2;
	}
	else
	{
		shortstr = str2;
		longstr = str1;
	}
	
	if(my_strstr(longstr, shortstr) != NULL)
	{
		return shortstr;
	}
	
	substr = (char*)malloc(sizeof(char)*(strlen(shortstr) + 1));
	
	for(i = strlen(shortstr)-1; i>0; i--)
	{
		for(j = 0; j <= strlen(shortstr)-i; j++)
		{
			memcpy(substr, &shortstr[j], i);
			substr[i] = '\0';
			if(my_strstr(longstr, substr) != NULL)
			{
				return substr;
			}
		}
	}
	return NULL;
}

int main()
{
	char str1[] = "aocdfe";
	char str2[] = "pmcdfa";
	
	printf("%s\n", mycomstring(str1, str2));
	
	return 0;
}
           

这道题,我没有用库函数strstr,而是用的之前的my_strstr函数,对两个字符串进行逐一排查。首先如果一个字符串是另一个字符串的子串,那么短的那个肯定是最大公共子串了,另一种情况就是对短字符串进行排查,在长字符串中进行查找。 输出:

cfd
           

继续阅读