1. 程式人生 > >將字元陣列:“student a am i”,改為:“i am a student”

將字元陣列:“student a am i”,改為:“i am a student”

問題:有一個字元陣列的內容為:"student a am i",請你將陣列的內容改為"i am a student".

           要求:不能使用庫函式。只能開闢有限個空間(空間個數和字串的長度無關)。 

思路分析:首先,大家會想到我把每個先將整個陣列前後交換,這樣的思考方式就會出現“i ma a tneduts”,這樣的話就會出現單詞的反轉了,我們再讓每個單詞翻轉過來就行了。
    這裡的翻轉在重複的使用,所以我們把翻轉的步驟封裝為一個函式,只要找到翻轉的前面和後面,就可以完成翻轉,所以需要兩個字元指標:*left 和 *right
程式碼實現:

    (1)交換函式:

void reverse(char *left, char *right)
{
	assert(left);	//斷言指標是否為空,如果是空指標就結束,不進行下面步驟
	assert(right);

	while (left < right)	//用於交換的主函式,如果傳來要交換的頭地址和尾地址,就可以完成交換
	{
		char tmp = *left;
		*left = *right;
		*right = tmp;
		left++;
		right--;
	}
}
        圖解:

    (2)交換函式寫完後我們就需要傳址交換了,

        第一步:需完成整個字串的交換,將字串的第一個元素和最後一個字元(\0的前一個字元)地址傳進去,然後實現交換;

        第二步:將每個單詞交換,我們開始可能會想到我手動的將他們每個單詞的地址傳進去,不就實現了嗎?但是電腦的出現不就是為了讓人更加便利嗎?所以我們通過思考會發現,這些單詞的截止處不是‘ ’(空格)就是‘\0’,所以我們以這個為截止,開始將單詞的起始位置記住,進行雙層迴圈是不是就可以實現了呢?

程式碼如下:

void strReverse(char *str, int sz)	
{
	assert(str);
	reverse(str, str + sz - 1);    //用於逆置整個字串
	while (*str != '\0')    //用於逆置每個單詞
	{
		char *p = str;    //記住每一個單詞的起始位置
		while ((*str != ' ') && (*str != '\0'))    //找尋每個單詞的終止位置
		{
			str++;
		}
		reverse(p, str - 1);    //找到空格處,前一個就為單詞的最後一個字母
		if (*str != '\0')
		{
			str++;
		}
	}
}

圖解:



全部程式碼:

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


void reverse(char *start, char *end)	//用於逆序整個字串
{
	assert(start);
	assert(end);
	while (start < end)
	{
		char* tmp = *start;
		*start = *end;
		*end = tmp;
		start++;
		end--;
	}
}

void strReverse(char *str, int sz)	//用於逆序一個單詞
{
	assert(str);
	reverse(str, str + sz - 1);
	while (*str != '\0')
	{
		char *p = str;
		while ((*str != ' ') && (*str != '\0'))
		{
			str++;
		}
		reverse(p, str - 1);
		if (*str != '\0')
		{
			str++;
		}
	}
}

int main()
{
	//1、讓整個語句逆序:i ma a tneduts
	//2、讓每個單詞逆序:i am a student
	char arr[] = "student a am i";
	int sz = strlen(arr);
	strReverse(arr, sz);
	printf("%s\n", arr);
	system("pause");
	return 0;
}