4、指针的应用
4.1、三角形周长和面积计算程序
描述
已知三角形的三条边的长度,求该三角形的周长和面积,如果三个边不能构成三角形,则三角形的周长和面积都为0。完成程序的编写。
输入
输入1行,包含3个实数,各实数之间用空格隔开。
输出
输出1行,包含2个实数(用一个空格隔开),分别是三角形的周长和面积,结果保留2位小数,第3位小数四舍五入。
输入样例 1 输出样例 1
5.968 5.123 7.63 18.72 15.26
具体实现
#include<stdio.h>
#include<math.h>
void CalAreaAndPremiter(double a,double b,double c){double s=0,area=0,premiter=0;if(a+b>c&&a+c>b&&b+c>a){s=(a+b+c)/2;premiter=2*s;area=sqrt(s*(s-a)*(s-b)*(s-c));printf("%.2lf %.2lf",premiter,area);}else printf("%.2lf %.2lf",premiter,area);
}
int main(){double a,b,c;scanf("%lf%lf%lf",&a,&b,&c);CalAreaAndPremiter(a,b,c);return 0;
}
4.2、三个实数排序程序
描述
输入三个实数,从小到大输出该三个实数。完成程序的编写。
输入
输入1行,包含3个实数,各实数之间用空格隔开。
输出
输出1行,包含从小到大排列的3个实数,各实数之间用空格隔开。
输入样例 1 输出样例 1
35.3 21.73 28.92 21.73 28.92 35.30
具体实现
#include<stdio.h>
int main()
{ double a,b,c,d;scanf("%lf%lf%lf",&a,&b,&c);if(a>b){d=a;a=b;b=d; //a、b的值互换,互换后a≤b}if(a>c){d=a;a=c;c=d; //a、c的值互换,互换后a≤c}if(b>c){d=b;b=c;c=d; //b、c的值互换,互换后b≤c}printf("%5.2lf %5.2lf %5.2lf\n",a,b,c);
}
4.3、 指针排序程序
描述
用指针的方法将n个整数存入a数组中,再用指针的方法将a数组中的数据从小到大排序输出。完成程序的编写。
输入
输入2行,第1行是一个整数n;第2行有n个整数,整数之间用空格隔开。
输出
输出1行,包含n个从小到大的整数,整数之间用1个空格隔开。
输入样例 1 输出样例 1
10 5 6 8 10 12 19 21 23 61 98 23 21 5 98 19 12 6 10 8 61
具体实现
#include "stdio.h"
#define N0 100
void sortP(int a[], int n){ int *pi, *pj, t;for(pi=a; pi<a+n-1; pi++){for(pj=a; pj<a+n-1-(pi-a); pj++){if(*pj > *(pj+1)){t = *pj;*pj = *(pj+1);*(pj+1) = t;}}}
}
int main(){int a[N0], n, *p; scanf("%d", &n); for(p=a; p<a+n; p++){scanf("%d", p);} sortP(a, n);for(p=a; p<a+n-1; p++)printf("%d ", *p);printf("%d\n", *p);return 0;
}
4.4、 指向指针的指针排序程序
描述
用指向指针的指针方法将n个字符串存入a数组,再用指向指针的指针方法将n个字符串从小到大排序输出。完成程序的编写。
输入
输入n+1行,第1行是一个整数n;第2行到第n+1行每行有一个字符串。
输出
输出n行,每行包含1个字符串,n个字符串从小到大排序输出。
输入样例 1 输出样例 1
5 237MJ BNVC asdkf3& 2345aoqwer KJ657KHL KJHKlkdfd KJH386skdfl 237MJ BNVC KJHKlkdfd KJH386skdfl asdkf3& 2345aoqwer KJ657KHL
具体实现
#include <stdio.h>
#include <string.h>
const int N0=100;
void sortStrings(char a[][N0+1], int n ){char *pa[N0], **pi, **pj, t[N0+1];for(int i=0; i<n; i++)pa[i]=a[i];for(pi=&pa[0]; pi<&pa[0]+n-1; pi++){for(pj=&pa[0]; pj<&pa[0]+n-1-(pi-&pa[0]); pj++){if(strcmp(*pj, *(pj+1))>0){ strcpy(t, *pj);strcpy(*pj, *(pj+1));strcpy(*(pj+1), t);}}} }
int main(){char a[N0][N0+1], *pa[N0], **p;int n, i; scanf("%d ", &n);for(i=0; i<n; i++)pa[i]=a[i]; for(p=&pa[0]; p<&pa[0]+n; p++){gets(*p);}sortStrings(a, n); for(p=&pa[0]; p<&pa[0]+n; p++){puts(*p);}return 0;
}
4.5、 查找最大整数程序
描述
编写一个返回值为指针的函数,输出n个整数中的最大整数。完成程序的编写。
输入
输入2行,第1行是一个整数n;第2行有n个整数,整数之间用空格隔开。
输出
输出1行,包含1个整数,即n个数中最大的那个。
输入样例 1 输出样例 1
10 98 23 21 5 98 19 12 6 10 8 61
具体实现
#include "stdio.h"
const int N0=100;
int *maxInt( int a[], int n ){int *p, *pm;pm=a;for(p=a+1; p<a+n; p++){if(*p > *pm){pm=p;}}return pm;
}
int main(){int a[N0], n, *p;scanf("%d", &n); for(p=a; p<a+n; p++)scanf("%d", p);p=maxInt( a, n );printf("%d\n", *p );return 0;
}
4.6、学生成绩排序程序
描述
某班级有n个学生,每个学生都有3门课的成绩:语文、数学、英语。用指向结构体的指针将数据存入结构体数组,再编写一个返回值是指针的函数,输出总分最高的学生的学号和总分,如果有最高相同的总分,输出语文成绩高的那位,如果语文成绩仍然相同,则输出学号小的那位。完成程序的编写。
输入
输入n+1行:第1行为一个正整数n,表示该班级的学生人数。第2到n+1行,每行有3个用空格隔开的数字,第j行的3个数字依次表示学号为j-1的学生的语文、数学、英语的成绩。每个学生的学号按照输入顺序编号为l~n(恰好是输入数据的行号减1)。
输出
输出1行,每行有1个学号和1个总分,2个数据之间用空格隔开。
输入样例 1 输出样例 1
6 3 264 78 44 40 91 91 82 93 91 80 61 88 33 98 46 83 76 93 67
具体实现
#include "stdio.h"
const int N0=500;
struct node{int no; // 学号int c,m,e,total;
};node *maxTotal(node a[], int n){node *pm, *p;pm = a;for(p=a+1; p<a+n; p++){ if(p->total > pm->total){pm = p;}else if(p->total == pm->total){if(p->c > pm->c){pm = p;}else if(p->c == pm->c){if(p->no < pm->no){pm = p;}}}}return pm;
}
int main(){node a[N0], *p; int n, i; scanf("%d", &n);for(p=a,i=1; p<a+n; p++,i++){scanf("%d%d%d", &p->c, &p->m, &p->e );p->total=p->c + p->m + p->e; p->no=i;} p=maxTotal( a, n );printf("%d %d\n", p->no, p->total);return 0;
}
4.7、 字符串中整数求和程序
描述
将字符串中的正、负整数取出求和。如字符串“w&sk234 K3wzm3455kdf43dkf-56slk%9”中正、负整数取出的和=234+3+3455+43-56+9=3688,程序运行后输出3688。注意:
(1)需要考虑字符串中出现的正负号(+, -),即所有转换结果为正或负整数。
(2)空格为字符串的有效字符、不能忽略。例如,字符串"-□345.123"(□表示空格)应转换为-0,345,123三个整数,而不是-345和123两个整数!
(3)需要考虑'0'开始的数字字符串情况,比如"00035",应转换为整数35;"000"应转换为整数0;"00.0035"应转换为整数0和35(忽略小数点:mmm.nnn当成两个数mmm和nnn来识别)。
(4)不考虑转换后整数超出范围情况,即测试用例中可能出现的最大整数不会超过unsigned int可处理的范围;
(5)输入字符串不会超过100Bytes,请不用考虑超长字符串的情况。
完成程序的编写。
输入
输入1行,一个字符串。
输出
输出1个整数,是字符串中所有正、负整数的和。
输入样例 1 输出样例 1
w&sk234 K3wzm3455kdf43dkf-56slk%9 3688
具体实现
#include "stdio.h"
#include "string.h"
#include<iostream>
using namespace std;
int sumInt( char *s ){int sum=0, t=0, sign; char *p=s; bool inNumber=false;while(*p){if(!inNumber && *p>='0' && *p<='9'){inNumber = true;t = 0;if(p>s && *(p-1)=='-'){sign = -1;}else{sign = 1;}}if(inNumber && (*p < '0' || *p > '9')){inNumber = false;sum += t * sign;}if(inNumber){ t = t*10 + (*p-'0');}p++;}if(inNumber){sum += t * sign;}return sum;
}int main(){char s[1000+1]; cin.getline(s,1001); printf("%d\n", sumInt(s)); return 0;
}
4.8、 大正整数相加程序
描述
求2个大正整数之和。完成程序的编写。
输入
输入2行,每行是1个大正整数。
输出
输出1个整数,是上面2个大整数的和。
输入样例 1 输出样例 1
45656834234234095782376907905623 4565683432812444876471745770365893890352982340549798035
具体实现
#include <stdio.h>
#include<malloc.h>
#include <string.h>
#define MAXLEN 500
char num1[MAXLEN];
char num2[MAXLEN];
int i, j, n, r;
int L1, L2, L;
char *sum;
void reverse(char *s)
{n = strlen(s);i = 0, j = n - 1;while(i < j){char c = s[i];s[i] = s[j];s[j] = c;i++, j--;}
}
int main()
{r = n = 0;scanf("%s", num1);scanf("%s", num2);reverse(num1);reverse(num2);L1 = strlen(num1), L2 = strlen(num2);L = L1 > L2 ? L1 : L2;L += 2;sum = (char*)malloc(sizeof(char)*L);memset(sum, 0, L);L = L1 < L2 ? L1 : L2;for (i = 0; i < L; i++){n = num1[i] - '0' + num2[i] - '0';sum[i] = (r + n) % 10 + '0';r = (r + n) / 10;}if (L1 <= L2){while (i < L2){n = num2[i] - '0';sum[i] = (r + n) % 10 + '0';r = (r + n) / 10;i++;}}else{while (i < L1){n = num1[i] - '0';sum[i] = (r + n) % 10 + '0';r = (r + n) / 10;i++;}}if (r)sum[i] = r + '0';sum[i + 1] = 0;reverse(sum);printf("%s", sum);return 0;
}
4.9、 删除子字符串程序
描述
在主字符串中删除所有子字符串。完成程序的编写。
输入
输入2行,第1行是主字符串,第2行是子字符串。
输出
输出1行,即删除所有子字符串后的主字符串。
输入样例 输出样例
hyuaaaabcad;dsj2390aaabcadldkaaaaabcaaabcade hyua;dsj2390ldkaaaaabce aaabcad
具体实现
#include<stdio.h>
#include<string.h>const int N0=1000;char *index(char s[],char *sub){int i =0,j=0;char *p=sub;if(*sub == '\0') return NULL;char *pi=s,*pj=sub;while(*pi && *pj)if(*pi == *pj){pi++;pj++;}else{pi = pi-(pj-sub)+1;pj=sub;}if(*pj =='\0')return pi-(pj-sub);elsereturn NULL;}
int main(){char s[N0+1],sub[N0+1],*p,*q;int sublen;gets(s);gets(sub);sublen=strlen(sub);while(p=index(s,sub)){q=p+sublen;while(*p++=*q++);}puts(s);return 0;
}
4.10、 字符串替换程序
描述
输入3行字符串,分别是s字符串,t字符串和r字符串。如果s字符串中有包含t字符串,则用r字符串替换之。例如:s=“12aaabc3aaaaaabc#$%aaabc”,t=“aaabc”,r=“abc”,将s中的“aaabc”替换成“abc”之后,s=“12abc3aabc#$%abc”。输出替换之后的s字符串。完成程序的编写。
输入
输入3行字符串,分别是s字符串,t字符串和r字符串。
输出
输出将s字符串中包含的t字符串,用r字符串替换之,输出替换之后的s字符串。
输入样例 1 输出样例 1
ALKJFOE23DLS67AFAOE ALKJFXYZ23DLS67AFAXYZ OE XYZ
具体实现
#include<stdio.h>
#include<string.h>const int N0=1000;char *index(char s[],char *sub){int i =0,j=0;char *p=sub;if(*sub == '\0') return NULL;char *pi=s,*pj=sub;while(*pi && *pj)if(*pi == *pj){pi++;pj++;}else{pi = pi-(pj-sub)+1;pj=sub;}if(*pj =='\0')return pi-(pj-sub);elsereturn NULL;}
void insStr(char *s,char *r ,char *p){char *pi,*pj;int i,j;int len=strlen(r);for(i=strlen(s);i>=p-s;i--)s[i+len]=s[i];for(i=p-s,j=0;r[j];i++,j++)s[i]=r[j];
}
int main(){char s[N0+1],t[N0+1],r[N0+1],*p,*p1,*q;int tlen;gets(s);gets(t);gets(r);tlen=strlen(t);while(p=p1=index(s,t)){q=p+tlen;while(*p++=*q++);insStr(s,r,p1);} puts(s);return 0;}
4.11、 有序表合并去重程序
描述
有2个从小到大已经排序好的(有序)表,每个结点的数据是1个整数,已知两个表的数据存放在带头结点的单向链表中,将2个有序表合并成1个新的有序表,要求新的有序表中去掉重复相同的数据。完成程序的编写。
输入
输入4行,第1行有1个整数n,即第1个表的结点数,第2行有n个整数;第3行有1个整数m,即第2个表的结点数,第4行有m个整数。整数之间用空格隔开。
输出
输出1行,将上述2个表的数据从小到大排序输出,数据中没有相同项,每个整数之后输出1个空格。
输入样例 1 输出样例 1
6 -5 3 6 8 11 25 43 67 84 92 96 99 3 6 11 25 67 84 10 -5 3 8 25 25 43 67 92 96 99
具体实现
#include "stdio.h"
const int INF=0x7fffffff; //无穷大整数
struct ND
{ int data; struct ND *next;
};ND *createLink( )
{ ND *head, *p;int n; head = p = new ND; scanf("%d", &n);while( n-- ){ p->next = new ND; p = p->next; scanf("%d", &p->data); }p->next = NULL; return head;
}
void printLink( ND *head )
{ ND *p=head->next; if( p==NULL )return ;while( p ){ printf( "%d ",p->data );p=p->next;}printf("\n");
}void deleteLink( ND *head)
{ ND *p=head;while( p ){ head = p->next;delete p;p = head;}
}ND * megerLink( ND *ha, ND *hb ) //合并2有序表,返回合并后链表头结点的地址
{ ND *pa=ha->next, *pb=hb->next, *hc, *pc;int data, lastData=INF; //lastData为上一个结点的数据项,用于判定是否有相同数据hc=pc=new ND;
//************************************************while(pa || pb){if(pa&&(pb==NULL || pa->data <= pb -> data)){data= pa->data;pa=pa->next; }else{data =pb->data;pb = pb->next;}if(data != lastData){pc->next=new ND;pc=pc->next;pc->data=data;lastData=data;}} pc->next=NULL;return hc;
//=================================================return hc;
}
int main()
{ ND *ha, *hb, *hc;//freopen( "sc6_6b.in", "r", stdin);//freopen( "sc6_6b.out", "w", stdout);ha = createLink();hb = createLink();hc = megerLink( ha, hb );printLink( hc );deleteLink( ha );deleteLink( hb );deleteLink( hc );return 0;}
4.12、 有序表交集合并程序
描述
有2个从小到大已经排序好的(有序)表,每个结点的数据是1个整数,已知两个表的数据存放在带头结点的单向链表中,将2个有序表合并成1个新的有序表,并要求新表中仅包含2个原表的交集。完成程序的编写。
输入
输入4行,第1行有1个整数n,即第1个表的结点数,第2行有n个整数;第3行有1个整数m,即第2个表的结点数,第4行有m个整数。整数之间用空格隔开
输出
输出1行,将上述2个表数据的交集从小到大排序输出,每个整数之后输出1个空格。
输入样例 1 输出样例 1
7 3 25 67 92 3 6 11 25 67 84 92 10 -5 3 8 25 25 43 67 92 96 99
具体实现
#include "stdio.h"
const int INF=0x7fffffff; //无穷大整数
struct ND
{ int data; struct ND *next;
};ND *createLink( )
{ ND *head, *p;int n; head = p = new ND; scanf("%d", &n);while( n-- ){ p->next = new ND; p = p->next; scanf("%d", &p->data); }p->next = NULL; return head;
}
void printLink( ND *head )
{ ND *p=head->next; if( p==NULL )return ;while( p ){ printf( "%d ",p->data );p=p->next;}printf("\n");
}void deleteLink( ND *head)
{ ND *p=head;while( p ){ head = p->next;delete p;p = head;}
}ND * megerLink( ND *ha, ND *hb ) //合并2有序表,返回合并后链表头结点的地址
{ ND *pa=ha->next, *pb=hb->next, *hc, *pc;int data, lastData=INF; //lastData为上一个结点的数据项,用于判定是否有相同数据hc=pc=new ND;
//************************************************while(pa || pb){if(pa&&(pb==NULL || pa->data<=pb->data)){if(pb&&pa->data==pb->data)data = pa->data;elsedata = -INF;pa=pa->next;}else{if(pa&& pa->data == pb->data)data=pa->data;elsedata =-INF;pb=pb->next;}if(data != -INF && data != lastData){pc->next=new ND;pc=pc->next;pc->data=data;lastData=data;}}pc->next=NULL;return hc;
}
int main()
{ ND *ha, *hb, *hc;
// freopen( "sc6_6c.in", "r", stdin);
// freopen( "sc6_6c.out", "w", stdout);ha = createLink();hb = createLink();hc = megerLink( ha, hb );printLink( hc );deleteLink( ha );deleteLink( hb );deleteLink( hc );return 0;
}