天天看點

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
           

繼續閱讀