鱼C论坛

 找回密码
 立即注册
查看: 1503|回复: 14

[已解决]S1E32猴子排序问题

[复制链接]
发表于 2021-10-8 20:01:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>

  4. int in_order(int array[], int length);
  5. void shuffle(int array[], int length);
  6. void bogo_sort(int array[], int length);

  7. int in_order(int array[], int length)
  8. {
  9.         int i = 0;

  10.         while (array[i] <= array[i+1] && ++i < length - 1)
  11.                 ;

  12.         if (i == length - 1)
  13.         {
  14.                 return 1;
  15.         }
  16.         else
  17.         {
  18.                 return 0;
  19.         }
  20. }

  21. void shuffle(int array[], int length)
  22. {
  23.         int index, temp, i;
  24.         static int t1, t2;

  25.         srand(t1);
  26.         t1 = rand();

  27.         t2 = time(NULL);
  28.         srand(t1+t2);

  29.         for (i = 0; i < length; i++)
  30.         {
  31.                 index = rand() % (length - i) + i;
  32.                 if (index != i)
  33.                 {
  34.                         temp = array[i];
  35.                         array[i] = array[index];
  36.                         array[index] = temp;
  37.                 }
  38.         }
  39. }

  40. void bogo_sort(int array[], int length)
  41. {
  42.         while (!in_order(array, length))
  43.         {
  44.                 shuffle(array, length);
  45.         }
  46. }

  47. int main(void)
  48. {
  49.         int array[] = {73, 108, 111, 118, 101, 70, 105, 104, 67};
  50.         int i, length;
  51.         time_t begin, end;

  52.         begin = time(NULL);

  53.         length = sizeof(array) / sizeof(array[0]);
  54.         
  55.                 bogo_sort(array, length);

  56.         printf("排序后的结果是:");
  57.         for (i = 0; i < length; i++)
  58.         {
  59.                 printf("%d ", array[i]);
  60.         }
  61.         putchar('\n');

  62.         end = time(NULL);
  63.         printf("总共耗时:%ld秒\n", end - begin);

  64.         return 0;
  65. }
复制代码


  1. #include <stdio.h>
  2. #include <time.h>
  3. #include <stdlib.h>

  4. int in_order(int array[], int length);
  5. void shuffle(int array[], int length);
  6. void bogo_sort(int a[], int n);

  7. int in_order(int array[], int length)//判断洗牌后的数组中数字是否顺序排列
  8. {
  9.         int i = 0;
  10.        
  11.         while(array[i] < array[i+1] && ++i < length -1)
  12.                 ;
  13.                
  14.         if (i == length - 1)
  15.         {
  16.                 return 1;
  17.         }
  18.         else
  19.         {
  20.                 return 0;
  21.         }
  22. }

  23. void shuffle(int array[], int length)// 随机排序
  24. {
  25.         int index, temp, i;
  26.                                
  27.         srand(time(NULL));        //rand(time(NULL)) 获得随机数的间隔是 1 秒 1 次
  28.        
  29.         for (i = 0;i < length;i++)
  30.         {
  31.                 index = rand() % (length - i) + i;
  32.                 if (index != i)
  33.                 {
  34.                         temp = array[index];
  35.                         array[index] = array[i];
  36.                         array[i] = temp;
  37.                 }
  38.         }
  39. }

  40. void bogo_sort(int array[], int length) //当与目标字符串一致时跳出循环
  41. {
  42.         while (!in_order(array, length))
  43.         {
  44.                 shuffle(array, length);
  45.         }       
  46. }

  47. int main(void)
  48. {
  49.         int array[] = {73, 108, 111, 118, 101, 70, 105, 104, 67};
  50.         int i, length;
  51.         time_t begin, end;

  52.         begin = time(NULL); //time:获取当前系统时间(UTC时间)的time_t值

  53.         length = sizeof(array) / sizeof(array[0]);
  54.         bogo_sort(array, length);

  55.         printf("排序后的结果是:");
  56.         for (i = 0; i < length; i++)
  57.         {
  58.                 printf("%d ", array[i]);
  59.         }
  60.         putchar('\n');

  61.         end = time(NULL);
  62.         printf("总共耗时:%ld秒\n", end - begin);

  63.         return 0;
  64. }
复制代码


请问这两个程序在dev C++中运行,为什么运行时间会这么长,运行很久都得不出结果?
最佳答案
2021-10-8 20:40:59
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>

  4. void swap(void *a, void *b) {
  5.     unsigned char *p = a;
  6.     unsigned char *q = b;
  7.     unsigned char tmp;
  8.     tmp = *p;        
  9.     *p = *q;         
  10.     *q = tmp;        
  11. }

  12. void shuffle(void *x, int size_elem, int total_elem) {
  13.     int i = total_elem - 1;            
  14.     for(i ; i >= 0; --i) {
  15.         int r = rand() % (i+1);
  16.         swap(x + r*size_elem, x + i*size_elem);
  17.     }                 
  18. }

  19. int main(int argc, char *argv[]) {
  20.     time_t begin, end;
  21.     begin = time(NULL);
  22.     srand((unsigned)time(NULL));
  23.     int l[] = {73, 108, 111, 118, 101, 70, 105, 104, 67};
  24.     int n;
  25.     n = sizeof(l)/sizeof(l[0]);
  26.     int isSort = 0;
  27.     int i;
  28.     while(!isSort) {
  29.         shuffle(l, sizeof(l[0]), n);
  30.         isSort = 1;
  31.         for(i = 0; i < n-1; i++) {
  32.             if (l[i] > l[i+1]){
  33.                 isSort = 0;
  34.                 break;
  35.             }
  36.         }
  37.     }
  38.     end = time(NULL);
  39.     for(int i=0; i<9; i++){
  40.         printf("%d ", l[i]);
  41.     }
  42.     printf("\n总共耗时:%ld秒\n", end - begin);
  43. }
复制代码
  1. 67 70 73 101 104 105 108 111 118
  2. 总共耗时:0秒
复制代码
45.png
1876.png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-10-8 20:13:27 | 显示全部楼层
你真的认真读了这份代码吗?
代码里面写的很清楚了吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-8 20:13:27 | 显示全部楼层
猴子排序本来就是效率极低的方法
其最坏时间复杂度:无限
平均时间复杂度:O(n*n!)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-8 20:21:26 | 显示全部楼层
傻眼貓咪 发表于 2021-10-8 20:13
猴子排序本来就是效率极低的方法
其最坏时间复杂度:无限
平均时间复杂度:O(n*n!)

“对 9 个整数进行 10 次排序,最差的结果是 10 秒钟,最快在 1 秒钟内可以得出结果”,那示例的演示结果用时最长10秒是偶然事件?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-8 20:22:04 | 显示全部楼层
qiuyouzhi 发表于 2021-10-8 20:13
你真的认真读了这份代码吗?
代码里面写的很清楚了吧

还请您指点
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-8 20:40:59 | 显示全部楼层    本楼为最佳答案   
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>

  4. void swap(void *a, void *b) {
  5.     unsigned char *p = a;
  6.     unsigned char *q = b;
  7.     unsigned char tmp;
  8.     tmp = *p;        
  9.     *p = *q;         
  10.     *q = tmp;        
  11. }

  12. void shuffle(void *x, int size_elem, int total_elem) {
  13.     int i = total_elem - 1;            
  14.     for(i ; i >= 0; --i) {
  15.         int r = rand() % (i+1);
  16.         swap(x + r*size_elem, x + i*size_elem);
  17.     }                 
  18. }

  19. int main(int argc, char *argv[]) {
  20.     time_t begin, end;
  21.     begin = time(NULL);
  22.     srand((unsigned)time(NULL));
  23.     int l[] = {73, 108, 111, 118, 101, 70, 105, 104, 67};
  24.     int n;
  25.     n = sizeof(l)/sizeof(l[0]);
  26.     int isSort = 0;
  27.     int i;
  28.     while(!isSort) {
  29.         shuffle(l, sizeof(l[0]), n);
  30.         isSort = 1;
  31.         for(i = 0; i < n-1; i++) {
  32.             if (l[i] > l[i+1]){
  33.                 isSort = 0;
  34.                 break;
  35.             }
  36.         }
  37.     }
  38.     end = time(NULL);
  39.     for(int i=0; i<9; i++){
  40.         printf("%d ", l[i]);
  41.     }
  42.     printf("\n总共耗时:%ld秒\n", end - begin);
  43. }
复制代码
  1. 67 70 73 101 104 105 108 111 118
  2. 总共耗时:0秒
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-8 21:10:13 | 显示全部楼层

你可以去查一下这个 Bogo 排序,
它的本质是用随机数作为下标来排序,每随机完一次就检查一遍是否排好序了。
所以它的排序时间就是靠运气的。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-8 21:23:08 | 显示全部楼层
qiuyouzhi 发表于 2021-10-8 21:10
你可以去查一下这个 Bogo 排序,
它的本质是用随机数作为下标来排序,每随机完一次就检查一遍是否排好序 ...

谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-9 12:23:39 | 显示全部楼层

您这个程序思路上和参考程序一致,为什么运行结果更快,最多一秒,而示例程序运行时间不定?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-9 13:36:44 | 显示全部楼层
本帖最后由 傻眼貓咪 于 2021-10-9 13:37 编辑

你的代码第15行多了个冒号 ; 而且输出结果也不正确
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-9 14:54:13 | 显示全部楼层
傻眼貓咪 发表于 2021-10-9 13:36
你的代码第15行多了个冒号 ; 而且输出结果也不正确

这里的;不是多余,只是循环体为空,相当于下面这段
  1. int i = 0;
  2.                 int count = 0;
  3.         while (array[i] <= array[i+1] && i < length -1 )
  4.         {
  5.                  count++;
  6.                 }

  7.         if (count == length - 1)
  8.         {
  9.                 return 1;
  10.         }
  11.         else
  12.         {
  13.                 return 0;
  14.         }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-9 15:13:52 | 显示全部楼层
雨中漫步~ 发表于 2021-10-9 14:54
这里的;不是多余,只是循环体为空,相当于下面这段

变成无限循环
范例:
  1. #include <stdio.h>

  2. int main()
  3. {
  4.     while(1)
  5.     ;
  6.    
  7.     printf("program is end!");
  8.     return 0;
  9. }
复制代码
这里永远不会打印 "program is end!",因为上面的 while 无限循环
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-9 15:47:57 | 显示全部楼层
傻眼貓咪 发表于 2021-10-9 15:13
变成无限循环
范例:这里永远不会打印 "program is end!",因为上面的 while 无限循环
  1. #include <stdio.h>

  2. int main()
  3. {
  4.         int i = 0;
  5.         int l[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
  6.        
  7.     while(l[i] <= l[i+1] && ++i < 8)
  8.             ;
  9.    
  10.     printf("program is end!");
  11.     return 0;
  12. }
复制代码


循环体while()里的判断语句并不是一直为真
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-9 16:05:13 | 显示全部楼层
本帖最后由 傻眼貓咪 于 2021-10-9 16:07 编辑
雨中漫步~ 发表于 2021-10-9 15:47
循环体while()里的判断语句并不是一直为真


你说的没有错,但是你的代码可能出于某些原因导致 while 一直处于 真(这是因为我尝试去掉冒号后,得出的结论),你试试检查看看。非常抱歉兄弟,我的能力不足。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-9 16:38:29 | 显示全部楼层
傻眼貓咪 发表于 2021-10-9 16:05
你说的没有错,但是你的代码可能出于某些原因导致 while 一直处于 真(这是因为我尝试去掉冒号后,得出 ...

非常感谢你耐心的解答
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-29 16:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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