1. 用篩選法求100之內(nèi)的素數(shù)
解析:這題的關(guān)鍵是要知道什么是篩選法用解析法設(shè)計程序,篩選法。
int main()
{
int i = 0, j = 0;
int arr[100];
//錄入數(shù)字
for (i = 0; i < 100; i++)
{
arr[i] = i + 1;
}
//1不是素數(shù),直接寫0,或者在上一步就把0寫進(jìn)去。
arr[0] = 0;
//這一步是實(shí)現(xiàn)篩選法
//篩選法實(shí)際上就是用后面的數(shù)字整除當(dāng)前數(shù)字
//如果后面的數(shù)字能夠整除當(dāng)前值,則將其排除
//按照這樣的步驟以次繼續(xù),直至到達(dá)范圍邊緣
for (i = 0; i < 100; i++)
{
for (j = i + 1; j < 100; j++)
{
//這個if要注意,在第一輪篩選的時候已經(jīng)把很多數(shù)字寫0
if (arr[j] != 0 && arr[i] != 0)
{
//如果后面的數(shù)字可以整除當(dāng)前值
//說明后面的數(shù)字肯定不是素數(shù)
//我這里說的整除和取模是一樣的,都是余數(shù)為0
if (arr[j] % arr[i] == 0)
{
arr[j] = 0;
}
}
}
}
//打印篩選后的數(shù)字
for (i = 0; i < 100; i++)
{
if (arr[i] != 0)
{
printf("%d ", arr[i]);
}
}
return 0;
}
運(yùn)行結(jié)果:
2. 用選擇法對10個整數(shù)排序
解析:問題來了啥是選擇法呢?選擇排序法。
簡單來說就是把最小值或者最大值標(biāo)記出來,當(dāng)比較結(jié)束后把標(biāo)記值和首位(或者末位)做交換,通過多輪比較,排出想要的順序。
//打印
void print(int* arr,int sz)
{
for (int i = 0; i <= sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int i, j, pos;
int arr[] = { 2,8,3,9,5,7,1,4,0,6 };
int sz = sizeof(arr) / sizeof(arr[0])-1;
print(&arr,sz);//這是自定義的打印函數(shù),不是printf!!!
for (i = 0; i <= sz; i++)
{
pos = 0;//將標(biāo)記置于第一位
for (j = 1; j <= sz-i; j++)//比較位從第二位開始,sz-i是為了讓范圍縮小
{
if (arr[j] > arr[pos])
{
pos = j;//如果比較值比標(biāo)記值大,便將比較值坐標(biāo)賦值給標(biāo)記坐標(biāo)
}
}
if (pos != sz-i)//比較完成后判斷標(biāo)記坐標(biāo)是不是在邊界
{
int temp = arr[pos];
arr[pos] = arr[sz-i];
arr[sz-i] = temp;
}
}
print(&arr, sizeof(arr) / sizeof(arr[0]) - 1);//sz已經(jīng)被改變了,要重新計算
return 0;
}
既然可以把最大值篩選出來,就可以把最小值篩選出來,如果兩個一起進(jìn)行效率會大很多。
3. 求一個3 X 3的整形矩陣對角線元素之和
解析:創(chuàng)建矩陣和創(chuàng)建數(shù)組是一樣的,像這一題要創(chuàng)建3x3的整形矩陣,可以這樣操作int arr[3][3];先行后列很簡單。
int main()
{
int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
int i, j;
int right_sum = 0, left_sum = 0;
for (i = 0; i <= 2; i++)
{
for (j = 0; j <= 2; j++)
{
if (i == j)
{
left_sum += arr[i][j];
}
if (i == 2 - j)
{
right_sum += arr[i][j];
}
}

}
printf("左對角線的數(shù)值為%d\n", left_sum);
printf("右對角線的數(shù)值為%d\n", right_sum);
return 0;
}
運(yùn)行結(jié)果:
4. 有一個已經(jīng)排好序的數(shù)組,要求輸入一個數(shù)后,按原來順序的規(guī)律將它插入數(shù)組中
解析:這個題目有一種簡單又粗暴的辦法:把插入的數(shù)字放在數(shù)組末端,然后再做一次排序。
但是我覺得這個方法不好,我們應(yīng)該換一個思路:首先我們將插入的數(shù)字和數(shù)組相比較,如果插入的數(shù)字比原來數(shù)組的數(shù)字小,就把數(shù)組數(shù)字的角標(biāo)給定位下來,并把原來數(shù)組數(shù)字向后挪一位。
int main()
{
int i, j;
int arr[10] = {1,2,3,4,5,6,7,8,9};
int input = 0;
int end = 8;//數(shù)組最后一位數(shù)字的角標(biāo)就是8
printf("請輸入要插入的數(shù)據(jù):>");
scanf("%d", &input);
printf("當(dāng)前排列情況:>");
for (i = 0; i < 9; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
//如果插入的數(shù)字比原來數(shù)組的數(shù)字小
//就把數(shù)組數(shù)字的角標(biāo)給定位下來,并把原來數(shù)組數(shù)字向后挪一位。
while (end >= 0 && input < arr[end])
{
arr[end + 1] = arr[end];
end--;
}
arr[end + 1] = input;
printf("插入排列情況:>");
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
printf("\n ");
return 0;
}
運(yùn)行結(jié)果:
5. 將一個數(shù)組中的值按逆序重新存放。例如:原來順序為8,6,5,4,1。要求改為1,4,5,6,8。
解析:這一題較上一題就簡單多了,可以用簡單的方法也可以用復(fù)雜的方法。
復(fù)雜的方法就是重新排序,十種排序方法你隨便選擇;
簡單的方法就是數(shù)值交換:數(shù)組左右交換,當(dāng)左坐標(biāo)大于等于右坐標(biāo)時停止;
int main()
{
//vs用的時C99標(biāo)準(zhǔn),數(shù)組的定義必須為常量
//如果用支持C11標(biāo)準(zhǔn)的編譯器,這里可以用變量定義,實(shí)現(xiàn)靈活定義數(shù)組
int arr[] = { 8,6,5,4,1 };
//這個sz隨意,可以自己寫數(shù)值,不一定要計算
int sz = sizeof(arr) / sizeof(arr[0]);
int left = 0, right = sz - 1;
//打印
printf("初始序列:>");
for (int i = 0; i < sz ; i++)
{
printf("%d ",arr[i]);
}
printf("\n");
//重新排序
//數(shù)組左右交換,當(dāng)左坐標(biāo)大于等于右坐標(biāo)時停止
while (left < right)
{
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
//打印
printf("重排序列:>");
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
運(yùn)行結(jié)果:
6. 輸出以下的楊輝三角(要求輸出10行)
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
……
解析:這題的關(guān)鍵在于知道什么是楊輝三角,楊輝三角的規(guī)律是什么。不知道還不點(diǎn)楊輝三角?解楊輝三角有幾種方法:
暴力解法:直接找規(guī)律挨個計算并打印出來。(不推薦,效率奇低)
創(chuàng)建數(shù)組:上面給的打印示例不好看出規(guī)律,我們把他排序看看,如下圖。
從這幅圖中我們可以得到一些信息:
每個數(shù)等于它上方兩數(shù)之和。
每行數(shù)字左右對稱,由1開始逐漸變大。
第n行的數(shù)字有n項。
前n行共[(1+n)n]/2 個數(shù)。
好,根據(jù)以上信息我們可以開始寫代碼了。
#define N 10
int main()
{
int i, j;
int arr[N][N];
printf("1\n");//第一行直接打印
//把邊界賦值為1
for (i = 1; i < N; i++)

{
arr[i][0] = 1;
j = i;
arr[i][j] = 1;
}
int aim = N;
for (i = 1; i < N; i++)
{
printf("1\t");//第一個1直接打印
for (j = 1; j < i; j++)
{
arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
printf("%d\t",arr[i][j]);
}
printf("1\n");//最后一個1直接打印并換行
}
return 0;
}
運(yùn)行結(jié)果:
這種是簡單粗暴的寫法,只針對這一題,通用性不佳,而且打印出的結(jié)果沒有空格美化。
我們可以做一些簡單的美化工作讓他好看點(diǎn)戳這里!‘
7. 輸出"魔方陣"。所謂魔方陣是指這樣的方陣,它的每一行、每一列和對角線之和均相等。
解析:找出一個二維數(shù)組中的鞍點(diǎn),即該位置上的元素在該行上最大,在該列上最小,也可能沒有鞍點(diǎn)。
鞍點(diǎn)是行上最大,列上最小的元素,因此對數(shù)組的第i元素進(jìn)行如下操作:
1、找到該行上最大元素,用max標(biāo)記,并標(biāo)記該元素所在列
2、找列上最小的元素,用min標(biāo)記,并標(biāo)記該元素所在行號
3、如果max和min相等,并且最小的元素剛好是在第i行,則為鞍點(diǎn)
4、如果所有行找完了,沒有輸出則沒有鞍點(diǎn)
#define ROW 3
#define COL 3
int main()
{
int i, j,max,min,flag = 0;
int arr[ROW][COL];
int rowindex = 0, colindex = 0;//尋找最大值的坐標(biāo)
for (int i = 0; i <= ROW - 1; i++)
{
for (int j = 0; j <= COL - 1; j++)
{
scanf("%d", &arr[i][j]);
}
}
for (i = 0; i <= ROW - 1; i++)
{
max = arr[i][0];
for (j = 0; j <= COL - 1; j++)
{
if (max < arr[i][j])
{
max = arr[i][j];
colindex = j;
}
}
min = arr[0][colindex];
for (int i = 0; i <= ROW - 1; i++)
{
if (arr[i][colindex] < min)
{
min = arr[i][colindex];
rowindex = i;
}
}
if (min == max && i == rowindex)
{
flag = 1;
printf("鞍點(diǎn)的坐標(biāo)為[%d,%d],值為%d", rowindex, colindex, arr[rowindex][colindex]);
break;
}
}
if (flag == 0)
{
printf("沒有鞍點(diǎn)");
}
return 0;
}
運(yùn)行結(jié)果:
9. 有15個數(shù)按由大到小順序存放在一個數(shù)組中,輸入一個數(shù),要求用折半查找法找出該數(shù)是數(shù)組中第幾個元素的值。如果該數(shù)不在數(shù)組中,則輸出"無此數(shù)"。
解析:二分查找是七大查找中的一個,這種查找方法比較簡單快捷,但是這種方法面對頻繁更新、刪除操作、無序的表較為無力。
二分法原理:(舉例的數(shù)組按由大到小排列)
1、標(biāo)記出數(shù)組的左右邊界和中間坐標(biāo);
2、比較中間值與查詢值得大小關(guān)系,如果中間值大于查詢值則把中間值+1賦值給左邊界,同理則把中間值+1賦值給右邊界;
3、當(dāng)中間值等于查詢值時終止比較并輸出結(jié)果;
4、當(dāng)左邊界大于有邊界時則認(rèn)為數(shù)組種不存在查找值,輸出不存在;
int binner_find(int* arr, int sz, int num)
{
int left = 0, right = sz - 1;
int i, j;
while (left <= right)
{
int mid = (left + right) / 2;
if (arr[mid] > num)
{
left = mid+1;
}
else if (arr[mid] < num)
{
right = mid-1;
}
else if (arr[mid] == num)
{

return mid+1;
}
}
return -1;
}
int main()
{
int arr[] = { 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
int num = 0;
printf("請輸入要查找的數(shù)值:>");
scanf("%d", &num);
int mod = binner_find(&arr, sz, num);
if (mod == -1)
{
printf("無此數(shù)");
}
else
{
printf("找到了是第%d個元素",mod);
}
return 0;
}
注:最后返回的mid+1是因為這一題要求找到查詢值是數(shù)組中的第幾個元素,按照算數(shù)排列的話這里的坐標(biāo)就是mid+1。
運(yùn)行結(jié)果:
10. 有一篇文章,共有3行文字,每行有80個字符。要求分別統(tǒng)計出其中英文大寫字母、小寫字母、數(shù)字、空格以及其他字符的個數(shù)。
解析:這題的難點(diǎn)在于如何遍歷3X80的字符。
大概有兩種方法:
1、讀取字符:利用能夠讀取單一字符的特性,運(yùn)用循環(huán)語句完成代碼;
2、創(chuàng)建數(shù)組:創(chuàng)建數(shù)組,運(yùn)用gets和循環(huán)遍歷數(shù)組完成代碼;
(1)運(yùn)用讀取字符
/*
getchar做法,getchar有一個特性:一次只能吞吐一個字符。
基于這個特性我們就可以設(shè)計一個3X80的循環(huán),一個一個逐字分析得出個字符的數(shù)量。
*/
int main()
{
char c;//創(chuàng)建一個字符變量來接收getchar的信息
int capital = 0, minuscules = 0,
numbe = 0, space = 0, other = 0;
printf("請輸入一篇文章(共3行文字,每行80個字符):>\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 80; j++)
{
c = getchar();
if (c >= 'A' && c <= 'Z')
{
capital++;
}
else if (c >= 'a' && c <= 'z')
{
minuscules++;
}
else if (c >= '0' && c <= '9')
{
numbe++;
}
else if (c == ' ')
{
space++;
}
else
{
other++;
}
}
}
printf("大寫字母的個數(shù):%d\n", capital);
printf("小寫字母的個數(shù):%d\n", minuscules);
printf("數(shù)字的個數(shù):%d\n", numbe);
printf("空格的個數(shù):%d\n", space);
printf("其他字符的個數(shù):%d\n", other);
return 0;
}
(2)創(chuàng)建數(shù)組
int main()
{
char c[3][3];
int i, j;
int capital = 0, minuscules = 0,
numbe = 0, space = 0, other = 0;
for (i = 0; i < 3; i++)
{
printf("請輸入第%d行:>\n", i + 1);
gets(c[i]);
for (j = 0; j < 3 && c[i][j] != '\0'; j++)
{
if (c[i][j] >= 'A' && c[i][j] <= 'Z')
{
capital++;
}
else if (c[i][j] >= 'a' && c[i][j] <= 'z')
{
minuscules++;
}
else if (c[i][j] >= '0' && c[i][j] <= '9')
{
numbe++;
}

else if (c[i][j] == ' ')
{
space++;
}
else
{
other++;
}
}
}
printf("大寫字母的個數(shù):%d\n", capital);
printf("小寫字母的個數(shù):%d\n", minuscules);
printf("數(shù)字的個數(shù):%d\n", numbe);
printf("空格的個數(shù):%d\n", space);
printf("其他字符的個數(shù):%d\n", other);
return 0;
}
注:這種方法在VS中會出現(xiàn)棧錯誤:Stack the 'XXX' was .可能是編譯器的問題。
這個圖片就不放了,自己運(yùn)行一下吧。
11. 輸出以下圖案:
* * * *
* * * *
* * * *
* * * *
* * * *
解析:難題做多了用解析法設(shè)計程序,做一個簡單的題目。這題比較簡單,我們可以通過觀察得到每一行打印多打印兩個空格,用for就可以輕松解決。
int main()
{
int i = 0, j = 0;
for (i = 0; i < 5; i++)
{
for (j = 0; j < i; j++)
{
printf(" ");
}
printf("* * * *\n");
}
return 0;
}
運(yùn)行結(jié)果:
12. 有一行電文,以按下面規(guī)律譯成密碼:
A--->Z ? a--->z
B--->Y ? b--->Y
C--->X ? c--->x
即第1個字母編程第26個字母,第i個字母編程第(26-i+1)個字母,非字母字符不變,要求編程序?qū)⒚艽a譯回原文,并輸出密碼和原文。
解析:這一題解題的關(guān)鍵是合理運(yùn)用ASCII碼,我們只要知道當(dāng)前要轉(zhuǎn)換的字母是26個字母中的N個字母,再把26-N加到要起始字母上就可以了。
int main()
{
char arr[9999] = { 0 };
scanf("%s", &arr);
int len = strlen(arr);
for (int i = 0; i < len; i++)
{
if (arr[i] >= 'a' && arr[i] <= 'z')
{
arr[i] = 'a' + 'z' - arr[i];
}
else if (arr[i] >= 'A' && arr[i] <= 'Z')
{
arr[i] = 'A' + 'Z' - arr[i];
}
}
printf("%s", arr);
return 0;
}
運(yùn)行結(jié)果:
13. 編一程序,將兩個字符串連接起來,不要用函數(shù)
解析:字符串和數(shù)組不一樣,不能使用 “ = ” 賦值。這里提供兩個思路:
1、創(chuàng)建數(shù)組,遍歷賦值法:顧名思義,就是創(chuàng)建一個新的字符串,把原來的兩個字符串遍歷讀取挨個賦值到新字符串中。
int main()
{
char arr1[9999] = { 0 };
char arr2[9999] = { 0 };
char arr3[9999] = { 0 };
printf("請輸入第一串字符:>");
scanf("%s", &arr1);
int len1 = strlen(arr1);
printf("請輸入第二串字符:>");
scanf("%s", &arr2);
int len2 = strlen(arr2);
for (int i = 0; i < len1; i++)
{
arr3[i] = arr1[i];
}
for (int i = 0; i < len2; i++)
{
arr3[len1 + i] = arr2[i];
}
printf("拼接后的字符:>%s", arr3);
return 0;
}
運(yùn)行結(jié)果:
2、指針拼接法:指針法和數(shù)組遍歷原理基本相似,也是遍歷兩個字符串把不等于 ‘\0’ 的值的地址挨個賦值到新字符串的地址上。
void my_strcat(char* arr1, char* arr2, char* p)
{
int i = 0;

for (; *arr1 != '\0';)
{
*p = *arr1;
arr1++;
p++;
}
for (; *arr2 != '\0';)
{
*p = *arr2;
arr2++;
p++;
}
*p = '\0';
}
int main()
{
char arr1[9999] = { 0 };
char arr2[9999] = { 0 };
char arr3[9999] = { 0 };
char* p = 0;
p = arr3;
printf("請輸入第一串字符:>");
scanf("%s", &arr1);
printf("請輸入第二串字符:>");
scanf("%s", &arr2);
my_strcat(arr1, arr2, p);
printf("拼接后的字符:>%s", p);
return 0;
}
運(yùn)行結(jié)果:
14. 編寫一個程序,對兩個字符串s1和s2進(jìn)行比較,如果s1 > s2,輸出一個整數(shù);若s1 = s2,輸出0;若s1 < s2,輸出一個負(fù)數(shù)。不要用函數(shù)。兩個字符串用gets函數(shù)讀入。輸出的正數(shù)或負(fù)數(shù)的絕對值應(yīng)是相比較的兩個字符串相對應(yīng)字符的ASCII碼的差值。例如,“A"和“C”相比,由于"A” < “C”,應(yīng)輸出負(fù)數(shù),同時由于‘A’與‘C’的ASCII碼差值為2,因此應(yīng)輸出"-2"。同理:“And”和"Aid"相比較,根據(jù)第2個字符比較結(jié)果,“n"比"i"大5,因此應(yīng)輸出"5”。
解析:這題題目看著很復(fù)雜也很長,但實(shí)際上這題只是運(yùn)用了ASCII的知識。運(yùn)用循環(huán)語句將字符串中的字符挨個對比,如果兩個相等則繼續(xù)比較,如果兩個不相等則進(jìn)行相減,并將ASCII導(dǎo)出。
int main()
{
int index = 0,ret = 0;
char s1[9999] = { 0 };
char s2[9999] = { 0 };
printf("請輸入第一串字符:>");
gets(s1);
printf("請輸入第二串字符:>");
gets(s2);
//這里當(dāng)s1[index] = s2[index]時,兩個的差值應(yīng)該是0,這里為了保證繼續(xù)運(yùn)行則對結(jié)果取非
while (!(ret = s1[index] - s2[index]) && ('\0' != s1[index]) && ('\0' != s2[index]))
{
++index;
}
printf("返回值:>%d", ret);
return 0;
}
運(yùn)行結(jié)果:
15. 編寫一個程序,將字符數(shù)組s2中的全部字符復(fù)制到字符數(shù)組s1中,不用函數(shù)。復(fù)制時,‘\0’也要賦值過去。’\0’之后的字符不復(fù)制。
解析:這題只是一個簡單的的字符串賦值問題,和前面的13題一樣,分兩種方法:
1、創(chuàng)建數(shù)組遍歷賦值法:創(chuàng)建一個新數(shù)組,把原來的字符串賦值到新數(shù)組;
int main()
{
char arr1[9999] = { 0 };
char arr2[9999] = { 0 };
printf("請輸入第一串字符:>");
scanf("%s", &arr1);
int len1 = strlen(arr1);
for (int i = 0; i < len1; i++)
{
arr2[i] = arr1[i];
}
printf("復(fù)制后的字符串:>%s", arr2);
return 0;
}
運(yùn)行結(jié)果:
2、指針法:遍歷字符串把不等于 ‘\0’ 的值的地址挨個賦值到新字符串的地址上。
void my_strcat(char* arr1, char* p)
{
int i = 0;
for (; *arr1 != '\0';)
{
*p = *arr1;
arr1++;
p++;
}
*p = '\0';
}
int main()
{
char arr1[9999] = { 0 };
char arr2[9999] = { 0 };
char* p = 0;
p = arr1;
printf("請輸入第一串字符:>");
scanf("%s", &arr1);
my_strcat(arr1, p);
printf("復(fù)制后的字符串:>%s", p);
return 0;
}
運(yùn)行結(jié)果: