鱼C论坛

 找回密码
 立即注册
查看: 1313|回复: 5

[已解决]关于C语言课后作业S1E15,求教!!!

[复制链接]
发表于 2021-11-25 21:31:33 | 显示全部楼层 |阅读模式
21鱼币
1. 求 10000 以内的素数个数
  1. #include <stdio.h>

  2. int main()
  3. {
  4.         int count = 2; // 已知2和3是素数
  5.         int i, j;
  6.         _Bool flag = 1;

  7.         for (i = 5; i < 10000; i++)
  8.         {
  9.                 for (j = 2; j < i / 2; j++)
  10.                 {
  11.                         if (i % j == 0)
  12.                         {
  13.                                 flag = 0;
  14.                                 break;
  15.                         }
  16.                 }

  17.                 if (flag)
  18.                 {
  19.                         count++;
  20.                 }
  21.                 else
  22.                 {
  23.                         flag = 1;
  24.                 }
  25.         }

  26.         printf("10000以内共有%d个素数!\n", count);

  27.         return 0;
  28. }
复制代码

i为啥要从5开始,2和3也是素数啊,从5开始最后的结果不就不准了吗?还有为啥if后面还有个else {flag = 1}; 只要是素数,从头到尾flag不都是1吗?有什么作用呢?

3. 写一个凯撒加密程序。
  1. #include <stdio.h>

  2. int main()
  3. {
  4.         int ch;

  5.         printf("请输入明文:");

  6.         while ((ch = getchar()) != '\n')
  7.         {
  8.                 if (ch >= 'a' && ch <= 'z')
  9.                 {
  10.                         putchar('a' + (ch - 'a' + 3) % 26);
  11.                         continue;
  12.                 }

  13.                 if (ch >= 'A' && ch <= 'Z')
  14.                 {
  15.                         putchar('A' + (ch - 'A' + 3) % 26);
  16.                         continue;
  17.                 }

  18.                 putchar(ch);
  19.         }

  20.         putchar('\n');

  21.         return 0;
  22. }
复制代码

putchar('a' + (ch - 'a'+3)%26);  是什么意思啊,换算成整型来计算的话,(ch-'a'+3)怎么都不可能打过26把,求余以后不是0就是1再加上'a'怎么可能做到向后偏移两位的,这是为什么啊?求大佬指点!!!
最佳答案
2021-11-25 21:31:34
第一个问题:
就像你说的2和3也是素数,因为这两个很简单嘛,人用脑一算就知道了,所以就不需要用程序去算,
直接从5开始,这样就省去2.3.4(3次循环),省去了一点点点点点的程序运行时间。

另外,结果并不会不准,因为在程序的第5行:int count = 2; /就已经将(2和3)算进去了。
再另外,else {flag = 1}这个语句,相当于使每一次进入第一个for循环(第9行的)确保flag = 1;
然后进入第二个for循环(第11行的),若该数不是素数,那么它就能满足第13行的if语句,使flag = 0;并退出这个for循环,
此时flag = 0 不满足 第20行的if语句;所以执行else;
把flag 重新赋值为 1;使其进入下次循环,flag的值还是为1;

第二个问题:
1.首先,(ch - 'a'+3)%26)这个表达式的结果不只是0和1;
对26取余,结果为0-25之间的任何一个数;

2.至于('a' + (ch - 'a'+3)%26)这个怎么计算,那么咱们简单的举个例子:
就已简单的字符ch = ‘ a ’为例;
带入('a' + (ch - 'a'+3)%26) = ‘a’ +(‘a’ - ‘a’ + 3)%26 = ‘a’ +3%26 = ‘a’ + 3
结果是 "a"+ 3 ,在编译器中这个计算就是用‘a’的ASCII码值+3;得到的数值在对照ASCII表转换为字符型的值;
当然咱们不用这么费事:这次从a向后数3个字符就行:
b、c、b,所以结果就是‘d’

综上:经过程序,把输入的‘a’变成了‘d’;
同理:输入其他的也一样:就是往后面数偏移多少位就行;

最佳答案

查看完整内容

第一个问题: 就像你说的2和3也是素数,因为这两个很简单嘛,人用脑一算就知道了,所以就不需要用程序去算, 直接从5开始,这样就省去2.3.4(3次循环),省去了一点点点点点的程序运行时间。 另外,结果并不会不准,因为在程序的第5行:int count = 2; /就已经将(2和3)算进去了。 再另外,else {flag = 1}这个语句,相当于使每一次进入第一个for循环(第9行的)确保flag = 1; 然后进入第二个for循环(第11行的),若该数 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-25 21:31:34 | 显示全部楼层    本楼为最佳答案   
第一个问题:
就像你说的2和3也是素数,因为这两个很简单嘛,人用脑一算就知道了,所以就不需要用程序去算,
直接从5开始,这样就省去2.3.4(3次循环),省去了一点点点点点的程序运行时间。

另外,结果并不会不准,因为在程序的第5行:int count = 2; /就已经将(2和3)算进去了。
再另外,else {flag = 1}这个语句,相当于使每一次进入第一个for循环(第9行的)确保flag = 1;
然后进入第二个for循环(第11行的),若该数不是素数,那么它就能满足第13行的if语句,使flag = 0;并退出这个for循环,
此时flag = 0 不满足 第20行的if语句;所以执行else;
把flag 重新赋值为 1;使其进入下次循环,flag的值还是为1;

第二个问题:
1.首先,(ch - 'a'+3)%26)这个表达式的结果不只是0和1;
对26取余,结果为0-25之间的任何一个数;

2.至于('a' + (ch - 'a'+3)%26)这个怎么计算,那么咱们简单的举个例子:
就已简单的字符ch = ‘ a ’为例;
带入('a' + (ch - 'a'+3)%26) = ‘a’ +(‘a’ - ‘a’ + 3)%26 = ‘a’ +3%26 = ‘a’ + 3
结果是 "a"+ 3 ,在编译器中这个计算就是用‘a’的ASCII码值+3;得到的数值在对照ASCII表转换为字符型的值;
当然咱们不用这么费事:这次从a向后数3个字符就行:
b、c、b,所以结果就是‘d’

综上:经过程序,把输入的‘a’变成了‘d’;
同理:输入其他的也一样:就是往后面数偏移多少位就行;

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-25 22:54:25 | 显示全部楼层
..
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-11-25 23:27:01 | 显示全部楼层
番杰 发表于 2021-11-25 21:31
第一个问题:
就像你说的2和3也是素数,因为这两个很简单嘛,人用脑一算就知道了,所以就不需要用程序去算 ...

卧槽,豁然开朗,感谢大佬!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-26 00:01:35 | 显示全部楼层
       【问题 1】:代码使用了穷举因子的方式在判定素数。在开始判断前前,先假定目标数就是一个素数(flag = 1),然后,按照从小到大的顺序,从所有比目标数小的数中,循环枚举目标数可能的因子,如果真的找到了任何一个因子(可以整除目标数),那么,就对前面的假设加以否定(flag = 0),并立即结束循环(break);反之,如果一直到循环结束也没有能够找到目标数的任何一个因子,那就说明前面的假设成立,目标数真的就是一个素数。循环结束后,根据 flag 的数值,就可以断定目标数是否属于素数。
       【问题 2】:凯撒密码是采用字母错位的方法进行加密的,明文和密文都是字母,在本例中加密采用
  1. 密文 = 明文 + 3
复制代码

        的规律进行加密,例如,字母 'a' -> 'd','b' -> 'e','c' -> 'f' . . .,'A' -> 'D','B' -> 'E' ,'C' -> 'F',... 显然,对于字母表比较位置靠前字母的加密比较好办,对于位置靠后的字母,加密过后,可能就会超过所属字母的范围,例如,'w' -> 'z' 那么,后续字母 'x'、'y' 、'z' 加密过后肯定会超出所属的字母表,那么,应该怎么办?按照规则,如果密文字符 ASCII 编码超出,应该自动回卷,就是说,'x' -> 'a'、'y' -> 'b'、'z' -> 'c'。取余操作正好可以满足自动回卷的要求。
        我们知道,字母表中每个字母的 ASCII 编码是按照其字母表位置顺序连续变化的。
  1. 小写字母 - 'a'
  2. 大写字母 - 'A'
复制代码

        一个字母被像上面这样减过以后,会得到一个 0~25 变化的数值,这个数值加过 3 以后
  1. 小写字母 - 'a' + 3
  2. 大写字母 - 'A' + 3
复制代码

       这个数值范围变为 3 ~ 28,我们需要把这个范围再次调整到 0 ~ 25 的范围,怎么办?让这个值对 26 取余就可以了
  1. (小写字母 - 'a' + 3) % 26
  2. (大写字母 - 'A' + 3) % 26
复制代码

       这样,把这个数值再加上相应的字母表开头字母的 ASCII 编码,得到的就是密文字符了。
  1. 'a' + (小写字母 - 'a' + 3) % 26
  2. 'A' + (大写字母 - 'A' + 3) % 26
复制代码

      
      
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-26 12:03:41 | 显示全部楼层
凯撒加密是什么意思
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 02:59

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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