吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 932|回复: 9
收起左侧

[学习记录] C Primer Plus 8章练习题

[复制链接]
forestlxg 发表于 2022-7-20 10:21
[C] 纯文本查看 复制代码
#include<stdio.h>
#include<stddef.h>
#include<ctype.h>
#define OFF15 0.15
#define OFF20 0.2
#define OFF25 0.25
#define PAY1 8.75
#define PAY2 9.33
#define PAY3 10.0
#define PAY4 11.20
char get_first(void);
float paycon(float p);
float get_a_num(void);
char show_menu_8(void);
int main(void)
{
        int i,j,k,flag,guess;
        float m,n;
        char ch;
    //8.1   此段程序编译后,输入文件内如果有回车符,则算做一个字符。
       i=0;    //字符数统计。
        while((ch=getchar())!=EOF)
            ++i;
        printf("文件中共有%d个字符\n",i);
        getchar();

    //8.2
    i=1;//每行打印控制
    while((ch=getchar())!=EOF)
       { 
        switch (ch)
        {
            case '\t':
                printf("\\t");
                putchar(ch);    
                printf("的ASCII码是%d。",ch);//打印ASCII码
                break;
            case '\n':
                printf("\\n");    
                printf("的ASCII码是%d。",ch);//打印ASCII码
                putchar(ch);               
                break;
            default:
                if (ch<=31)
                    {
                        printf("^");
                        putchar(ch+64);
                        //printf("%c",ch+64);
                        printf("的ASCII码是%d。",ch);//打印ASCII码
                    }
                else
                    {
                        putchar(ch);    
                        printf("的ASCII码是%d。",ch);//打印ASCII码  
                    }
        }
            ++i;
        if (i>10)   //每行10个字符
           {
               printf("\n");
               i=0;
           }
       }
       getchar();   

    //8.3
    i=0;//大写字母计数。
    j=0;//小写字母计数。
    k=0;//数字计数。
    while ((ch=getchar())!=EOF)
            if (isdigit(ch))
                k++;
            else if (isupper(ch))
                i++;
            else if (islower(ch))
                j++;
    printf("在文件中,大写字母共%d个,小写字母共%d个,数字共%d个\n",i,j,k);
    getchar();        
 
    //8.4
    i=0;//单词字母个数统计。
    j=0;//单词个数统计。
    m=0;//平均每个单词字母个数初始化。
    flag=0;//标志位,去除文件开头空格。
    while((ch=getchar())!=EOF)
        {
            if (!ispunct(ch))   //去除标点
                if(!isspace(ch))
                    flag=1; //去除文件开头空格。
                if (ch==' '&& flag!=0)    
                        j++;//已经计数一个单词。
                if (ch!=' '&& flag==1 && !ispunct(ch))
                    i++;    //非空非标点字符,计数一次。
               
        }
    j++; //EOF前最后一个单词。
    m = (float)i/(float)j;      //强制转换整型为浮点型。
    printf("文件中共有%d个单词,共有%d个字母,平均每个单词%.2f个字母\n",j,i,m);
    getchar();


    //8.5
    i=1;        //下限
    j=100;      //上限
    k=i+(j-i)/2;      //二分法的中值。
    printf("选择一个1到100的整数,我试着猜猜它\n");
    scanf("%d",&guess);     //用户输入待猜的数字。
    getchar();
    printf("如果我的猜测是对的,用y回答,如果是错的,用n回答\n");
    while(i<=j)
    {
        printf("嗯...你的数字是%d?\n",k);
        scanf("%c",&ch);        //是否为你输入的数
        getchar();
        if (ch=='y')
            {
                printf("我知道我可以猜到!\n");
                break;
            }
        else if (ch=='n')
                {
                    printf("%d是大了吗?请输入y/n\n",k);
                    scanf("%c",&ch);
                    getchar();
                    if (ch=='y')
                        {
                            j=k-1;      //从中间值向前查找,修改上限。
                            k=i+(j-i)/2;        //修改中间值。
                        }
                    else
                        {
                            i=k+1;      //从中间值向后查找,修改下限。
                            k=i+(j-i)/2;      //修改中间值。
                        }
                }
            else
                printf("对不起,我只明白y或n,请重新输入\n");
    }
    if(i>j)         //此处检测上下限的值,如果下限大于大限,还没有确认,就是作弊了。
                    //因为前面break语句和正常猜到数字后都会退出循环。
        printf("你作弊了!!\n");       
    else
        printf("你输入的数就是%d\n",k); 
    getchar();


    //8.6
    ch=get_first();
    if (ch=='\n')
        printf("你输入的为空字符\n");
    else
        printf("第一个非空字符为%c\n",ch);
    getchar();
   
    //8.7
    printf("*****************************************************************\n");
    printf("Enter the number corresponding to the desired pay rate or cation:\n");
    printf("a) $8.75/hr                          b) $9.33/hr\n");
    printf("c) $10.00/hr                         d) $11.20/hr\n");
    printf("q) quit\n");
    printf("*****************************************************************\n");
    ch=getchar();
    getchar();
    while(1)
    {    
        switch (ch)
        {
            case 'a':
            case 'A':
                {paycon(PAY1);
                break;}
            case 'b':
            case 'B':
                {paycon(PAY2);
                break;}
            case 'c':
            case 'C':
                {paycon(PAY3);
                break;}
            case 'd':
            case 'D':
                {
                    paycon(PAY4);
                    break;
                }
            case 'q':
            case 'Q':
                goto bey;
            default :
                {
                    printf("请输入1-5之间的数字\n");
                    break;
                }
        }
        printf("*****************************************************************\n");
        printf("Enter the number corresponding to the desired pay rate or cation:\n");
        printf("a) $8.75/hr                          b) $9.33/hr\n");
        printf("c) $10.00/hr                         d) $11.20/hr\n");
        printf("q) quit\n");
        printf("*****************************************************************\n");
        ch=getchar();
        getchar();
    }
    bey:printf("DONE!\n");
    getchar();
    getchar();    

    //8.8
    char ch3;       //存储运算符。
    float resultn;      //计算结果。
    show_menu_8();      //菜单显示函数。
    ch=getchar();
    getchar();
    while (!(ch=='Q'||ch=='q'))     //按Q退出。
    {
        printf("Enter first number:\n");
        m=get_a_num();
        printf("Enter second number:\n");
        n=get_a_num(); 
        switch (ch)
        {
            case 'a':
            case 'A':
                resultn=m+n;
                ch3='+';
                break;

            case 's':
            case 'S':
                resultn=m-n;
                ch3='-';
                 break;
            case 'm':
            case 'M':
                resultn=m*n;
                ch3='*';
                break;
            case 'd':
            case 'D':
                if(n==0)        //除数不能为0。
                    {
                        printf("Enter a number other than 0:\n");
                        n=get_a_num();
                    }
                resultn=m/n;
                ch3='/';
                break;
            }
            printf("%.2f%c%.2f=%.2f\n",m,ch3,n,resultn);
            show_menu_8();
            getchar();
            ch=getchar();
            getchar();     
    }   
        printf("DONE\n");
    
    getchar();
    getchar();
    return 0;
}
float get_a_num(void)
{
    float num;
    char ch;
    while (scanf("%f",&num)!=1)
        {
            while((ch=getchar())!='\n')     //如果SCANF函数接收的不是数字,则输入的字符返回输入队列,所以GETCHAR()可以接受到完整的字符。
                putchar(ch);
            printf(" is not a number,\n");
            printf("Please enter a number,such as 2.5,-1.78E8,or 3:\n");
        }
    return num;
}

char get_first(void)
{
    int flag=0;     //初始化标志位,如果有非空字符,flag设置为1。
    char ch;
    while ((ch=getchar())!='\n')
    {
        if(isspace(ch))
            continue;
        else
            {
                flag=1;
                break;
            }
    }
        if (flag==1)
            return ch;
        else 
            return '\n';
}
float paycon(float p)
{
    int i,j;
    float m,n,q;
    q=p;
    printf("请输入一周工作小时数");
    scanf("%d",&i);
    if (i<=40)
            m=i*q;
    else  
            m=40*q+(i-40)*q*1.5;
    if (m<=300)
        n=m*OFF15;
    else if (m<=450)
        n=300*OFF15+(m-300)*OFF20;
    else if (m>450)
        n=300*OFF15+150*OFF20+(m-450)*OFF25;
    return (printf("您本周工作时间为%d小时,收入为%.0f元,税费为%.2f元\n",i,m,n));
}
char show_menu_8()
{
    printf("*****************************************************************\n");
    printf("Enter the operation of your choice:\n");
    printf("a. add                          s.subtract\n");
    printf("m.multiply                      d.divide\n");
    printf("q. quit\n");
    printf("*****************************************************************\n"); 
    return 0;
}

第八章练习题.txt

9.68 KB, 下载次数: 0, 下载积分: 吾爱币 -1 CB

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Supermexyh 发表于 2022-7-20 11:05
楼主做完这个后会做LeetCode第一题吗 https://leetcode.cn/problems/two-sum/
zhaomingzhi 发表于 2022-7-20 12:32
25535 发表于 2022-7-20 13:53
Supermexyh 发表于 2022-7-20 11:05
楼主做完这个后会做LeetCode第一题吗 https://leetcode.cn/problems/two-sum/

1、num_tmp=target  -nums
2、查找num_tmp得出两个角标

免费评分

参与人数 1吾爱币 +3 热心值 +1 收起 理由
Supermexyh + 3 + 1 用心讨论,共获提升!

查看全部评分

Supermexyh 发表于 2022-7-20 14:08
25535 发表于 2022-7-20 13:53
1、num_tmp=target  -nums
2、查找num_tmp得出两个角标

我以为你是新手,却没想到你竟然是老鸟
25535 发表于 2022-7-20 14:12
Supermexyh 发表于 2022-7-20 14:08
我以为你是新手,却没想到你竟然是老鸟

我是低级程序猿
25535 发表于 2022-7-20 14:14
本帖最后由 25535 于 2022-7-20 14:20 编辑
Supermexyh 发表于 2022-7-20 14:08
我以为你是新手,却没想到你竟然是老鸟

我具体没有写,思路是这样。力扣 还得考虑复杂度
 楼主| forestlxg 发表于 2022-7-20 14:55
本帖最后由 forestlxg 于 2022-7-20 15:00 编辑
Supermexyh 发表于 2022-7-20 11:05
楼主做完这个后会做LeetCode第一题吗 https://leetcode.cn/problems/two-sum/

[C] 纯文本查看 复制代码
int* twoSum(int* nums, int numsSize, int target, int* returnSize){

int i,j;//数组下限,数组中值。

for(i=0;i<numsSize;i++)
    for(j=i+1;j<numsSize;j++)
        if(*(nums+i)+*(nums+j)==target)
             *(returnSize)=i,*(returnSize+1)=j;
return *returnSize
}
 楼主| forestlxg 发表于 2022-7-20 15:05
Supermexyh 发表于 2022-7-20 11:05
楼主做完这个后会做LeetCode第一题吗 https://leetcode.cn/problems/two-sum/

我的解,是最笨的暴力法。这个是要用算法的。目前,还没多少算法的知识储备。只是先把C捡起来。上学时学过,然后都还给老师了。目前就是重温一下C。然后再看算法。
LogerLaw 发表于 2022-7-20 15:49
本帖最后由 LogerLaw 于 2022-7-20 15:53 编辑
Supermexyh 发表于 2022-7-20 11:05
楼主做完这个后会做LeetCode第一题吗 https://leetcode.cn/problems/two-sum/

四楼的答案时间复杂度是O(n^2),不满足进阶要求
我的算法:
1.先将数组用时间复杂度小于O(n^2)的排序算法从小到大排序,如归并排序O(nlogn)等。题目既然只考虑整数则可使用基数排序O(n)。记录排序前后数组下标对应关系
2.既然两数之和等于target,假设n1+n2==target,n1<n2,那一定有n1<=target/2,n2>=target/2。那么遍历排好序的数组,直至发现target/2交界的位置,假设是i、j。j=i+1,num[ i]<=target/2,num[j]>=target/2
3.循环计算num[ i]+num[j],判断与target的大小关系,小于target则j++,大于target则i--,直至发现等于target的下标ij或到达数组一端也没发现满足条件的
4.将3中找到的下标还原原数组下标
这个算法时间复杂度是O(n)
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 11:52

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表