所以我有这个代码,它根据用户输入随机生成一个整数数组,并按升序和降序排列元素。但是,目前,代码只打印两次降序。所以我想知道如何制作数组ascd的副本,并在组织降序的代码片段中使用副本。我只是一个初学者,所以如果这是一个愚蠢的问题我很抱歉,并感谢我能得到的所有指导。这是我的代码:
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
int main (){
int x;
printf("Enter the size of your array\n");//User is entering number of elements
scanf("%d", &x);
int ascd[x]; //Array
int c;
int d;
int e;
int kk = 0;
int temp;
int tempother;
int turtle;
for(c = 0; c<x; c++){//Randomly generating elements
srand(time(0));
ascd[kk] = (rand() %100) + 1;
}
for(c = 0; c<x; c++){ //Ascending order
for(d = 0; d<(x-c-1); d++){
if(ascd[d] > ascd[d+1]){
temp = ascd[d];
ascd[d] = ascd[d+1];
ascd[d+1] = temp;
}
}
}
for(turtle = 0; turtle<x; turtle++){//Descending order
for(e = 0; e<(x-turtle-1); e++){
if(ascd[e] < ascd[e+1]){
tempother = ascd[e];
ascd[e] = ascd[e+1];
ascd[e+1] = tempother;
}
}
}
printf("The ascending order is\n\n");
for(c = 0; c<x; c++){
printf("%d\n", ascd[c]);
}
printf("\n\nThe descending order is\n\n");
for(turtle = 0; turtle<x; turtle++){
printf("%d\n", ascd[turtle]);
}
}
答案 0 :(得分:3)
您需要考虑许多其他问题。首先,始终,验证用户输入。如果没有别的,使用scanf
系列函数,请确保已成功执行预期的转化次数。 e.g。
int x = 0;
printf ("\n enter the number of elements for your array: ");
if (scanf ("%d", &x) != 1) { /* always validate user input */
fprintf (stderr, "error: invalid input, integer required.\n");
return 1;
}
int ascd[x], desc[x];
接下来,您只需要将随机数生成器播种一次。将srand (time (NULL));
移出循环。
虽然不是必需条件,但最好将VLA初始化为零(或某些数字,因为您无法提供初始化程序),以消除在迭代数组时无意识读取未初始化值的可能性(您在这种情况下可以考虑填充初始化,使memset
在这里可选,但是你不会立即循环并填写所有情况。如果你没有立即填充数组,那么如下所示就足够了,例如
memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */
填充数组后,如果您希望保留升序和降序排序,则简单的memcpy
将复制数组,例如
for (int i = 0; i < x; i++) /* x random values 1 - 100 */
ascd[i] = (rand () % 100) + 1;
memcpy (desc, ascd, x * sizeof *ascd); /* copy ascd to desc */
剩下的只是一点点清理。抵制为代码中的每个值创建(变量)的冲动。这很快变得难以理解。虽然我更喜欢C89声明,但for
块内的C99 / C11声明很方便,例如:
for (int i = 0; i < x; i++) /* ascending order */
for (int j = 0; j < (x - i - 1); j++)
if (ascd[j] > ascd[j + 1]) {
int temp = ascd[j];
ascd[j] = ascd[j + 1];
ascd[j + 1] = temp;
}
将所有部分放在一起,并注意到main()
是int
类型,因此return
是一个值,您可以按照以下方式整理。你的风格完全取决于你,但目标应该是可读性。 e.g。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main (void) {
int x = 0;
printf ("\n enter the number of elements for your array: ");
if (scanf ("%d", &x) != 1) { /* always validate user input */
fprintf (stderr, "error: invalid input, integer required.\n");
return 1;
}
int ascd[x], desc[x];
srand (time (NULL)); /* you only need do this once */
memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */
for (int i = 0; i < x; i++) /* x random values 1 - 100 */
ascd[i] = (rand () % 100) + 1;
memcpy (desc, ascd, x * sizeof *ascd); /* copy ascd to desc */
for (int i = 0; i < x; i++) /* ascending order */
for (int j = 0; j < (x - i - 1); j++)
if (ascd[j] > ascd[j + 1]) {
int temp = ascd[j];
ascd[j] = ascd[j + 1];
ascd[j + 1] = temp;
}
for (int i = 0; i < x; i++) /* descending order */
for (int j = 0; j < (x - i - 1); j++)
if (desc[j] < desc[j + 1]) {
int temp = desc[j];
desc[j] = desc[j + 1];
desc[j + 1] = temp;
}
printf ("\n the ascending order is\n\n");
for (int i = 0; i < x; i++) {
if (i && !(i % 10)) putchar ('\n');
printf (" %3d", ascd[i]);
}
printf ("\n\n the descending order is\n\n");
for (int i = 0; i < x; i++) {
if (i && !(i % 10)) putchar ('\n');
printf (" %3d", desc[i]);
}
putchar ('\n');
return 0;
}
示例使用/输出
$ ./bin/sort_copy
enter the number of elements for your array: 100
the ascending order is
1 1 4 4 5 5 7 8 8 9
10 13 16 16 17 20 22 22 22 23
24 24 25 27 29 29 33 35 35 35
37 38 40 41 41 41 41 42 44 45
46 48 48 48 49 50 53 54 56 57
58 59 61 61 63 64 65 65 66 66
67 68 68 70 71 73 74 74 74 75
76 80 80 80 80 82 84 84 85 85
85 85 86 88 88 89 89 90 91 91
91 92 92 93 93 93 96 99 100 100
the descending order is
100 100 99 96 93 93 93 92 92 91
91 91 90 89 89 88 88 86 85 85
85 85 84 84 82 80 80 80 80 76
75 74 74 74 73 71 70 68 68 67
66 66 65 65 64 63 61 61 59 58
57 56 54 53 50 49 48 48 48 46
45 44 42 41 41 41 41 40 38 37
35 35 35 33 29 29 27 25 24 24
23 22 22 22 20 17 16 16 13 10
9 8 8 7 5 5 4 4 1 1
仔细看看,如果您有任何问题,请告诉我。
排序 qsort
继续评论,qsort
是一个优化的排序例程,它是C标准库的一部分(在stdlib.h
中),无论您拥有何种类型的数据,它都是首选排序函数排序。通常捕获新C程序员的唯一要求是需要编写一个比较函数以传递给qsort
,以便qsort
知道您希望如何对对象集合进行排序。 qsort
将通过将指向值的指针传递给您编写的compare函数来比较两个元素。无论您要排序什么,比较的声明都是相同的,例如。
int compare (const void *a, const void *b);
你知道你正在排序整数值,所以你需要做的就是升序排序是写一个函数,如果a > b
返回一个正值 ,如果它们相等则返回零,如果b > a
,则返回负值。简单的方法就是写
int compare (const void *a, const void *b) {
int x = *(int *)a;
int y = *(int *)b;
return x - y;
}
满足升序的排序要求,并按降序排序return y - x;
- ,但存在问题。如果x
和y
碰巧是大的正值和大的负值,则x - y
可能会超过整数的最大值(或最小值)(例如溢出) ,因为结果不适合整数值。)
解决方案很简单。您可以执行相同的比较,但使用不等式的结果,例如返回(a > b) - (a < b)
进行升序比较,(a < b) - (a > b)
进行降序比较。 (此方案适用于所有数字类型,您只需要调整演员表)。迈出不平等的一步。在升序的情况下,如果a > b
返回1
(例如return 1 - 0;
)。如果它们相等,则不等式返回0
(0 - 0
),最后返回a < b
,返回的值为-1
(0 - 1
)。
虽然您可以继续明确声明x
和y
变量,但通常会在比较中看到它与强制转换一起编写,从而无需使用x
和y
完全/* integer comparison ascending (prevents overflow) */
int cmpascd (const void *a, const void *b)
{
/* (a > b) - (a < b) */
return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b);
}
个变量,例如
qsort
将这些部分放在一起,可以使用#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define ROW 10
int cmpascd (const void *a, const void *b);
int cmpdesc (const void *a, const void *b);
void prnarr (int *a, int n, int row);
int main (void) {
int x = 0;
printf ("\n enter the number of elements for your array: ");
if (scanf ("%d", &x) != 1) { /* always validate user input */
fprintf (stderr, "error: invalid input, integer required.\n");
return 1;
}
int ascd[x], desc[x];
srand (time (NULL)); /* you only need do this once */
memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */
for (int i = 0; i < x; i++) /* x random values 1 - 100 */
ascd[i] = (rand () % 100) + 1;
memcpy (desc, ascd, x * sizeof *ascd); /* copy ascd to desc */
qsort (ascd, x, sizeof *ascd, cmpascd); /* qsort ascending */
qsort (desc, x, sizeof *desc, cmpdesc); /* qsort descending */
printf ("\n the ascending order is\n\n");
prnarr (ascd, x, ROW);
printf ("\n\n the descending order is\n\n");
prnarr (desc, x, ROW);
putchar ('\n');
return 0;
}
/* integer comparison ascending (prevents overflow) */
int cmpascd (const void *a, const void *b)
{
/* (a > b) - (a < b) */
return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b);
}
/* integer comparison descending */
int cmpdesc (const void *a, const void *b)
{
/* (a < b) - (a > b) */
return (*(int *)a < *(int *)b) - (*(int *)a > *(int *)b);
}
void prnarr (int *a, int n, int row)
{
for (int i = 0; i < n; i++) {
printf (" %3d", a[i]);
if (i && !((i + 1) % row))
putchar ('\n');
}
}
而不是低效的嵌套循环(并将打印数组例程移动到它自己的函数)来编写相同的程序,如下所示,
-Wall -Wextra
与第一个答案一样,试一试,如果您有任何疑问,请告诉我。 (并且记住始终使用最小-pedantic
进行编译以启用大多数编译器警告 - 并在您认为代码可靠之前修复生成的任何警告 - 您不会遇到可以理解并安全地忽略警告的任何情况任何时候)添加gcc
以查看几乎所有可以生成的警告。 (如果你在Websters中查找 pedantic ,你就会明白为什么这个名字很合适。)只是FYI,我用来编译代码的$ gcc -Wall -Wextra -pedantic -std=c11 -Ofast -o bin/sort_copy sort_copy.c
编译器字符串是:
{{1}}
答案 1 :(得分:0)
您打印最后一个数组两次,您可以通过在完成升序操作后立即打印数组的值来获得升序数组输出。
答案 2 :(得分:0)
创建另一个数组来存储降序项。您可以反转升序数组以创建降序数组。试试这个代码。 #包括 #包括 #包括 #包括 int main(){
int x;
printf("Enter the size of your array\n");//User is entering number of elements
scanf("%d", &x);
int ascd[x]; //Array
int desc[x];
int c;
int d;
int e;
int kk = 0;
int temp;
int tempother;
int turtle;
int z=0;
for(c = 0; c<x; c++){//Randomly generating elements
srand(time(0));
ascd[kk] = (rand() %100) + 1;
}
for(c = 0; c<x; c++){ //Ascending order
for(d = 0; d<(x-c-1); d++){
if(ascd[d] > ascd[d+1]){
temp = ascd[d];
ascd[d] = ascd[d+1];
ascd[d+1] = temp;
}
}
}
for(turtle = x-1; turtle>=0; turtle--){//Descending order
desc[z]=ascd[turtle];
z++;
}
printf("The ascending order is\n\n");
for(c = 0; c<x; c++){
printf("%d\n", ascd[c]);
}
printf("\n\nThe descending order is\n\n");
for(turtle = 0; turtle<x; turtle++){
printf("%d\n", desc[turtle]);
}
}