FizzBuzz

實際運行時頭文件:vs2013

#if _MSC_VER
#define snprintf _snprintf
#endif
#pragma warning(disable: 4996)


方法一:

char** fizzBuzz(int n, int* returnSize) {
	int i;
	char **ret;
	char *buf;
	ret = (char **)calloc(1, n * sizeof(char **));//兩次分配內存
	for (i = 0; i < n; i++)
		ret[i] = (char *)calloc(1, 16 * sizeof(char *));//內存
	for (i = 0; i < n; i++) {
		if ((i + 1) % 15 == 0) {
			ret[i] = strdup("FizzBuzz");
		}
		else if ((i + 1) % 3 == 0) {
			ret[i] = strdup("Fizz");
		}
		else if ((i + 1) % 5 == 0) {
			ret[i] = strdup("Buzz");
		}
		else {
			snprintf(ret[i], 31, "%d", i + 1);
		}
	}


	*returnSize = n;
	return ret;
}

學會三個知識點:

一:malloc和calloc

它們都是動態分配內存,先看看它們的原型:

void *malloc( size_t size ); //分配的大小

void *calloc( size_t numElements, size_t sizeOfElement ); // 分配元素的個數和每個元素的大小

共同點就是:它們返回的是 void * 類型,也就是說如果我們要爲int或者其他類型的數據分配空間必須顯式強制轉換

不同點是:用malloc分配存儲空間時,必須由我們計算需要的字節數。如果想要分配5個int型的空間,那就是說需要5*sizeof(int)的內存空間:

int * ip_a;
ip_a = (int*)malloc( sizeof (int) * 5 );

而用calloc就不需要這麼計算了,直接:
ip_a = ( int* )calloc( 5, sizeof(int) );這樣,就分配了相應的空間,而他們之間最大的區別就是:用malloc只分配空間不初始化,也就是依然保留着這段內存裏的數據,而calloc則進行了初始化,calloc分配的空間全部初始化爲0,這樣就避免了可能的一些數據錯誤。

二:strdup函數

原型:
extern char *strdup(char *s);
頭文件:string.h
說明:
功 能: 將串拷貝到新建的位置處
strdup()在內部調用了malloc()爲變量分配內存,不需要使用返回的字符串時,需要用free()釋放相應的內存空間,否則會造成內存泄漏。
返回值:編輯
返回一個指針,指向爲複製字符串分配的空間;如果分配空間失敗,則返回NULL值。

三:snprintf函數

函數原型:int snprintf(char *str, size_t size, const char *format, ...)

功能:
將可變個參數(...)按照format格式化成字符串,然後將其複製到str中
(1) 如果格式化後的字符串長度 < size,則將此字符串全部複製到str中,並給其後添加一個字符串結束符('\0');
(2) 如果格式化後的字符串長度 >= size,則只將其中的(size-1)個字符複製到str中,並給其後添加一個字符串結束符('\0'),返回值爲欲寫入的字符串長度

方法二:

char** fizzBuzz(int n, int* returnSize) {
	*returnSize = n;
	char buf[11];
	char** p = (char**)malloc(sizeof(char*)*n);
	int i = 0;
	for (i = 0; i<n; i++)
	{
		if ((i+1)%15==0)
		{
			sprintf(buf, "%s", "FizzBuzz");
		}
		else if ((i + 1) % 3 == 0){
			sprintf(buf, "%s", "Fizz");
		}
		else if ((i + 1) % 5 == 0){
			sprintf(buf, "%s", "Buzz");
		}
		else{
			sprintf(buf, "%d", i + 1);
		}
		p[i] =(char *) malloc(sizeof(buf));//也要分配內存
		memcpy(p[i], buf, strlen(buf) + 1);
		//memset(buf,0, 11);
	}

	return p;
}
學會一個知識點:

sprintf函數

功能
把格式化的數據寫入某個字符串緩衝區。
頭文件
stdio.h
原型
int sprintf( char *buffer, const char *format, [ argument] … );
參數列表
buffer:char型指針,指向將要寫入的字符串的緩衝區。
format:格式化字符串。
[argument]...:可選參數,可以是任何類型的數據。
返回值
返回寫入buffer 的字符數,出錯則返回-1. 如果 buffer 或 format 是空指針,且不出錯而繼續,函數將返回-1,並且 errno 會被設置爲 EINVAL。

sprintf和snprintf區別:

snprintf最多從源串中複製size-1 個字符到目標串中,然後再後面加一個\0,sprintf沒有這樣的限制,使用snprintf更安全。
sprintf使用注意事項
(1)多個字符串連接,sprintf(s,"%.Ms %.Ns",a1,a2);其中M N 是正整數,分別指定複製a1中的M個字符,a2中N個字符輸出到s中
(2)一定要申請較大的數組空間,避免出現堆棧的溢出,破壞堆棧
snprintf使用注意事項
(1)snprintf最多從源串中複製size-1 個字符到目標串中,返回值是源串字符的個數,而不是複製字符的個數
snprintf(buf,sizeof(buf),......)

方法三:

char** fizzBuzz(int n, int* returnSize) {
	char **s;
	s = (char **)malloc(n * sizeof(char*));
	char temp[1024];//足夠大內存
	for (int i = 0; i < n; i++){
		if ((i + 1) % 3 && (i + 1) % 5){
			sprintf(temp, "%d", i + 1);
			s[i] = (char *)malloc(strlen(temp) + 1);
			strcpy(s[i], temp);
		}
		if ((i + 1) % 15 == 0){
			s[i] = (char *)malloc(strlen("FizzBuzz") + 1);
			strcpy(s[i], "FizzBuzz");
		}
		else if ((i + 1) % 3 == 0){
			s[i] = (char *)malloc(strlen("Fizz") + 1);
			strcpy(s[i], "Fizz");
		}
		else if ((i + 1) % 5 == 0){
			s[i] = (char *)malloc(strlen("Buzz") + 1);
			strcpy(s[i], "Buzz");
		}
	}
	*returnSize = n;
	return s;
}
運行時間一樣

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章