將字元陣列:“student a am i”,改為:“i am a student”
阿新 • • 發佈:2018-11-07
問題:有一個字元陣列的內容為:"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;
}