2年前去T公司面試,面試官給了我一張紙一支筆,說寫個程序吧,輸入一個字符串然後反序輸出。我問輸入輸出是用函數參數呢還是系統I/O,面試官說隨你便,寫完了說說各有什麼優缺點吧。當時我大三,沒有參加過ACM沒有實驗室經歷除了課程設計也沒寫過什麼程序,完全小白。當然至今也仍然是菜鳥一隻,不堪回首啊。

方法一:據說有庫函數strrev()啊

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
	if (argc != 2)
	{
		printf("Usage: %s string\n\n", argv[0]);
		return -1;
	}
	char* str = argv[1];
	strrev(str);
	printf("Reversed string: %s\n", str);
	return 0;
}

結果Linux下編譯報錯,說找不到strrev()這個函數,我勒個去,坑爹呢這是?VS2010編譯通過正常運行。好吧,還是自己來寫一個吧~

方法二:首尾互換

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <cstring>
using namespace std; 
 
char *reverse(char *str)
{
	int len = strlen(str);
	char *head = str;
	char *tail = str + len - 1;
	while (head &lt; tail)
	{
		char tmp = *head;
		*head++ = *tail;
		*tail-- = tmp;
	}
	return str;
}
int main(int argc, char* argv[])
{
	if (argc != 2)
	{
		cout << "Usage: " << argv[0] << " string" << endl;
		return -1;
	}
	cout << "Reversed string: " << reverse(argv[1]) << endl;
	return 0;
}

終於都通過了啊。就用了個循環把字符串里的字符逐個首尾互換了。啥?性能?有啥問題?沒看到每次進循環都要新建變量tmp嗎?這這這。。。這也有影響?好吧,把這個聲明放到循環外面。還能提升么?去掉字符互換操作!!直接從尾巴倒過來輸出不就得了~

方法三:從尾到頭

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>
using namespace std;
int main()
{
	string str;
	cout << "Input: ";
	cin >> str;
	unsigned int i = str.length();
	cout << "Reversed string: ";
	while(i != 0)
	{
		cout << str[i-1];
		--i;
	}
	cout << endl;
	return 0;
}

這回用了I/O做輸入,並且還能保留原來的字符串不變。嗯,不錯不錯,其實我們連字符串長度都不需要知道。再寫一個~

方法四:遞歸

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;
void reverse(char *str)
{
	if(*str)
		reverse(str+1);
	else
		return;
	cout << *str;
}
int main()
{
	char str[1024] = {NULL};
	cout << "Input: ";
	cin >> str;
	reverse(str);
	cout << endl;
	return 0;
}

估計一般沒人會這麼寫吧。。。