1.创建一个链表并反向输出
思路:双向链表反向输出
#include<stdio.h>
#include<stdlib.h>
struct list
{
int date;
struct list *prve,*next;
};
int main()
{
struct list* head, *before, * end;
head = (struct list*)malloc(sizeof(struct list));
head->next = NULL;
head->prve = NULL;
before = end = head;
printf("创建一个1-10的数列并反向输出");
for (int i = 1; i <= 10; i++)
{
end = (struct list*)malloc(sizeof(struct list));
end->date = i;
end->next = NULL;
end->prve = before;
before->next = end;
before = end;
}
struct list* t = end;
while (t->prve)
{
printf("%d ", t->date);
t = t->prve;
}
return 0;
}
2.设计函数实现任意数制转化
设计2-36进制相互转化
利用字符串存储数据,将a进制转化为10进制再转化为b进制
a进制转化10进制过程每次取余乘权数直到为0
10进制转化b进制为取余除b直到为0
#include<stdio.h>
#include<string.h>
int toten(int t,int a)
{
int ans = 0,to=1;
while (t)
{
ans += (t % 10) * to;
to = to * a;
t = t / 10;
}
return ans;
}
char* tob(int ten, int b)
{
char character[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static char ans[32];
int i;
if (ten < b)
{
ans[0] = character[ten];
}
else
{
for ( i = 0; ten; i++)
{
ans[i] = character[(ten % b)];
ten /= b;
}
ans[i] = '\0';
}
return ans;
}
int main()
{
int a, b,t;
printf("请输入a进制及a进制数与要转化的b进制:\n");
scanf("%d%d%d", &a, &t, &b);
printf("%d进制数%d转化为10进制结果为:%d\n", a,t,toten(t, a));
char *c;
printf("%d进制数%d转化为%d进制结果为:", a, t);
c = tob(toten(t, a), b);
for (int i = strlen(c); i >= 0; i--)
printf("%c", c[i]);
return 0;
}
3.设计一个函数放回字符串最后一个字符若为空放回NULL;
利用该函数放回两个字符串的最后一个字符,用指针完成;
#include<stdio.h>
#include<string.h>
char lastchar(char str[])
{
if (strlen(str) == 0)return '\0';
return str[strlen(str)-1];
}
int main()
{
char a[100] = { "heajdskjal" };
char b[100] = { "" };
printf("%c\n", lastchar(b));
printf("%c", lastchar(a));
return 0;
}
4.输入三个数字,利用指针找出最大最小值
分析:p,q,r分别指向a,b,c;
如果a<b让q指向p,p指向b的地址完成交换,反之不变 此次if后保证p指向a,b最大值同理比较c
最后q,r为三个数中较小的两个数一次比较可以得到最小值;
#include<stdio.h>
int main()
{
int a, b, c;
int* p, * q, * r;
p = &a, q = &b, r = &c;
printf("输入三个数字\n");
scanf("%d%d%d", &a, &b, &c);
if (*p < *q)
{
q = p;
p = &b;
}
if (*p < *r)
{
r = p;
p = &c;
}
if (*q <* r)
{
r = q;
}
printf("最大值为:%d\n最小值为%d\n", *p, *r);
return 0;
}
5.给定一个年份 y 和一个整数 d,问这一年的第 d 天是几月几日?注意闰年的 2 月有29 天。
分析:利用数组存储月份天数,判断是否为闰年;
循环减得到月份和天数;
#include<stdio.h>
int month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
void run(int year)
{
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
month[2] = 29;
else month[2] = 28;
}
int main()
{
int year,day;
printf("请输入你需要查询的年份以及天数");
scanf("%d%d", &year, &day);
run(year);
int i;
for (i= 1; i <= 12&&day-month[i]>0; i++)
{
day -= month[i];
}
printf("查询日期为:%d月%d日", i, day);
return 0;
}
- 用指针实现:程序的功能是在字符串 s 中找出最大的字符并放在第一个位置上,并将该字符前的原字符往后顺序移动。
分析:简单模拟,找到最大字符记录其位置
#include<stdio.h>
#include<string.h>
int main()
{
char str[100];
printf("输入字符串:");
scanf("%s", str);
char* t=&str[0];
int i,j=0;
for ( i = 0; i < strlen(str); i++)
{
if (*t < str[i])
{
t = &str[i];
j = i;
}
}
str[0] = *t;
printf("修改后字符串为:\n");
for (int i = j; i > 1; i--)
{
str[i] = str[i - 1];
}
printf("%s", str);
return 0;
}
- 用指针实现删除字符串 s 中的所有空格(包括 TAB 符、回车符)
#include<stdio.h>
#include<string.h>
int main()
{
char str[100],ans[100];
printf("输入一个字符串");
scanf("%[^\n]", str);
char* t = &str[0];
int i,j=0;
for (i = 0; i < strlen(str); i++,t++)
{
if (*t ==' ')continue;
else ans[j++] = *t;
}
ans[j] = '\0';
printf("去空格后:");
for ( j = 0; j < strlen(ans); j++)
printf("%c", ans[j]);;
return 0;
}
- 求数组的最大值和最小值,并分析时间复杂度和空间复杂度。
#include<stdio.h>
int main()
{
int num[100] = {32,21,41,12,3,34,5,77};
int max = num[0], min = num[0];
for (int i = 0; i <= 7; i++)
{
if (max < num[i])max = num[i];
if (min > num[i])min = num[i];
}
printf("最大值为:%d 最小值为:%d", max, min);
return 0;
}
时间复杂度:历遍数组时间复杂度为O(n);
空间复制度为数组大小S(n)=O(n);
12. 通过函数交换 a 和 b 的值,并详细分析内存里的数值``的传输过程。
#include<stdio.h>
void swap(int* t1, int* t2)
{
int t;
t = *t1;
*t1 = *t2;
*t2 = t;
}
int main()
{
int a = 1, b = 2;
swap(&a, &b);
printf("a的值:%d b的值:%d",a,b);
return 0;
}
将a,b地址作为函数参数利用临时变量t存储a地址中的值
将b地址中的值赋给a地址中的值;
再将变量t值赋给b地址中的值;
13. 利用递归函数调用方式,将所输入的 5 个字符,以相反顺序打印出来。
#include<stdio.h>
void f(int n)
{
if (n == 1)
{
char x=getchar();
putchar(x);
}
else
{
char x = getchar();
f(n - 1);
putchar(x);
}
}
int main()
{
printf("输入五个字符");
f(5);
return 0;
}
- 创建两个学生链表,分别根据学生成绩对链表排序,并把这两个链表连接在一起。连接的时候,按照从小到大的顺序连接。
分析:链表基本操作
#include<stdio.h>
#include<stdlib.h>
struct node
{
int socre;
struct node *next;
};
void creat(struct node* head)
{
struct node* before, * temp;
before = temp = head;
for (int i = 0; i < 5; i++)
{
temp = (struct node*)malloc(sizeof(struct node));
scanf("%d", &temp->socre);
temp->next = NULL;
before->next = temp;
before = temp;
}
}
void sort(struct node* head)
{
struct node* begin = NULL, * end = NULL;
begin = head->next;
while (begin != end)
{
while (begin->next != end)
{
if (begin->socre > begin->next->socre)
{
int t;
t = begin->socre;
begin->socre = begin->next->socre;
begin->next->socre = t;
}
begin = begin->next;
}
end = begin;
begin = head->next;
}
}
void connct(struct node*head,struct node* head1, struct node* head2)
{
struct node* t1,*t2;
t1 = head1->next;
t2 = head2->next;
struct node* before, * temp;
before = temp = head;
while(t1&&t2)
{
temp = (struct node*)malloc(sizeof(struct node));
if (t1->socre < t2->socre) { temp->socre = t1->socre; t1 = t1->next; }
else { temp->socre = t2->socre; t2 = t2->next; }
temp->next = NULL;
before->next = temp;
before = temp;
}
while (t1)
{
temp = (struct node*)malloc(sizeof(struct node));
temp->socre = t1->socre; t1 = t1->next;
temp->next = NULL;
before->next = temp;
before = temp;
}
while (t2)
{
temp = (struct node*)malloc(sizeof(struct node));
temp->socre = t2->socre; t2 = t2->next;
temp->next = NULL;
before->next = temp;
before = temp;
}
}
void dis(struct node* head)
{
struct node* t = head->next;
while (t)
{
printf("%d ", t->socre);
t = t->next;
}
printf("\n");
}
int main()
{
struct node* head1, * head2, * head3;
head1 = (struct node*)malloc(sizeof(struct node));
head1->next = NULL;
creat(head1);
sort(head1);
printf("对第一个链表排序后:\n");
dis(head1);
head2 = (struct node*)malloc(sizeof(struct node));
head2->next = NULL;
creat(head2);
sort(head2);
printf("对第二个链表排序后:\n");
dis(head2);
printf("链接两个链表\n");
head3 = (struct node*)malloc(sizeof(struct node));
head3->next = NULL;
connct(head3, head1, head2);
dis(head3);
return 0;
}
16. 有 n 个整数,使其前面各数顺序向后移 m 个位置,最后 m 个数变成最前面的 m
个数。
#include<stdio.h>
int main()
{
int num[100];
int n, m;
printf("请输入n");
scanf("%d", &n);
printf("请输入n长度的数组");
for (int i = 1; i <= n; i++)
scanf("%d", &num[i]);
printf("请输入往后移动的位数m");
scanf("%d", &m);
for (int i = n + m; i >=n-1; i--)
{
num[i] = num[i - m];
}
for (int j = 1, i = n+1; j <=m; i++, j++)
{
num[j] = num[i];
}
for (int i = 1; i <= n + m; i++)
printf("%d ", num[i]);
return 0;
}
- 将一个正整数分解质因数。例如:输入 90,打印出 90=233*5。
#include<stdio.h>
int main()
{
int n;
printf("请输入一个正整数:");
scanf("%d", &n);
printf("%d = ", n);
for (int i = 2; i <= n; i++)
{
if (n % i == 0)
{
while (n % i == 0)
{
printf("%d", i);
n /= i;
if (n >=i)printf("*");
}
}
}
if(n>1)printf("%d\n", n);
return 0;
}
- 给定 n 个正整数,找出它们中出现次数最多的数。如果这样的数有多个,请输出其中最小的一个
分析:桶排序
#include<stdio.h>
int book[100];
int main()
{
int n;
printf("输入n:");
scanf("%d", &n);
int t;
for (int i = 1; i <= n; i++)
{
scanf("%d", &t);
book[t]++;
}
int max =-1, posi=0;
for (int i = 1; i <= 100; i++)
{
if (book[i] > max)
{
max = book[i];
posi = i;
}
}
printf("%d出现的最多", posi);
return 0;
}
- 求 0-7 所能组成的奇数个数。
分析:排列组合问题
#include<stdio.h>
int main()
{
long sum = 4, t = 4; //1位数为4个
int j;
for (j = 2; j <= 8; j++)
{
printf("\n%ld", sum);
if (j <= 2) //如果j为两位数
t *= 7;
else
t*= 8;
sum += t;
}
printf("\nsum=%ld", sum);
}
- 把 M 个同样的苹果放在 N 个同样的盘子里,允许有的盘子空着不放,问共有多
少种不同的分法?(用 K 表示)5,1,1 和 1,5,1 是同一种分法。
m<n时,至少有n-m个盘子空着(这些空盘子并不影响最后的结果,因为每种方法都带有着些空盘子)。只考虑m个苹果放m个盘子 f(m,n)=f(m,m)
m>n时,按是否有空盘子 分2种情况:
a.假设至少一个盘子空着,相当于f(m,n)=f(m,n-1)
b.所有的盘子都有苹果,假设每个盘子可以先放一个,问题就变成:m-n个苹果放到n个盘子,即f(m,n)=f(m-n,n)
临界条件
n=1时,所有苹果都放在同一个盘子里 f(m,n)=1
m=0时,没有苹果 f(m,n)=1
#include<stdio.h>
int apple(int m, int n) {
if (n == 1 || m == 0) return 1;
else if (m < n) return apple(m, m);
else return apple(m, n - 1) + apple(m - n, n);
}
int main()
{
int m, n;
printf("输入苹果个数和盘子个数");
scanf("%d%d", &m, &n);
int k = apple(m,n);
printf("有%d种放法", k);
}
- 有一实数或者字母序列 A[1]、A[2] 、A[3] 、……A[n-1] 、A[n],若 i<j,并且 A[i]
>A[j],则称 A[i]与 A[j]构成了一个逆序对,求字符串 A 中逆序对的个数。
分析:归并排序求逆序对
#include<stdio.h>
int num[100005], tem[100005];
long long sort(int l, int r)
{
long long res;
if (l == r)return 0;
int mid;
mid = l + r >> 1;
res = sort(l, mid) + sort(mid + 1, r);
int i = l, j = mid + 1, k = 0;
while (i <= mid && j <= r)
{
if (num[i] <= num[j])tem[k++] = num[i++];
else { tem[k++] = num[j++]; res += mid - i + 1; }
}
while (i <= mid)tem[k++] = num[i++];
while (j <= r)tem[k++] = num[j++];
for (int i = l, j = 0; i <= r; i++, j++)
num[i] = tem[j];
return res;
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &num[i]);
printf("%lld", sort(0, n - 1));
return 0;
}
- 给一个非负整数,判断这个数是不是相互不同的非负整数的阶乘的和。如 6=3!;7=3!+ 1!;但 5 不是相互不同的非负整数的阶乘的和。
#include<stdio.h>
int jc(int n)
{
if (n == 1)return 1;
else return n * jc(n - 1);
}
int main()
{
int num[11] = {0};
for (int i = 1; i <= 10; i++)
{
num[i] = jc(i);
}
int n;
printf("请输入一个数");
scanf("%d", &n);
if (n == 0)printf("NO\n");
else
{
for (int i = 9; i >= 1; i--)
{
if (n >= num[i])n = n - num[i];
}
if (n == 0)printf("YES");
else printf("NO");
}
return 0;
}
- 图像的像素可以用一个二维数组来表示,对图像求中值滤波,滤波窗口大小为 3x3。图像像素值自行设定。
分析:二维状态压缩为一维,排序找中间值
#include<stdio.h>
int GetMedNum(int* Array, int iFilterLen)
{
int i, j;
int Temp;
for (j = 0; j < iFilterLen - 1; j++)
{
for (i = 0; i < iFilterLen - j - 1; i++)
{
if (Array[i] > Array[i + 1])
{
Temp = Array[i];
Array[i] = Array[i + 1];
Array[i + 1] = Temp;
}
}
}
Temp = Array[(iFilterLen + 1) / 2];
return Temp;
}
int main()
{
int num[3][3] = { 1,23,43,534,213,11,55,77,44 };
int t[9];
int k = 0;
for(int i=0;i<3;i++)
for (int j = 0; j < 3; j++)
{
t[k++] = num[i][j];
}
printf("%d", GetMedNum(t, 9));
}
- 在图像编码的算法中,需要将一个给定的方形矩阵进行 Z 字形扫描(Zigzag Scan)。
给定一个 n×n 的矩阵,Z 字形扫描的过程如下图所示:
对于下面的 4×4 的矩阵,
1 5 3 9
3 7 5 6
9 4 6 4
7 3 1 3
对其进行 Z 字形扫描后得到长度为 16 的序列:
1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3
请实现一个 Z 字形扫描的程序,给定一个 n×n 的矩阵,输出对这个矩阵进行 Z 字形扫描的结果。
#include<stdio.h>
int num[100][100];
int main()
{
int n;
printf("请输入矩阵边长");
scanf("%d", &n);
int i, j;
printf("输入矩阵数据\n");
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
scanf("%d", &num[i][j]);
i = 0,j=0;
int k = 1;
printf("%d ", num[0][0]);
while (k<=n*n)
{
if (j + 1 >= n)
{
i++;
}
else
{
j++;
}
if (k++ >= n * n)break;
printf("%d ", num[i][j]);
while (j-1>= 0&&i+1<n) //斜下
{
i++, j--; printf("%d ", num[i][j]);
k++;
}
if (i + 1 >= n)
{
j++;
}
else
{
i++;
}
if (k++ >= n * n)break;
printf("%d ", num[i][j]);
while (i -1>=0&&j+1<n) //斜上
{
i--, j++;
printf("%d ", num[i][j]);
if (k++ >= n * n)break;
}
}
return 0;
}