C语言作业求助:实现质数与非质数按指定规则排序的程序
问题分析
你的程序核心问题出在合并质数数组和非质数数组的逻辑上:
- 原代码通过
(i+1)%3==0判断是否放置非质数,但未考虑质数或非质数提前耗尽的情况。比如质数数量不足2个时,或非质数用完后,剩余位置应直接填充剩余质数;若质数先耗尽,剩余位置需填充剩余非质数。 - 合并时修改了原本用于计数的
prime和nonprime变量,导致后续判断逻辑混乱,应使用独立索引变量跟踪当前取到第几个质数/非质数。
另外,原质数判断函数可优化循环范围,提升效率,但这不是程序失效的核心原因。
修正后的完整代码
#include<stdio.h> #include<stdbool.h> #include<math.h> // 用于质数判断优化 void read_array(int [], int); void display_array(int [], int); void sortPrimeOrNot(int [], int); void sortAscending(int [], int); void sortDescending(int [], int); bool is_prime(int); // 重命名函数,语义更清晰 void read_array(int arr[], int n) { for(int i=0;i<n;i++) { printf("Enter integer %d out of %d:",i+1,n); scanf("%d",&arr[i]); } } // 优化后的质数判断函数 bool is_prime(int n) { if(n <= 1) return false; if(n == 2) return true; if(n % 2 == 0) return false; // 仅遍历奇数到sqrt(n),减少循环次数 for(int j=3; j<=sqrt(n); j+=2) { if(n%j == 0) return false; } return true; } void sortPrimeOrNot(int arr[], int n) { int prime_count = 0, nonprime_count = 0; // 统计质数和非质数数量 for(int i=0; i<n; i++) { if(is_prime(arr[i])) prime_count++; else nonprime_count++; } int primes[prime_count], nonprimes[nonprime_count]; int p_idx = 0, np_idx = 0; // 分离质数和非质数到各自数组 for(int i=0; i<n; i++) { if(is_prime(arr[i])) { primes[p_idx++] = arr[i]; } else { nonprimes[np_idx++] = arr[i]; } } // 排序:质数升序,非质数降序 sortAscending(primes, prime_count); sortDescending(nonprimes, nonprime_count); // 重新合并到原数组:每2个质数 + 1个非质数的规则 p_idx = 0; np_idx = 0; int current = 0; while(p_idx < prime_count && np_idx < nonprime_count) { // 先放2个质数(如果还有剩余) if(p_idx < prime_count) arr[current++] = primes[p_idx++]; if(p_idx < prime_count) arr[current++] = primes[p_idx++]; // 再放1个非质数(如果还有剩余) if(np_idx < nonprime_count) arr[current++] = nonprimes[np_idx++]; } // 填充剩余的质数 while(p_idx < prime_count) arr[current++] = primes[p_idx++]; // 填充剩余的非质数 while(np_idx < nonprime_count) arr[current++] = nonprimes[np_idx++]; } void display_array(int arr[], int n) { for(int i=0;i<n;i++) { printf(" %d",arr[i]); } } void sortAscending(int arr[], int n) { for(int i=0;i<n;i++) { for(int j=0;j<n-i-1;j++) { if(arr[j]>arr[j+1]) { int temp=arr[j+1]; arr[j+1]=arr[j]; arr[j]=temp; } } } } void sortDescending(int arr[], int n) { for(int i=0;i<n;i++) { for(int j=0;j<n-i-1;j++) { if(arr[j]<arr[j+1]) { int temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } } } int main() { int n, arr[50]; printf("Enter a positive integer in the range [1, 50]:"); scanf("%d",&n); if(n<1 || n>50) { printf("Invalid input."); return 1; } read_array(arr,n); printf("\nOriginal Array: "); display_array(arr,n); printf("\nModified Array: "); sortPrimeOrNot(arr,n); display_array(arr,n); return 0; }
关键修改说明
- 合并逻辑重构:
- 抛弃索引模3的判断方式,改为循环优先放置2个质数、再放置1个非质数,直到其中一类数耗尽。
- 使用独立的
p_idx和np_idx跟踪当前取数位置,不修改原始计数变量,避免逻辑混乱。 - 新增两个单独循环,分别填充剩余的质数或非质数,确保所有元素都被正确放置。
- 质数判断优化:
- 重命名函数为
is_prime,语义更清晰。 - 增加偶数、2等特殊情况的判断,循环仅遍历奇数到
sqrt(n),大幅提升判断效率。
- 重命名函数为
- 变量命名优化:
- 将
arr1、arr2重命名为primes、nonprimes,prime、nonprime改为prime_count、nonprime_count,提升代码可读性。
- 将
内容的提问来源于stack exchange,提问作者Labrynth
相关产品推荐
相关产品推荐

