繁体   English   中英

如何在C中将字符串数组与整数数组并行排序? 没有结构?

[英]How to sort string array in C with integer array in parallel? Without structs?

好吧,冒泡的年龄工程。 我现在遇到的问题是需要首先进行的全名冒泡。 我考虑过将经过排序的年龄临时存储在一个数组中,但我想这是作弊。 我需要输入数据,打印未排序的名称和年龄,排序名称,打印已排序的名称未排序的年龄,排序年龄以及打印已排序的名称和年龄...

我怎样才能?

  1. 成功对字符串数组进行排序?
  2. 使用相应的字符串保留适当的年龄?
  3. 打印排序的字符串而不同时对年龄和字符串进行排序?

     #define SIZE 5 #include <stdio.h> #include <string.h> #include <stdio.h> void input(char fullname[][25], int age[]); void output(char fullname[][25], int age[]); //int compare(int x, int y); void bubbleSortage(int * const array,const int size); int main(int argc, char *argv[]) { char fullname[SIZE][25]; int age[SIZE]; int unneccessayalternateagearraybecausewehavetoprintthesortedvaluestwice[SIZE]; // prompt user for names and ages input(fullname, age); //output unsorted names and ages output(fullname, age); bubblesortname(fullname,SIZE); output(fullname, age); //sorts age bubbleSortage(age,SIZE); // output(fullname, age); return 0; } void input(char fullname[][25], int age[]) { int i; for (i = 0; i < SIZE; i++) { fflush(stdin); printf("Enter a full name\\n"); //scanf("%[\\^n]\\n", fullname[i]); fgets (fullname[i],40, stdin); printf("Enter the age\\n"); scanf("%d", &age[i]); } } void output(char fullname[][25], int age[]) { int i; for (i = 0; i < SIZE; i++) printf("%s, %d\\n", fullname[i], age[i]); }//end function void bubblesortname(int * const array, const int size) { int i, j; for (j = 0; j < size -1; j++) { for (i = 0; i < size -1; i++) { if (0<strcmp(fullname[i + 1], fullname[i])) { char *temp = fullname[i]; fullname[i]= fullname[i+1]; fullname[i+1]= tmp; }//end if }//end inner for }//end for }//end function void bubbleSortage(int * const array, const int size) { void swap(int *element1Ptr, int *element2Ptr ); int pass; //pass counter int j; // comparison counter //loop to control passes for(pass = 0;pass < size -1; pass++) { //loop to control comparison each pass for(j=0; j<size - 1;j++) { //swap elements if they are not in order if(array[j]>array[j+1]) { swap(&array[j], &array[j+1]); }// end if }// end inner for }// end outer for }// end function //swap values at memory locations to 1Ptr and 2 Ptr void swap(int *element1Ptr, int *element2Ptr) { int hold = *element1Ptr; *element1Ptr = *element2Ptr; *element2Ptr = hold; }// end swap function 

全部内容将存储在字符串数组(二维字符数组)中。 年龄将存储在整数数组中。 将数组作为并行数组进行管理 数据输入将从键盘输入,并读取全名和年龄。 当阵列已满或没有输入全名时,数据输入将终止。 使用子例程输入数据,并将数组传递给子例程,不要使用全局数组。 数据输入完毕后,使用另一个子例程将阵列打印到屏幕上。 然后,使用子例程将数据按全名(升序)排序。 重新使用打印子例程,然后将分类的数据打印到屏幕上。 编写另一个子例程,该例程将关于age的数据排序为主要排序,将全名作为次要排序。 最后,重用print子例程将数据打印到屏幕上。 主程序将调用数据输入功能,然后调用打印功能,名称排序功能,打印功能,年龄排序功能,最后是打印功能。 所有数据将传递给函数,无全局数据

****更新代码************

    #define SIZE 5
    #include <stdio.h>
    #include <string.h>
    #include <stdio.h>


    void input(char fullname[][25], int age[]);
    void output(char fullname[][25], int age[]);
    void bubblesortname(char *fullname[], int *age, SIZE size);
    bubblesortage(char *fullname[], int *age, SIZE size);

    int main(int argc, char *argv[]) 
    {
        char fullname[SIZE][25];
        int age[SIZE];
        char *tmp;


        // promt user for names and ages
        input(fullname, age);
        //output unsorted names and ages
        output(fullname, age);

        bubblesortname(fullname,age,SIZE);

        output(fullname, age);

        //sorts age
        bubbleSortage(fullname,age,SIZE);
        //
        output(fullname, age);


        return 0;
    }

    void input(char fullname[][25], int age[]) 
    {
        int i;
        for (i = 0; i < SIZE; i++) 
        {
            fflush(stdin);
            printf("Enter a full name\n");
            //scanf("%[\^n]\n", fullname[i]);
            fgets (fullname[i],40, stdin);
            printf("Enter the age\n");
            scanf("%d", &age[i]);

        }
    }

    void output(char fullname[][25], int age[]) 
    {
        int i;
        for (i = 0; i < SIZE; i++)
            printf("%s, %d\n", fullname[i], age[i]);
    }//end function

    void bubblesortname(char *fullname[], int *age, SIZE size)
    {
         int temp_age;
          char* temp_name;
          int n;

          for (SIZE pass = 0; pass < size - 1; ++pass) 
          {
            for (SIZE n = 0; n < len - 1; ++n) 
            {
              if (strcmp(fullname[n], fullname[n + 1]) > 0) 
              {
                temp_age = age[n];
                age[n] = age[n + 1];
                age[n + 1] = temp_age;

                temp_name = fullname[n];
                fullname[n] = fullname[n + 1];
                fullname[n + 1] = temp_name;


                 }//end if

            }//end inner for

        }//end for

    }//end function

            bubblesortage(char *fullname[], int *ages, SIZE size) 
            {
                int n;
                int temp_age;
                char* temp_name;
                    for (SIZE pass = 0; pass < size - 1; ++pass) 
                      {
                         for (SIZE n = 0; n < size - 1; ++n) 
                            {
                                 if (age[n] > age[n + 1]) 
                                  {

                                    temp_age = age[n];
                                    age[n] = age[n + 1];
                                    age[n + 1] = temp_age;
                                    temp_name = fullname[n];
                                    fullname[n] = fullname[n + 1];
                                    fullname[n + 1] = temp_name;

                                    }// end inner for

                            }// end outer for


                        }// end function

我将尝试解决您的3个子问题:

1.如何成功对字符串数组进行排序?

要对任何内容进行排序,您需要一种比较各个组件的方法。 要对字符串进行排序,您需要能够比较两个字符串,在C语言中,您可以通过调用strcmp()函数来做到这一点。

 #include <string.h> int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n); 

描述

strcmp()函数比较两个字符串s1s2 如果分别找到s1小于,匹配或大于s2 ,则它返回小于,等于或大于零的整数。

除了只比较s1s2的前n个字节(最多)之外, strncmp()函数类似。

返回值

如果发现s1 (或其前n个字节)分别小于,匹配或大于s2 ,则strcmp()strncmp()函数将返回小于,等于或大于零的整数。 。

因此,下面的代码示例说明了如何在C中比较字符串:

#include <stdio.h>
#include <string.h>

int main()
{
    const char* jenna = "Jenna";
    const char* mark  = "Mark";

    // warning: Be careful here because the order of strings matters
    //          and is directly related to the result. If you swap them
    //          the result changes sign (1 becomes -1, -1 becomes 1 and
    //          zero stays zero).
    int comparisonResult = strcmp(jenna, mark)

    if (comparisonResult < 0)
    {
        printf("%s is less than %s\n", jenna, mark);
    }
    else if (comparisonResult > 0)
    {
        printf("%s is greater than %s\n", jenna, mark);
    }
    else // We know that (comparisonResult == 0)
    {
        printf("%s is the same as %s\n", jenna, mark);
    }

有了它,您应该能够修改现有的算法,以对年龄进行排序以对字符串进行排序。 这是我在Google上找到的示例

2.如何保持带有相应字符串的适当年龄?

为了将C中的不同数据保持在一起,可以使用struct 因此,如果您想将姓名和年龄保持在一起,则可以按照以下方式建立数据结构:

struct Person {
    char* name;
    int   age;
};

int main()
{
    // The person is a datastructure containing two elements in it.
    struct Person person = { "Mark", 25 };

    // You can access each of the subcomponents of person by using the . operator like in this printf statement.
    printf("Hi, my name is %s and I'm %d years old\n", person.name, person.age);

    return 0;
}

现在,每次必须在Person前面键入struct变得很烦人,因此大多数人只是这样使用typedef

typedef struct Person_s {
    char* name;
    int age;
} Person;

int main()
{
    Person person = { "Mark", 25 };

    printf("Hi, my name is %s and I'm %d years old\n", person.name, person.age);

    return 0;
}

3.如何打印排序后的字符串而不同时对年龄和字符串进行排序?

同时部分是模棱两可的,是否意味着您不想更改输入的原始顺序?

无论如何,您都有两种选择。 您可以复制所有输入内容,然后按年龄或姓名对副本进行排序,然后打印副本。 或者,您可以在打印原始数据后对其进行排序,而对原始数据的排序对您而言已不再重要,因为它已经被打印出来了。

注意:我正在尝试使您自己解决此问题,而不仅仅是为您编写代码。 我很确定这是您正在从事的某种作业/家庭作业,并且您的用户名表明您是C的新手。

对于加分:

我在第二部分的说明中使用的typedef语法使用此示例:

typedef struct Person_s {
    char* name;
    int age;
} Person;

该语法用于说我想创建一个名为struct Person_s的类型,这是花括号{ ... definition ... }内的{ ... definition ... }但请将该类型从struct Person_s重命名为Person (这是一部分在末尾)。

也许如何使用typedef的另一个示例会有所帮助:

typedef int number_type; // make an alias for int and call it number_type

// From here on, we can use number_type instead of int.

number_type main()
{
    number_type number = 7;

    printf("%d\n", number);

    return 0;
}

我们之前对struct Person_s进行了相同的struct Person_s

typedef 
// Define the struct
struct Person_s {
    char* name;
    int age;
}
// Give it the following alias so that you can save me some typing...
Person;

注意:这是简化操作,目的是让初学者更清楚一点,我在掩盖一些事情……对我来说,轻松一点吧!

显然,您需要并行管理阵列。 按照我的原始答案,使用结构会更好。

但是你不能。 因此,您必须有两个数组。 原理仍然相同,只是有点混乱。 使用strcmp比较名称字符串,并手动比较年龄。

现在,从技术上讲,您的规范要求两个排序子例程。 这意味着您将有一个用于年龄,它对int数组进行排序,另一个用于名称,对char*数组进行排序。

对整数进行排序( 请注意,这遵循您的排序算法,实际上并不是冒泡排序 ):

void bubble_sort_age(int *arr, size_t len) {
  int temp;
  for (size_t pass = 0; pass < len - 1; ++pass) {
    for (size_t n = 0; n < len - 1; ++n) {
      if (arr[n] > arr[n + 1]) {
        // write a swap function if you really want to
        temp = arr[n];
        arr[n] = arr[n + 1];
        arr[n + 1] = temp;
      }
    }
  }
}

请注意,我将size_t类型用于数组索引计数器,因为可以保证它对于任何数组都足够大。

就个人而言,我可能会使用unsigned int类型来表示年龄,因为年龄为负数的人没有多大意义。

这是同一件事,但是在字符串上使用strcmp

void bubble_sort_name(char *arr[], size_t len) {
  char* temp;
  for (size_t pass = 0; pass < len - 1; ++pass) {
    for (size_t n = 0; n < len - 1; ++n) {
      if (strcmp(arr[n], arr[n + 1]) > 0) {
        temp = arr[n];
        arr[n] = arr[n + 1];
        arr[n + 1] = temp;
      }
    }
  }
} 

这还不够,因为我们需要确保在排序时将成对的名称和年龄保持在一起...因此, 无论何时进行排序和交换,我们都将两个数组都传递给我们,将交换应用于... 两个数组。

现在,如果我们将它们放在一起,它将看起来像这样:

// swap BOTH name and age to keep the arrays in sync =)
void bubble_sort_name(char *names[], int *ages, size_t len) {
  int temp_age;
  char* temp_name;
  for (size_t pass = 0; pass < len - 1; ++pass) {
    for (size_t n = 0; n < len - 1; ++n) {
      if (strcmp(names[n], names[n + 1]) > 0) {
        temp_age = ages[n];
        ages[n] = ages[n + 1];
        ages[n + 1] = temp_age;

        temp_name = names[n];
        names[n] = names[n + 1];
        names[n + 1] = temp_name;
      }
    }
  }
}

void bubble_sort_age(char *names[], int *ages, size_t len) {
  int temp_age;
  char* temp_name;
  for (size_t pass = 0; pass < len - 1; ++pass) {
    for (size_t n = 0; n < len - 1; ++n) {
      if (ages[n] > ages[n + 1]) {
        // write a swap function if you really want to
        temp_age = ages[n];
        ages[n] = ages[n + 1];
        ages[n + 1] = temp_age;

        temp_name = names[n];
        names[n] = names[n + 1];
        names[n + 1] = temp_name;
      }
    }
  }
}

void print(char *names[], const int *ages, size_t len) {
  for (size_t n = 0; n < len; ++n) {
    printf("%s %d\n", names[n], ages[n]);
  }
}

int main(void) {
  // Input &c omitted.
  // If you don't know how to malloc/realloc and read input,
  // there should be plenty of other SO questions showing how

  int ages[N_ITEMS] = { -10, 2, -1, -10, 0xDEADBEEF };
  char *names[] = { "one", "two", "-1", "onf", "foo" };

  print(names, ages, N_ITEMS);
  printf("\n");

  bubble_sort_name(names, ages, N_ITEMS);
  print(names, ages, N_ITEMS);
  printf("\n");

  bubble_sort_age(names, ages, N_ITEMS);
  print(names, ages, N_ITEMS);

  return 0;
}

由于要求您先按名称,打印方式进行排序,然后再按年龄进行主要排序,然后再根据年龄进行次要排序,所以我们可以利用冒泡排序的功能。

这是一种稳定的排序 ,因此当我们使用其他条件对数组进行排序时,相等的元素(在新的排序顺序下)将保持与旧排序对其进行排序的顺序(彼此相对)。

这意味着我们可以简单地第二次对年龄进行排序,只要我们记住名称和年龄都必须重新排列,这就是我们需要做的:)


专家的额外建议:您实际上可以重写冒泡排序方法,以便可以将其同时用于string和int 您可以使用void *和强制类型转换来实现。 不过,使用struct类型会更好。

要对字符串排序,请使用strcmp()进行比较。

同时对交替/并行数组进行排序,以便根据名称对名称和年龄进行排序:

在对名称进行排序时在冒泡排序算法中执行交换的代码中:

添加代码还可以交换交替/并行数组(年龄)中的相关条目

如果冒泡排序使用数组索引而不是指针,这将变得更加容易,因为索引也可以在交替/并行数组中使用

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM