常用算法
#include <stdio.h>
void filecopy(FILE *ifp, FILE *ofp);
int main(int argc, char *argv[]) {
FILE *ifp;
char *name = argv[0];
if (argc == 1) { /* 没有参数,从标准输入复制到标准输出 */
filecopy(stdin, stdout);
return 0;
}
while (*++argv != NULL)
if ((ifp = fopen(*argv, "r")) == NULL)
printf("%s, can't open input file: %s\n", name, *argv);
else {
filecopy(ifp, stdout);
fclose(ifp);
}
return 0;
}
void filecopy(FILE *ifp, FILE *ofp) {
int c;
while ((c = getc(ifp)) != EOF)
putc(c, ofp);
}
程序1
while (scanf("%ld %s %d %d %d", &number, name, &year, &month, &day) != 5) {
printf("Input error.\n");
printf("Format: number name year month day\n");
while (gerchar() != '\n')
; /* 丢掉本输入行剩下的无用字符 */
}
程序2:
char line[256];
while (1) {
printf(">>");
gets(line);
if (sscanf(line, "%ld %s %d %d %d",
&number, name, &year, &month, &day) == 5)
break;
if (sscanf(line, "%ld %s %d,%d,%d",
&number, name, &year, &month, &day) == 5)
break;
if (sscanf(line, "%ld %s %d/%d/%d",
&number, name, &day, &month, &year) == 5)
break;
printf("Invalid form: %s", line);
}
void pAverage(FILE *fp, char *fname) {
double x, sum = 0.0;
int n = 0, m, c;
printf("\nFile %s:\n", fname);
whlie ((m = fscanf(fp, "%lf", &x)) != EOF) {
if (m == 1) {
sum += x;
n++;
continue; /* 继续循环读入 */
}
printf("Date error. Discard: ");
while (!isspace(c = getc(fp)))
putchar(c);
putchar('\n');
}
printf("Average: %16.8f\n", sum / n);
}
int main(void) {
char name[256];
FILE *fp;
while (1) {
printf("File name (Ctrl-Z for the end): ");
if (gets(name) == NULL) break;
if ((fp = fopen(name, "r")) == NULL)
printf("Can't open file: %s\n", name);
else {
pAvarage(fp, name);
fclose(fp);
}
}
printf("Bye!\n");
return 0;
}
int sum(int n, ...) {
va_list vap;
int i, s = 0;
va_start(vap, n);
for (i = 1; i <= n; i++)
s += va_arg(vap, int);
va_end(vap);
return s;
}
例:打印输出身份证结构中身份证号码和姓名
void prtIDCard0(IDCARD ic) {
printf("%s\n", ic.id_number);
printf("%s\n\n", ic.name);
}
或者定义下面的函数,调用时应该传身份证记录的地址:
void prtIDCard(IDCARD *icp) {
printf("%s\n", icp->id_number);
printf("%s\n\n", icp->name);
}
POINT *mkpoint2(double x, double y) {
POINT *p;
p = (POINT *)malloc(sizeof(POINT));
p->x = x;
p->y = y;
return p;
}
#include <string.h> /* 程序中需要做字符串复制和比较 */
#include <stdlib.h> /* 程序中要做动态存储分配 */
#define MAXLEN 20
typedef struct node NODE, *LINK; /* 类型定义 */
struct node {
char word[MAXLEN];
int count;
LINK next;
};
int getword(char w[], int limit); /* 有关函数的原型说明 */
LINK addword(LINK l, char w[]);
void printwords(LINK l);
LINK list = NULL; /* 全局变量,作为表的头指针 */
char word[MAXLEN]; /* 读入用的临时字符数组 */
int main (void) {
while (getword(word, MAXLEN) != 0)
if (isalpha(word[0]))
list = addword(list, word);
printwords(list);
return 0;
}
void printwords(LINK p) {
for ( ; p != NULL; p = p->next)
printf("%d %s\n", p->count, p->word);
}
LINK mknode(char w[]) {
LINK p = (LINK)malloc(sizeof(NODE));
if (p != NULL) {
strncpy(p->word, w, MAXLEN);
p->count = 1;
p->next = NULL;
}
return p;
}
LINK addword(LINK p, char w[]) {
if (p != NULL) {
if(strcmp(p->word, w) == 0)
p->count++;
else
p->next = addword(p->next, w);
return p;
}
else
return mknode(w);
}
void swap(int *p, int *q) {
int t = *p;
*p = *q;
*q = t;
}
double sum(double a[], int n) {
int i;
double s = 0.0;
for (i = 0; i < n; i++)
s += a[i];
return s;
}
程序1:
int strLength (const char *s) {
int n = 0;
while (*s != '\0') {
s++;
n++;
}
}
程序2:
int strLength (const char *s) {
char *p = s;
while (*p != '\0') p++;
return p - s;
}
程序1:
void strCopy (char *s, const char *t) {
while ((*s = *t) != '\0') {
s++;
t++;
}
}
程序2:
void strCopy (char *s, const char *t) {
while (*s = *t) {
s++;
t++;
}
}
程序3
void strCopy (char *s, const char *t) {
while (*s++ = *t++)
;
}
程序1:
#include <stdio.h>
int main (int argc, char *argv[]) {
int i;
for (i = 0; i < argc; i++)
printf("%s%c", argv[i], i < argc-1 ? ' ' :'\n');
return 0;
}
程序2:
#include <stdio.h>
int main (int argc, char *argv[]) {
while(*agrv != NULL)
printf("%s ", *argv++);
putchar('\n');
return 0;
}
void prtMatrix (int *mp, int m, int n) {
int i, j;
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++)
printf("%d ", *(mp + i * n + j));
putchar('\n');
}
}
例:求出两个用数组表示的向量的和
double *vadd(double a[], double b[], int n) {
double *p;
int i;
p = (double *)malloc(n * sizeof(double));
if (p == NULL) return NULL;
for (i = 0; i < n; i++)
p[i] = a[i] + b[i];
return p;
}
double cross(MFP fp, double x1, double x2) {
double y1 = fp(x1), y2 = fp(x2);
return (x1 * y2 - x2 * y1) / (y2 - y1);
}
double root(MFP fp, double x1, double x2) {
double x, y, y1 = fp(x1);
do {
x = cross(fp, x1, x2);
y = fp(x);
if (y * y1 > 0.0) {
y1 = y;
x1 = x;
}
else
x2 = x;
} while (y >= 1E-6 || y <= -1E-6);
return x;
}
程序1:
#define DIVN 30
double numInt(MFP fp, double a, double b) {
double res = 0.0, step = (b - a) / DIVN;
/* DIVN 是划分小区间的数目 */
int i;
for (i = 0; i < DIVN; i++)
res += fp(a + i * step) * step;
return res;
}
程序2(改进程序,根据实际情况自动决定划分数):
double numInt(MFP fp, double a, double b) {
long i, divn = 10;
double step, dif, res0,
res = (fp(b) + fp(a)) * (b - a) / 2;
for (dif = 1.0; dif > 1E-6 || dif < -1E-6; divn *= 2) {
res0 = res;
step = (b - a) / divn;
for (res = 0.0, i = 0; i < divn; i++)
res += fp(a + i * step) * step;
dif = res - res0;
}
return res;
}
例:打印Fibonacci序列前30个数
#include <stdio.h>
int main (void) {
long fib[30];
int n;
fib[0] = 1;
fib[1] = 1;
for (n = 2; n < 30; n++)
fib[n] = fib[n-1] + fib[n-2];
for (n = 0; n < 30; n++) {
printf("%d", fib[n]);
putchar(n % 6 == 5 ? '\n' : ' ');
}
return 0;
}
例:求2.38、3.142、5.674、8.257、6.44的平均值的2个程序
程序 1:
#include <stdio.h>
double a[5] = {2.38, 3.142, 5.674, 8.257, 6.44};
int main (void) {
int n;
double sum = 0.0;
for (n = 0; n < 5; n++)
sum += a[n];
printf("Average: %f\n", sum / 5);
return 0;
}
程序 2:
#include <stdio.h>
double a[] = {2.38, 3.142, 5.674, 8.257, 6.44};
#define NUM (sizeof(a) / sizeof(a[0]))
int main (void) {
int n;
double sum = 0.0;
for (n = 0; n < NUM; n++)
sum += a[n];
printf("Average: %f\n", sum / NUM);
return 0;
}
#include <stdio.h>
int main (void) {
int c, i, cs[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
while ((c = getchar()) != EOF)
if (c >= '0' && c <= '9')
cs[c - '0']++;
for (i = 0; i < 10; i++)
printf("%d ", cs[i]);
putchar('\n');
return 0;
}
程序 1:
double sqsum0(double a[]) {
double x = 0.0;
int i;
for (i = 0; i < LEN; i++)
/*符号常量 LEN 是数组的长度 */
x += a[i] * a[i];
return x;
}
程序 2:
double sqsum(double a[], int n) {
double x = 0.0;
int i;
for (i = 0; i < n; i++)
x += a[i] * a[i];
return x;
}
void rev(int a[], int n) {
int x, i, m = n/2;
for (i = 0; i < m; i++) {
x = a[i];
a[i] = a[n - i - 1];
a[n - i - 1] = x;
}
int main (void) {
int i, b[] = {1, 2, 3, 4, 5, 6, 7};
for (i = 0; i < 7; i++)
printf("b[%d] = %d\n", i, b[i]);
rev(b, 7);
printf("After reversion:\n");
for (i = 0; i < 7; i++)
printf("b[%d] = %d\n", i, b[i]);
return 0;
}
程序 1:
void str_copy (char s[], char t[]) {
int i = 0;
while (t[i] != '\0') {
s[i] = t[i];
i++;
}
}
程序 2:
void str_copy (char s[], char t[]) {
int i = 0;
while ((s[i] = t[i]) != '\0')
i++;
}
程序 3:
void str_copy (char s[], char t[]) {
int i = 0;
while (s[i] = t[i]) i++;
}
程序 1:
#include <stdio.h>
#define MAXLEN 1024
int getline(char line[], int limit);
void str_copy (char s[], char t[]);
int main (void) {
int n, max = 0; /* 记录当前行和最长行的长度 */
char line[MAXLEN], maxline[MAXLEN];
while ((n = getline(line, MAXLEN)) > 0)
if (n > max) {
max = n;
str_copy(maxline, line);
}
if (max > 0)
printf("%s\n", maxline);
return 0;
}
void str_copy (char s[], char t[]) {
int i = 0;
while ((s[i] = t[i]) != '\0')
i++;
}
int getline(char line[], int limit) {
int c, i = 0;
while (i < limit - 1 &&
(c = getchar()) != EOF && c != '\n') {
line[i] = c;
i++;
}
if (c == '\n') {
line[i] = '\n';
i++;
}
line[i] = '\0';
return i;
}
程序 2:
#include <stdio.h>
#define MAXLEN 1024
int getline(void);
void str_copy (void);
char line[MAXLEN], maxline[MAXLEN];
main (void) {
int n, max = 0; /* 记录当前行和最长行的长度 */
while ((n = getline()) > 0)
if (n > max) {
max = n;
str_copy();
}
if (max > 0)
printf("%s\n", maxline);
return 0;
}
void str_copy () {
int i = 0;
while ((maxline[i] = line[i]) != '\0')
i++;
}
int getline(void) {
int c, i = 0;
while (i < MAXLEN - 1 &&
(c = getchar()) != EOF && c != '\n') {
line[i] = c;
i++;
}
if (c == '\n') {
line[i] = '\n';
i++;
}
line[i] = '\0';
return i;
}
#include <stdio.h>
#define N 5
double A[N][N] = { ... ...}, B[N][N] = { ... ...},
C[N][N]; /* 数组A和B的实际数据需要填充 */
int main (void) {
int i, j, k;
double x;
for (i = 0; i < N; i++)
for (j = 0; j < N; j++) {
x = 0.0;
for (k = 0; k < N; k++)
x += A[i][k] * B[k][j];
C[i][j] = x;
}
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
printf("%f%c", C[i][j], j == N-1 ? '\n' :' ');
return 0;
}
double aaverage(double a[][5], int n) {
int i, j;
double sum = 0.0;
for (i = 0; i < n; i++)
for (j = 0; i < 5; j++)
sum += a[i][j];
return sum / (5 * n);
}
程序 1:
/* 程序 1 无法完成所要求的工作。 */
void count10_1(void) {
int m = 0; /* m是函数内部定义的局部自动变量 */
if (++m == 10) {
printf("Count 10\n");
m = 0;
}
}
程序 2:
int m = 0; /* m是个外部定义的变量 */
void count10_2(void) {
if (++m == 10) {
printf("Count 10\n");
m = 0;
}
}
程序 3:
void count10_3(void) {
static int m = 0; /* m是个静态局部变量 */
if (++m == 10) {
printf("Count 10\n");
m = 0;
}
}
例:用弦线法求方程的根
#include <stdio.h>
#include <math.h>
double f (double); /* f的原型,函数定义可以写在任何地方 */
double crossp (double x1, double x2) {
double y1 = f(x1), y2 = f(x2);
return (x1 * y2 - x2 * y1) / (y2 - y1);
}
double root (double x1, double x2) {
double x, y, y1 = f(x1);
do {
x = crossp(x1, x2);
y = f(x);
if (y * y1 > 0) { /* y与y1符号相同,取新区间为 [x,x2] */
x1 = x; y1 = y;
}
else x2 = x; /* y与y1符号不同,取新区间为 [x1,x] */
} while (fabs(y) >= 1E-6); /* y值不够小,继续 */
return x;
}
main (void) { /* 定义从略 */ }
/* 假设被求值的函数为 f(x) = x* sin(x) - 2*x*x */
double f (double x) {
return x * sin(x) - 2 * x * x;
}
#include <stdio.h>
#include <math.h>
main () {
double s;
s = (3 + 5 + 7) / 2.0;
printf("Area: %f\n", sqrt(s * (s-3) * (s-5) * (s-7) ) );
}
#include <stdio.h>
double c_area (double r) {
return r * r * 3.14159265;
}
main () {
printf("area1 = %f\n", c_area(3.24));
printf("area2 = %f\n", c_area(2.137));
printf("area3 = %f\n", c_area(0.865));
printf("area4 = %f\n", c_area(3.746));
printf("area5 = %f\n", c_area(12.3364));
printf("area6 = %f\n", c_area(8.421));
}
double t_area (double a, double b, double c) {
double s = (a + b + c)/2.0;
return (sqrt(s * (s-a) * (s-b) * (s-c)));
}
double dmax (double x, double y) {
return x > y ? x : y;
}
double sign (double x) {
return x > 0 ? 1 : (x == 0 ? 0 : -1);
}
long fact (long n) {
return n == 0 ? 1 : n * fact(n-1);
}
double dexp1 (int n) {
return n == 0 ? 1 : 2.71828 * dexp1(n-1);
}
double dexp (int n) {
return n >= 0 ? depx1(n) : 1 / dexp1(-n);
}
void pc_area (double r) {
if (r < 0)
printf("radius incorrect: %f\n", r);
else
printf("radius: %f, area: %f\n", r, 3.14159265*r*r);
}
void root2 (double a, double b, double c) {
double d;
d = b*b - 4*a*c;
if (d > 0) {
d = sqrt(d);
printf("Two real roots: %f, %f\n",
(-b+d)/2/a, (-b-d)/2/a);
}
else if (d == 0)
printf("One real root: %f\n", -b/2/a);
else
printf("No real root\n");
}
#include <stdio.h>
main () {
int c = 0;
while (c <= 300) {
printf("C = %d, F = %f\n", c, c * 9 / 5.0 + 32.0);
c = c + 20;
}
}
double dsin (double x) {
double sum = 0.0, t = x;
int n = 0;
while (t >= 1E-6 || t <= -1E-6) {
sum = sum + t;
n = n + 1;
t = -t * x * x / (2*n) / (2*n + 1);
}
return sum;
}
#include <stdio.h>
main() {
printf("V = %fcm^3\n",
(3.1416 * 6.5 * 6.5 * 6.5) * 4.0 / 3.0);
}
例:求两个相邻边的长度分别为 3.5 和 4.72 米,两边夹角为 37 度的三角形的面积
#include <stdio.h>
#include <math.h>
main () {
printf("Area of the triangle: %fm^2\n",
3.5 * 4.72 * sin(37.0 / 180 * 3.1416) / 2);
}
#include <stdio.h>
#include <math.h>
main () {
printf("%f\n", sqrt((3+5+7)/2.0 * ((3+5+7)/2.0 - 3) *
((3+5+7)/2.0 - 5) * ((3+5+7)/2.0 - 7)));
}
逐个检查1到200的所有整数,求1到200之间的完全平方数
#include <stdio.h>
main () {
int m, n;
for (n = 1; n <= 200; n++)
for (m = 1; m * m <= n; m++)
if (m * m == n)
printf("%d ", n);
printf("\n"); /* 最后换一行 */
}
例:利用sqrt求1到200之间的完全平方数
for (n = 1; n <= 200; n++)
if ((int)sqrt(n) * (int)sqrt(n) == n)
printf("%d ", n);
例:利用sqrt求1到200之间的完全平方数的改进程序
for (n = 1; n <= 200; n++) {
m = (int)sqrt(n);
if (m * m == n)
printf("%d ", n);
}
例:利用从1开始逐个打印计数变量值的平方,求1到200之间的完全平方数
for (n = 1; n * n <= 200; n++)
printf("%d ", n * n); /* 注意应当打印什么 */
int primeQ (int n) { /* 判断一个数是否素数 */
int m = 2;
for ( ; m * m <= n; m++)
if (n % m == 0) return 0; /* 发现因子,不是素数 */
return 1; /* 可能性均考虑过,没有因子,是素数 */
}
double cbrt(double x){
double x1, x2;
x1 = x;
x2 = (2.0 * x1 + x / (x1 * x1)) / 3.0;
while (fabs((x2 - x1) / x1) >= 1E-6) {
x1 = x2;
x2 = (2.0 * x1 + x / (x1 * x1)) / 3.0;
}
return x2;
}
double cbrt(double x){
double x1, x2;
if (x == 0.0) return 0.0;
for (x1 = x;
x2 = (2.0 * x1 + x / (x1 * x1)) / 3,
fabs((x2 - x1)/x1) >= 1E-6;
)
x1 = x2;
return x2;
}
long fib (int n) {
return n < 2 ? 1 : fib(n-1) + fib(n-2);
}
#include <stdio.h>
#include <time.h>
long fib (int n) {
return n <= 1 ? 1 : fib(n-1) + fib(n-2);
}
main () {
double x;
x = clock() / CLOCKS_PER_SEC;
fib(33);
x = clock() / CLOCKS_PER_SEC - x;
printf("Timing fib(33): %f\n", x);
}
long fib1 (int n) {
long f1 = 1, f2 = 1, f3, i;
if (n <= 1) return 1;
for (f3 = f1 + f2, i = 2; i < n; i++) {
f1 = f2;
f2 = f3;
f3 = f1 + f2;
}
return f3;
}
#include <stdio.h>
long count (double m) {
long n;
double sum = 0.0;
for (n = 0; sum <= m; n++)
sum += 1.0 / n;
return n;
}
main () {
printf("Sum of %ld terms exceeds %f\n",
count(100.0), 100.0);
printf("Sum of %ld terms exceeds %f\n",
count(200.0), 200.0);
printf("Sum of %ld terms exceeds %f\n",
count(1000.0), 1000.0);
}
例:从1开始逐个递增求最大公约数
long gcd (long m, long n) {
long d = 1, k = 2;
for ( ; k <= m && k <= n; k++)
if (m % k == 0 && n % k == 0)
d = k;
return d;
}
for ( k = (m > n ? n : m);
m % k != 0 || n % k != 0; k--)
; /* 空循环体 */
return k; /* 循环结束时,k总是最大公约数 */
long gcd(long m, long n) {
if (m < 0) m = -m;
if (n < 0) n = -n;
return n == 0 ? m : gcd1(m, n);
}
long gcd2 (long m, long n) {
long r;
if (n == 0) return m;
for (r = m % n; r != 0; r = m % n) {
m = n;
n = r;
}
return n;
}
for (n = 6; n <= 200; n += 2)
for (m = 3; m <= n/2; m+= 2)
if (primeQ(m) && primeQ(n - m))
printf("%d = %d + %d\n", n, m, n-m);
例:由输入得到的一个字符输出,并换一行
#include <stdio.h>
main () {
int c;
c = getchar();
putchar(c);
putchar('\n');
}
#include <stdio.h>
main () {
int c;
do {
c = getchar();
printf("%d ", c);
} while (c != '\n');
}
#include <stdio.h>
main () {
int c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
}
例:统计由标准输入得到的文件中字符的个数
#include <stdio.h>
main () {
int c; long n = 0;
while ((c = getchar()) != EOF)
n++;
printf("%ld\n", n);
}
例:读入一系列数值,把每个数据作为一个圆盘的半径,分别计算出每个圆盘的面积
#include <stdio.h>
void pc_area (double r) {
printf ("r = %f, S = %f\n", r, 3.14159265 * r * r);
}
main () {
double x;
while (scanf("%lf", &x) == 1)
if (x < 0)
printf("Input error: %lf\n", x);
else
pc_area(x);
}
#include <stdio.h>
main () {
double sum = 0.0, biggest, smallest, x;
int count = 1;
scanf("%lf", &sum);
biggest = smallest = sum;
while (scanf("%lf", &x) == 1) {
sum += x;
count++;
if (x > biggest) biggest = x;
if (x < smallest) smallest = x;
}
printf("Count of numbers: %d\n", count);
printf("Biggest: %lf, Smallest: %lf, Average: %lf\n",
biggest, smallest, sum / count);
}
例:分别统计输入文件中的空格、行、数字、花括号以及其他所有字符
#include <stdio.h>
main (void) {
int c;
int nd = 0, nb = 0, nl = 0, nc = 0, nn = 0; /*5个计数器*/
while ((c = getchar()) != EOF)
switch (c) {
case ' ':
nb++; break;
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '0':
nd++; break;
case '\n':
nl++; break;
case '{':
case '}':
nc++; break;
default:
nn++; break;
}
printf("spaces: %d, lines: %d, digits: %d", nb, nl, nd);
printf("{ and }: %d, others: %d\n", nc, nn);
}
#define OUT 0
main (void) {
int c, count = 0, state = OUT;
while ((c = getchar()) != EOF)
if (c == ' ' || c == '\t' || c == '\n')
state = OUT;
else if (state == OUT) {
state = IN;
count++;
}
printf("word count: %d\n", count);
}
// 直接取浮点数的指数部分
inline int exponent_of_2(int n)
{
float t = n;
return ((*(unsigned int *)&t)>>23) - 127;
}