C和指針 第六章 習題

6。1編寫一個函數,它在一個字符串中進行搜索,查找全部在一個給定字符集中出現的字符,返回第一個找到的字符位置指針,未找到返回NULL數組

#include <stdio.h>

char * find_char(char const *source, char const *chars)
{
	char const *sptr = source;
	char const *cptr = chars;

	if (sptr == NULL || cptr == NULL) {
		return NULL;
	}

	while (*sptr != '\0') {
		cptr = chars;
		while (*cptr != '\0') {
			if (*cptr == *sptr) {
                   //找到打印source地址 printf("chars:0x%p\n", chars); //返回類型爲 char *,此處類型轉換一下把char const *轉換回來 return (char *)cptr; } cptr++; } sptr++; } return NULL; }

 

#include <stdio.h>
#include "function.h"

int main()
{
	char *source = "ABCDEF";
	char *str1 = "XYZ";
	char *str2 = "XRCQEF";
	char *chars = str1;
	char *ptr = NULL;
        //沒有對應的字符
	ptr = find_char(source, chars);
	printf("0x%p\n", ptr);
        //對應的字符C,第三個
	chars = str2;
	ptr = find_char(source, chars);
	printf("0x%p\n", ptr);

	while (1)
		;
	return 0;
}

  執行結果:函數

 

6.2刪除字符串中子串部分,將剩下部分前移。指針

int del_substr(char *str, char const *substr)
{
	if (str == NULL || substr == NULL) {
		return 0;
	}
       //將數組首位賦值給指針數組
	char *source = str;
	char *sub = substr;
	char *tmp = NULL;

	while (*source != '\0') {
		//將指針重置指向子串首
		sub = substr;
		//使用臨時變量進行對比,保持source位置信息不變
		tmp = source;
		//當遇到相同的字符,開始比較以後是否相同
		while (*tmp++ == *sub++) {
			//循環中已經sub++了,到達末尾,證實找到子串,開始前移
			if (*sub == '\0') {
				//未到達字符串末尾,繼續前移
				while (*(tmp + 1) != '\0') {
					*source = *tmp;
				}
				return 1;
			}
		}
		source++;
	}
	return 0;
}

 

int main()
{
	char *source = "ABCDEF";
	char *str1 = "CGE";
	char *str2 = "CDE";
	int isDel;
        //無子串
	isDel = del_substr(source, str1);
	printf("del_substr: %d\n", isDel);
        //有子串
	isDel = del_substr(source, str2);
	printf("del_substr: %d\n", isDel);

	while (1)
		;
	return 0;
}

執行結果:blog

6.3 編寫函數reverse_string,翻轉字符串。字符串

void reverse_string(char *string)
{
	//先定義兩個指針,一個指向首一個指向末尾
	char *head = string;
	//string自己指向第一位,加上字符串長度後是指向\0後的,因此須要前移,指向最後一個字符
	char *tail = string + strlen(string) - 1;
	char tmp;

	//同一數組內能夠進行指針位置對比
	while (head < tail) {
		tmp = *head;
		*head = *tail;
		*tail = tmp;
		head++;
		tail--;
	}
}

int main()
{
	char source[] = "ABCDEF";
	printf("source: %s\n", source);

	reverse_string(source);
	printf("result: %s\n", source);

	return 0;
}

  執行結果:string

6.4 Eratosthenes法找質數,第一步寫下2至某個上線之間的全部的數,第二步開始剔除不是質數的整數,找到列表第一個不被剔除的數(就是2)而後將表後面全部逢雙的數都剔除,由於均可以被2整除,因此不是質數,而後回到表頭,此時表頭還沒有被剔除的是三,而後每逢三位剔除,反覆進行最後都是質數。it

void find_primer(int *numbers, int length)
{
        //0 1 不爲質數
	numbers[0] = FALSE;
	numbers[1] = FALSE;

	int tmp;
	int loc;
	int index = 2;

	while (index < length) {
		tmp = index;                
                //當前頭部找到的質數,和後面的數相乘的結果對應的位置所有不是質數。
		while ( (tmp += index) < length) {
			*(numbers + tmp) = FALSE;
		}
		index++;
	}

}

 

int main()
{
	int numbers[10000];
	for (int index = 0; index < 10000; index++) {
		numbers[index] = TRUE;
	}

	find_primer(numbers, 10000);

	for (int index = 0; index < 10000; index++) {
		if (numbers[index]) {
			printf("%-08d", index);
		}
	}

	return 0;
}

  運行結果:io

 

 6.5利用第五章的位數組求質數function

位數組:class

//字符偏移
unsigned int char_offset(unsigned bit_number)
{
	return bit_number / CHAR_BIT;
}

//bit位偏移
unsigned int bit_offset(unsigned bit_number)
{
	return bit_number % CHAR_BIT;
}

void set_bit(char bit_array[], unsigned bit_number)
{
	bit_array[char_offset(bit_number)] |= 1 << bit_offset(bit_number);
}

void clear_bit(char bit_array[], unsigned bit_number)
{
	bit_array[char_offset(bit_number)] &= ~(1 << bit_offset(bit_number));
}

void assign_bit(char bit_array[], unsigned bit_number, int value)
{
	if (value != 0) {
		set_bit(bit_array, bit_number);
	}
	else {
		clear_bit(bit_array, bit_number);
	}
}

int test_bit(char bit_array[], unsigned bit_number)
{
	//對該bit位進行與操做,若是是1則結果仍是 1<< (bit_number % CHAR_BIT)
	return (bit_array[char_offset(bit_number)] & (1 << bit_offset(bit_number))) != 0;
}

位數組求質數:

void find_primer_bit(char bit_array[], unsigned long int length)
{
	clear_bit(bit_array, 0);
	clear_bit(bit_array, 1);

	unsigned int tmp;
	unsigned int loc;
	unsigned int index = 2;

	while (index < length) {
		tmp = index;
		//沒逢index位置0
		while ( (tmp += index) < length) {
			clear_bit(bit_array, tmp);
		}
		index++;
	}
}

 

#define MAX_LEN 1000000
#define MAX_ARR_SIZE (MAX_LEN / 8)

int main()
{
	char bit_array[MAX_ARR_SIZE];
	unsigned int count = 0;
	unsigned int index = 0;
	unsigned int total = 0;
	while (index < MAX_ARR_SIZE) {
		bit_array[index++] = 0xff;
	}

	find_primer_bit(bit_array, MAX_LEN);

	index = 1;
	while (index < MAX_LEN) {
		if (test_bit(bit_array, index)) {
			total++;
			printf("%-8d", index);
		}
		index++;
	}

	printf("\n共計: %d 個質數 \n", total);

	return 0;
}

  

執行結果

檢測一下是否正確:

 

1000000萬內有78498個質數

6.6計算每隔1000位質數個數:

統計一下每隔100000的質數

#define MAX_LEN 1000000
#define MAX_ARR_SIZE (MAX_LEN / 8)
int main()
{
	char bit_array[MAX_ARR_SIZE];
	unsigned int count = 0;
	unsigned int index = 0;
	unsigned int total = 0;
	unsigned int limit = 100000;
	while (index < MAX_ARR_SIZE) {
		bit_array[index++] = 0xff;
	}
	find_primer_bit(bit_array, MAX_LEN);

	index = 0;
	while (index < MAX_LEN) {
		if (index == limit) {
			printf("%-6d %-6d avg: %5.2f\n", index - 100000, index, (float)count / 100);
			count = 0;
			limit += 100000;
		}
		if (test_bit(bit_array, index)) {
			count++;
			total++;
		}
		index++;
	}

	printf("\n共計: %d 個質數 \n", total);
	while (1)
		;
	return 0;
}

  

  

相關文章
相關標籤/搜索