一、程式設計實作字元串中各單詞的翻轉
編寫函數實作“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