主頁 > 軟體設計 > C語言習題積累(正在更新)

C語言習題積累(正在更新)

2021-09-15 10:32:28 軟體設計

文章目錄

      • 作業題積累
        • 1判斷閏年
          • 題目
          • 答案
          • 決議
        • 2最大公約數和最小公倍數
          • 題目
          • 答案
          • 決議
        • 3分數求和
          • 題目
          • 答案
          • 決議
        • 4二分查找
          • 題目
          • 答案
          • 決議
        • 5字串逆序
          • 題目
          • 答案
          • 決議
            • 代碼邏輯
        • 6進制轉換
          • 題目
          • 答案
          • 決議
        • 7冒泡排序
          • 題目
          • 答案
          • 決議
        • 8陣列操作
          • 題目
          • 答案
          • 決議
        • 9列印二進制奇數偶數位
          • 題目
          • 答案
          • 決議
        • 10交換兩個變數
          • 題目
          • 答案
          • 決議
        • 11統計二進制中1的個數
          • 題目
          • 答案
          • 決議
        • 12計算求和
          • 題目
          • 答案
          • 決議
        • 13自冪數
          • 題目
          • 答案
          • 決議
        • 14字串逆序
          • 題目
          • 答案
          • 決議
        • 15喝汽水問題
          • 題目
          • 答案
          • 決議
        • 16程式解釋
          • 題目
          • 答案
          • 決議
        • 17調整奇偶順序
          • 題目
          • 答案
          • 決議
        • 18楊輝三角
          • 題目
          • 答案
          • 決議
        • 19猜兇手
          • 題目
          • 答案
          • 決議
        • 20程式解釋
          • 題目
          • 答案
          • 決議
        • 21猜名次
          • 題目
          • 答案
          • 決議
        • 22楊氏矩陣
          • 題目
          • 答案
          • 決議
        • 23模擬`qsort`
          • 題目
          • 答案
          • 決議
        • 24字串左旋
          • 題目
          • 答案
          • 決議
        • 25檢查字串旋轉結果
          • 題目
          • 答案
          • 決議

作業題積累

1判斷閏年

題目

判斷閏年函式,

答案
int main() {
	int i = 0;
	int leapyear = 0;
	for (i = 1000; i <= 1900; i++) {
        if ((i % 400 == 0) || (i % 4 == 0 && i % 100 != 0)) {
			printf("%d ", i);
		}
	}
	return 0;
}
int is_leap_year(int year) {
	return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
}
決議

閏年分為普通閏年和世紀閏年,其判斷方法為:

  1. 普通閏年:年份是4的倍數,且不是100的倍數,y%4==0&&y%100!=0
  2. 世紀閏年:年份是整百數,且必須是400的倍數,y%400==0

若將萬年內,設可整除4年的為 S A S_A SA?,可整除100年的為 S B S_B SB?,可整除400年的為 S C S_C SC?

利用這張圖,閏年 S S S 可表示為 S A + S C S_A+S_C SA?+SC?

四年一閏,百年不閏,四百年再閏,

2最大公約數和最小公倍數

題目

求出最大公因數和最小公倍數,

答案
//1.遍歷元素,暴力求解
int main() {
	int num1 = 0;
	int num2 = 0;
	scanf("%d %d", &num1, &num2);
	int min = num1 < num2 ? num1 : num2;
	int max = num1 < num2 ? num2 : num1;
	//遍歷元素
	for (int i = min; i > 0; i--) {
		if (num1 % i == 0 && num2 % i == 0) {
            printf("%d", i);
			break;
		}
	}
    for(int i = max; i > 0; i++) {
        if(i % num1 == 0 && i % num2 == 0) {
            printf("%d\n", i);
            break;
        }
    }
	return 0;
}

//2.輾轉相除法
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d%d", &a, &b);
	int tmp = a * b;
	int c = 0;
	while (c = a % b) {
		a = b;
		b = c;
	}
	//最大公約數
	printf("%d\n", b);
	//最小公倍數
	printf("%d\n", tmp / b);
	return 0;
}
//1.更相減損法
#include <math.h>
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	if (a % 2 == 0 && a > 2) {
		a /= 2;
	}
	if (b % 2 == 0 && b > 2) {
		b /= 2;
	}
	if (a < b) {
		int tmp = a;
		a = b;
		b = tmp;
	}
	int tmp = a - b;
	while (b != tmp) {
		tmp = abs(tmp - b);
	}
	printf("%d\n", b);
	return 0;
}
決議
  • 最小公倍數比二者都大,最大公約數比二者都小,找最小公倍數則從二者中較大的向后遍歷,最大公約數是從最小值前前遍歷,
  • 輾轉相除法
    • 在二者之模不為0的情況下,除數賦給被除數,模賦給除數,再執行整數除法直至模為0時,除數為最大公約數,初始二者數值乘積除以最大公約數即為最小公倍數,
  • 更相減損法
    • 若二者能整除2則除,不可的話,那么用大數減去小數,互相減來減去,一直到減數與差相等為止,此時所得即最大公約數,

3分數求和

題目

計算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值,列印出結果,

答案
int main()
{
    int num = 100;
    double flg = 1.0;
    double sum = 0;
    for (int Den = 1; Den <= num; Den++) {
        //1.
        double pro = flg / (Den / 1.0);//小數能影響除法
        //2.
        double pro = flg / Den;
        sum += pro;
        flg = -flg;
    }
    printf("%lf\n", sum);
	return 0;
}
決議

注意只有一個小數參與除法運算才可以觸發小數除法,故第二中直接把分子定義為浮點數,通過取負得到±1,

4二分查找

題目

二分查找,在一個有序整型陣列中查找某個數字,

答案
int main() {
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr)/sizeof(arr[0]);
    int key = 0;
    scanf("%d", &key);
    int left = 0;
    int right = sz - 1;
    while(left <= right) {
        int mid = (left + right) / 2;
        if (arr[mid] > key) {
            right = mid - 1;
        }
        else if (arr[mid] < key) {
            left = mid + 1;
        }
        else {
            printf("找到了下標為%d\n", mid);
        }  
    } 
    if (left > right) {
        printf("找不到\n");
    }
    return 0;
}
決議

通過下標訪問元素進行對比,從中間開始,臨界條件是左下標小于右下標,當然折半法僅限有序陣列,

5字串逆序

題目

撰寫一個函式 reverse(char* str),用遞回的方式實作:將引數字串中的字符反向排列,不是逆序列印,
要求:不能使用C函式庫中的字串操作函式,
例如:char arr[] = "abcdef";,逆序之后陣列內容變成:fedcba

答案
void reverse_string3(char* ch)//遞回
{
	char* left = ch;
	char* right = ch + strlen(ch) - 1;

	if (*ch != '\0')
	{
		char tmp = *left;//提取
		*left = *right;//賦值
		*right = '\0';//賦\0

		reverse_string3(ch+1);//ch+1,而不是ch++

		*right = tmp;//賦值
	}
}
決議

abcdef

遞推:(先把后面賦值給前面,后面用覆寫\0)

$ \Rightarrow$ f b c d e \0

? \Rightarrow ? f e c \0\0

? \Rightarrow ? f e d \0\0\0

回歸:(把前面轉移出去的字符對應賦值給\0)

$ \Rightarrow$ f e d c \0\0

? \Rightarrow ? f e d c b \0

? \Rightarrow ? f e d c b a

代碼邏輯

reverse(“abcdef\0”)

交換a和f+reverse(“f bcde\0\0”)

交換a和f+交換b和e+reverse(“fe cd\0\0\0”)

交換a和f+交換b和e+交換c和d+reverse(“fed \0\0\0\0”)

  • 交換兩個字符
    1. 將在前的字符先放到一邊存著
    2. 把在后的字符賦值到前面的位置
    3. 再把后面的位置對應覆寫為\0
  • 原在前字符替換\0
    1. 把事先存好的在前的字符對應替換到\0的位置上

6進制轉換

題目

將一個十進制數轉換成二進制并列印二進制序列的每一位,

答案
void Bin(n)
{
	if (n / 2 != 0)
	{
		Bin(n / 2);
	}
	printf("%d", n % 2);
}
決議

10進制數轉換成二進制數,這是一個連續除2的程序:

  1. 把要轉換的數,除以2,得到商和余數,
  2. 將商繼續除以2,直到商為0,

最后將所有余數倒序排列,得到數就是轉換結果,

7冒泡排序

題目

有一個無序的整型陣列,使用冒泡排序的方法使其按升序或降序的方式排序,

答案
int BubbleSort() {
    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    for (int i = 0; i < sz - 1; i--) {
        for (int j = 0; j < sz - 1 - i; j++) {
            if (arr[j] < arr[j + 1]) {
               int tmp  = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
}
決議

冒泡排序的核心思想是相鄰兩數相比,可以抽象為一個比較函式,

基本思路是比較 n ? 1 n-1 n?1 趟,每趟比較 n ? 1 ? i n-1-i n?1?i 次,

因為外回圈結束一次排序完一個數,使其來到其最終位置上,內回圈一次使其與未經和其比較的數進行比較,并在滿足條件的情況下進行交換,所以每次減i

8陣列操作

題目

實作reverse()函式完成陣列元素的逆置,

答案
void reverse(int arr[], int sz)
{
	int left = 0;
	int right = sz - 1;
	while (left < right)
	{
		int tmp = arr[left];
		arr[left] = arr[right];
		arr[right] = tmp;
		left++;
		right--;
	}
}
決議

通過下標訪問陣列元素從左向右依次進行交換,這種逆序整型陣列也可以逆序字串,都是一樣的字串也可以通過下標訪問,

9列印二進制奇數偶數位

題目

輸入一個整數,分別列印其二進制序列的奇數位和偶數位,

答案
int main() {
	int n = 0;
    int i = 0;
	scanf("%d", &n);
	printf("奇數位:");
	for (i = 30; i >= 0; i -= 2) {
		printf("%d ", (n >> i) & 1);
	}
	printf("\n偶數位:");
	for (i = 31; i >= 1; i -= 2) {
		printf("%d ", (n >> i) & 1);
	}
	return 0;
}
決議

回圈遍歷二進制序列中的每一位,讓每一位右移上i位都有機會來到最后一位和整數1按位與,這樣得到的數也只能10,這樣就相當于變相得到二進制序列的每一位,由于要區分奇數位和偶數位且按照順序列印,故要從后往前遍歷,

10交換兩個變數

題目

不創建臨時變數的條件下,交換兩個整型變數,

答案
int main()
{
	int a = 10;
	int b = 20;
	printf("a=%d,b=%d\n", a, b);
	//1.
	a = a + b;
	b = a - b;
	a = a - b;

	//2.
    //(a^b)^a=b (a^b)^b=a
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;

	printf("a=%d,b=%d\n", a, b);
	return 0;
}
決議

不創建臨時變數來交換兩個整數資料,

  • 通過賦值的方法,把a+b賦值給a,此時a已經等于a+b,再將a-b賦值給b,這樣b就等于原來的a,再用a-b,這樣就得到了b再賦值給a,這樣a,b就完成了交換,
  • 通過按位異或的方法,按位異或的特點是,相同為0,相異為1,這樣就會導致一個結果(a^b)^a=b(a^b)^b=a,這樣的話把a^b的結果再與b異或然后賦值給b,再將a^b,也就是(a^b)^a=b賦值給a

但二者都有局限,前者的大小受限,a+b加起來不可以大于一個整型不然就會溢位,后者因按位運算子僅是由于整型,故后者也受限于變數型別為整型,

11統計二進制中1的個數

題目

輸入一個整數,統計其二進制序列中1的個數,

答案
  1. 方法1
int Return_Number_1(int n)
{
	int i = 0;
	int count = 0;
	for (i = 0; i < 32; i++)
	{
		if (((n >> i) & 1) == 1)
		{
			count++;
		}
	}
	return count;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	printf("%d\n", Return_Number_1(n));

	return 0;
}
  1. 方法2
int main()
{
	int n = 0;
	int count = 0;
	scanf("%d", &n);
	while (n) {
		n = n & (n - 1);
		count++;
	}
	printf("%d\n", count);

	return 0;
}

決議

如圖所示我們用n&(n-1)作為計數器的條件,可以發現n&(n-1)的結果比n的二進制序列少一個1,再將結果賦值給n,就可以依靠回圈來實作計數器,

12計算求和

題目

S n = a + a a + a a a + a a a a + a a a a a Sn = a + aa + aaa + aaaa + aaaaa Sn=a+aa+aaa+aaaa+aaaaa 的前5項之和,其中 a a a 是一個數字,例如: 2 + 22 + 222 + 2222 + 22222 2 + 22 + 222 + 2222 + 22222 2+22+222+2222+22222

答案

第一種思路:

2 = 2*10^0
22 = 2*10^1 + 2
222 = 2*10^2 + 22
2222 = 2*10^3 + 222 
22222 = 2*10^4 + 2222
22222 = 2*10^4 + 2222

第二種思路:

2 = 2 + 0
22 = 2 * 10 + 2
222 = 22 * 10 + 2
2222 = 222 * 10 + 2
22222 = 2222 * 10 + 2
#include <math.h>
int main()
{
	int a = 0;
	scanf("%d", &a);
	int sum = 0;
	int ret = 0;
	for (int i = 0; i < 5; i++) {
		//1.
        ret += a * (int)pow(10, i);
		//2.
        ret = ret * 10 + a;
		sum += ret;
	}
	printf("%d\n", sum);
	return 0;
}

第三種方法:

#include <math.h>
int main()
{
	int a = 0;
	int n = 0;
	int sum = 0;
	scanf("%d %d", &a, &n);
	while (n) {
		int i = n;
		int ite = 0;
		while (i) {
			ite += a * pow(10, i - 1);
			i--;
		}
		sum += ite;
		n--;
	}
	printf("%d\n", sum);
	return 0;
}
決議
  • 第一種是把 a a a 看作 a × 1 0 0 a×10^0 a×100 a a aa aa 看成 a × 1 0 1 + a × 1 0 0 a×10^1+a×10^0 a×101+a×100 ……

  • 第二種每次在前一次運算的結果上乘10并加上2,

  • 第三種是可以規定位數,

13自冪數

題目

求出0~100000之間的所有“水仙花數”并輸出,
“水仙花數”是指一個n位數,其各位數字的n次方之和確好等于該數本身,如: 153 = 1 3 + 5 3 + 3 3 153=1^3+5^3+3^3 153=13+53+33
則153是一個“水仙花數”,

答案
#include<math.h>
int main() {
	for (int i = 0; i < 10000; i++) {
		//1. 求位數
		int n = 1;
		int num = i;
		while (num /= 10) {
			n++;
		}
		//2. 求每項和
		int sum = 0;
		num = i;
		while (num) {
			sum += (int)pow((num % 10), n);
			num /= 10;
		}
		//3. 判斷
		if (sum == i) {
			printf("%d\n", i);
		}
	}
	return 0;
}
決議

求自冪數需要三步,1求出該數的位數2求每項和3.判斷是否相等,每次做出改變i動作時,要把i賦值給臨時變數以免在回圈內改變臨時變數,

14字串逆序

題目

現有一字串i am a student,將其全部逆序得tneduts a ma i

進階版:將其單詞外逆序,單詞內順序不變,得:student a am i

答案
#include <string.h>
char* reverse(char* arr) {
	int len = strlen(arr);
	char* left = arr;
	char* right = arr + len - 1;
	while (left < right) {
		char tmp = *left;
		*left = *right;
		*right = tmp;
		left++;
		right--;
	}
	return arr;
}
int main()
{
	char arr[] = "i am a student";
	reverse(arr);
	printf("%s\n", arr);
	return 0;
}

進階版:

char* reverse(char* left, char* right) {
	while (left < right) {
		char tmp = *left;
		*left = *right;
		*right = tmp;
		left++;
		right--;
	}
	return left;
}
char* move(char* arr) {
	int len = strlen(arr);
	reverse(arr, arr + len - 1);
	reverse(arr, arr + 6);
	reverse(arr + 8, arr + 8);
	reverse(arr + 10, arr + 11);
	reverse(arr + 13, arr + 13);
	return arr;

}
//tneduts a ma i
//01234567890123
int main()
{
	char arr[] = "i am a student";
	move(arr);
	printf("%s\n", arr);
	return 0;
}
決議

把所有單詞都可視為字符,故逆序字串即可,進階版只需要將全部逆序后的結果數清每個字符的下標位置,并單獨在逆序就可以了,

15喝汽水問題

題目

喝汽水,1瓶汽水1元,2個空瓶可以換一瓶汽水,給20元,可以多少汽水,

答案
//喝汽水
int main()
{
	int money = 20;
	//買的
	int total = money;
	int empty = money;
	//換的
	while (empty > 1) {
		total += empty / 2;
		empty = empty / 2 + empty % 2;
	}
	printf("%d\n", total);


	return 0;
}
決議

喝到的汽水可以分為兩種,一種是買來的一種是換來的,首先花已有的錢買來的一元一瓶故先total等于money,

然后計算換來的,定義空瓶數,兩個空瓶換一瓶,故total等于empty/2,empty執行整數除法,故empty等于不僅要/2還要%2,奇數瓶還會剩下奇數瓶,

16程式解釋

題目

請解釋下列代碼的運行結果和問題原因,

#include <stdio.h>
int main()
{
	int i = 0;
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	for (i = 0; i <= 12; i++)
	{
		arr[i] = 0;
		printf("hello bit\n");
	}
	return 0;
}
答案

決議

陣列其后第三塊空間正好被編譯器用來放置存盤下標的變數,故每次到這里都會清零,就重新開始了,每個編譯器的位置不一樣,這個屬于編譯器的自我優化,不是我們可以改變的,且在release版本會優化掉這個問題,

17調整奇偶順序

題目

調整陣列使奇數全部都位于偶數前面,
輸入一個整數陣列,調整該陣列中數字的順序,使得陣列中所有的奇數位于陣列的前半部分,所有偶數位于陣列的后半部分,

答案
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int* pl = arr;
	int* pr = &arr[sz - 1];
	while (pl < pr) {
		while (*pl % 2 == 1) {
			pl++;
		}
		while (*pr % 2 == 0) {
			pr--;
		}
		if (pl < pr) {
			int tmp = *pl;
			*pl = *pr;
			*pr = tmp;
		}
	}
	for (int i = 0; i < sz; i++) {
		printf("%d ", arr[i]);
	}
	return 0;
}
決議

plpr不可以同時加減,在前面用pl尋找奇數,后面用pr尋找偶數,找到之后再兩者交換,

18楊輝三角

題目

列印如圖所示的資料三角形,

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1

列印楊輝三角菱形形式,

    1
   1 1
  1 2 1
 1 3 3 1
1 4 6 4 1
答案
int main()
{
	int n = 0;
	scanf("%d", &n);
	int arr[20][20] = { 0 };
	arr[1][1] = 1;
	for (int i = 2; i <= n; i++) {
		for (int j = 1; j <= i; j++) {
			arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];//規律
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= i; j++) {
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}

進階版:

int main()
{
	int arr[10][10] = { 0 };
	for (int i = 0; i < 10; i++) {
		for (int j = 0; j <= i; j++) {
			//初始化
			arr[i][0] = arr[i][i] = 1;
			//計算
			if (i >= 2 && j >= 1) {
				arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
			}
			//列印
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	for (int i = 0; i < 10; i++) {
		for (int j = 0; j < 10; j++) {
			if (j < 9 - i) {
				printf(" ");
			}
			else {
				printf("%d ", arr[i][j - 9 + i]);
			}
		}
		printf("\n");
	}
	return 0;
}
決議

首先楊輝三角的規律為 a r r [ i ] [ j ] = a r r [ i ? 1 ] [ j ? 1 ] + a r r [ i ? 1 ] [ j ] arr[i][j] = arr[i-1][j-1]+arr[i-1][j] arr[i][j]=arr[i?1][j?1]+arr[i?1][j]

  • 第一種初始化時是從第2行第2列初始化,將arr[1][1]置為1,
  • 第二種是將第1列和對角線初始化為1,然后從第3行第2列開始初始化,

19猜兇手

題目

日本某地發生了一件謀殺案,警察通過排查確定殺人兇手必為4個嫌疑犯的一個,以下為4個嫌疑犯的供詞:
A說:不是我,
B說:是C,
C說:是D,
D說:C在胡說
已知3個人說了真話,1個人說的是假話,
現在請根據這些資訊,寫一個程式來確定到底誰是兇手,

答案
int main()
{
	int kill = 0;
	//列舉法,一一列舉
	for (kill = 'A'; kill <= 'D'; kill++) {
		//利用運算式回傳值特點,直觀
		if ((kill != 'A') +
			(kill == 'C') + 
			(kill == 'D') + 
			(kill != 'D') == 3) {
			printf("%c\n", kill);
			break;
		}
	}
	return 0;
}
決議

定義killer變數,將是與不是轉化為關于killer變數的關系運算,因為只有ABCD每人一個條件故只要一個回圈即可,三人真話,一人假話,故所有條件運算式相加的結果應為3,在killer假設條件正確時,

20程式解釋

題目

求代碼中strlen(a)的結果,并解釋清楚原因,

int main()
{
	char a[1000] = { 0 };
	int i = 0;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	printf("%d", strlen(a));
	return 0;
}
答案

255

決議

strlen(a)的值,也就是求a[i]=0的時候,i為多少,準確的來說應該是-1-i等于多少,因為陣列a為字符元素陣列,故當-1-i的尾七位二進制補碼為全1的時候,由于存入陣列時發生截斷故存入的是0,

21猜名次

題目

5位運動員參加了10米臺跳水比賽,有人讓他們預測比賽結果:
A選手說:B第二,我第三;
B選手說:我第二,E第四;
C選手說:我第一,D第二;
D選手說:C最后,我第三;
E選手說:我第四,A第一;
比賽結束后,每位選手都說對了一半,請編程確定比賽的名次,

答案
int main()
{
	int a = 0;
	int b = 0;
	int c = 0;
	int d = 0;
	int e = 0;
	for (a = 1; a <= 5; a++) {
		for (b = 1; b <= 5; b++) {
			for (c = 1; c <= 5; c++) {
				for (d = 1; d <= 5; d++) {
					for (e = 1; e <= 5; e++) {
						//回圈5^5次
						//判斷條件1.
						//if ((b == 2) + (a == 3) +
						//	(b == 2) + (e == 4) +
						//	(c == 1) + (d == 2) +
						//	(c == 5) + (d == 3) +
						//	(e == 4) + (a == 1) == 5) {
						//判斷條件2.
						if (((b == 2) + (a == 3) == 1) &&
							((b == 2) + (e == 4) == 1) &&
							((c == 1) + (d == 2) == 1) &&
							((c == 5) + (d == 3) == 1) &&
							((e == 4) + (a == 1) == 1)) {
							if (a * b * c * d * e == 120) {//1*2*3*4*5=120
								printf("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e);
								goto again;
								return 0;
							}
						}
					}
				}
			}
		}
	}
again:
}
決議

找兇手的題目兇手只有一個,猜名次必須要排序,所以要有5個回圈,每個回圈判斷一個選手的名次,同樣是把所有人的話作為一個條件,限制條件是每個人只有半句是對的,所以是兩個條件加起來是1,最后要取出排名重復的情況,

22楊氏矩陣

題目

有一個數字矩陣,矩陣的每行從左到右是遞增的,矩陣從上到下是遞增的,
請撰寫程式在這樣的矩陣中查找某個數字是否存在,
要求:時間復雜度小于O(N);

答案
void find_key(int(*pa)[3], int* px, int* py, int k) {
	int x = *px;
	int y = *py;
	while (x < 3 && y >= 0) {
		if (pa[x][y] > k) {
			y--;
		}
		else if (pa[x][y] < k) {
			x++;
		}
		else {
			printf("(%d,%d)\n", x, y);
			return;
		}
	}
	printf("NO\n");

}

int main() {
	int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
	int key = 7;
	int x = 0;
	int y = 2;
	find_key(arr, &x, &y, key);

	return 0;
}
決議

因為所謂楊氏矩陣的定義就是該矩陣從左向右遞增從上到下遞增,不一定是按照某種順序,同時要求時間復雜度不超過 O ( N = n 2 ) O(N=n^2) O(N=n2),所以不可以遍歷,所以從矩陣的特點入手,從矩陣的右上角入手,該數字是該行的最大值,又是該列的最小值,這樣就可以通過大小比較來控制行和列,

23模擬qsort

題目

模擬實作my_qsort函式,并排序整型陣列,

答案
//列印函式
Print(int* arr, int sz) {
	for (int i = 0; i < sz; i++) {
		printf("%d ", arr[i]);
	}
	putchar(10);
}

//比較函式
int cmp(const void* e1, const void* e2) {
	return *(int*)e1 - *(int*)e2;
}
//交換函式
void Swap(char* buf1, char* buf2, size_t width) {
	for (size_t i = 0; i < width; i++) {
		char tmp = *(buf1 + i);
		*(buf1 + i) = *(buf2 + i);
		*(buf2 + i) = tmp;
	}
}
//模擬實作qsort
void my_qsort(void* base, size_t num, size_t width, int(*cmp)(const void*, const void*)) {
	for (size_t i = 0; i < num; i++) {
		for (size_t j = 0; j < num - i - 1; j++) {
			if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) {
				Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
			}
		}
	}
}
int main() {
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_qsort(arr, sz, sizeof(arr[0]), cmp);
	Print(arr, sz);
	return 0;
}
決議

排序函式的要素:起始位置,元素大小,元素寬度以及比較函式,比較函式中要內嵌交換函式,

24字串左旋

題目

實作一個函式,可以左旋字串中的k個字符,
例如:ABCD左旋一個字符得到BCDA,ABCD左旋兩個字符得到CDAB,

答案
  1. 第一種方案
#include <string.h>
#include <assert.h>
char* left_hand(char* arr, int k) {
	assert(arr);
	int len = strlen(arr);
	//0. 判斷次數
	k %= len;
	while (k) {
		//1. 提取第一個字符
		char tmp = arr[0];
		//2. 后面的字符向前移動一位

		for (int i = 1; i < len; i++) {
			arr[i - 1] = arr[i];
		}
		//3. 插入最后一個字符
		arr[len - 1] = tmp;
		k--;
	}
	//4. 回傳字串地址
	return arr;
}
int main() {
	char arr[] = "ABCD";
	int k = 2;
	printf("%s\n", left_hand(arr, k));

	return 0;
}
  1. 第二種方案
//AB CDEF
//BA FECD
//CD EFAB
char* reverse(char* left,char* right) {
	char* begin = left;
	while (left <= right) {
		char tmp = *left;
		*left = *right;
		*right = tmp;
		left++;
		right--;
	}
	return begin;
}
char* hand(char* arr, int k) {
	int len = strlen(arr);
	reverse(arr, arr + k - 1);
	reverse(arr + k, arr + len - 1);
	reverse(arr, arr + len - 1);
}
int main()
{
	char arr[] = "ABCDEF";
	int k = 2;
	hand(arr, k);
	printf("%s\n", arr);
	return 0;
}
決議
  • 第一種是每次左旋一個字符,再回圈k次,左旋的邏輯是提取字符然后剩余元素前移一位最后字符放入最后位置,
  • 第二種是確定左旋字符個數后,先分別逆序前后兩個字串,再將整個字串逆序,

25檢查字串旋轉結果

題目

寫一個函式,判斷一個字串是否為另外一個字串旋轉之后的字串,
例如:給定s1 = AABCDs2 = BCDAA,回傳1;給定s1 = ABCDs2 = ACBD,回傳0,
AABCD左旋一個字符得到ABCDA
AABCD左旋兩個字符得到BCDAA
AABCD右旋一個字符得到DAABC

答案
  1. 第一種方案
#include <string.h>
#include <assert.h>
int check_hand(char* s1, char* s2) {
	assert(s1 && s2);
	int len1 = strlen(s1);
	int len2 = strlen(s2);
	if (len1 != len2) {
		return 0;
	}
	else {
		for (int k = 0; k < len2; k++) {
			if (strcmp(left_hand(s1, 1), s2) == 0) {
				return 1;
			}
		}
		return 0;
	}
}
int  main()
{
	char s1[] = "AABCD";
	char s2[] = "DAABC";
	int ret = check_hand(s1, s2);
	printf("%d\n", ret);
	return 0;
}
  1. 第二種方案
#include <string.h>
int check_by_add(char* s1, char* s2) {
	assert(s1 && s2);
	int len = strlen(s1);
	char* ps = strncat(s1, s1, len);
	if ((size_t)len != strlen(ps)) { 
		return 0;
	}
	else {
		if (strstr(ps, s1)) {
			return 1;
		}
		else
			return 0;
	}
}
//AABCD AABCD
int main()
{
	char s1[20] = "AABCD";
	char s2[20] = "DAABC";
	if (check_by_add(s1, s2)) {
		printf("Yes\n");
	}
	else {
		printf("No\n");
	}
	return 0;
}
決議
  • 第一種是將需判斷字串與源字串所有旋轉的結果進行比較,同樣右旋k個字符也就等于左旋n-k個字符,

  • 第二種是字串最后追加一個源字串,這樣任意旋轉后的結果字串必然是該字串的子字串,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/300292.html

標籤:其他

上一篇:《重學Java高并發》你管這“破玩意兒”叫鎖(沒有高并發經驗的朋友們看過來,該專欄結合筆者的實戰來講高并發)

下一篇:??萬字【Python基礎】保姆式教學??,小白快速入門Python!

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more