简体   繁体   English

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

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

Ok the bubblesort for age works. 好吧,冒泡的年龄工程。 The part I am having trouble with now is the bubblesort for the fullname which needs to happen first. 我现在遇到的问题是需要首先进行的全名冒泡。 I thought about temporarily storing the sorted ages in an array but I guess that's cheating. 我考虑过将经过排序的年龄临时存储在一个数组中,但我想这是作弊。 I need to data entry, print unsorted name and age, sort name, print sorted name unsorted age, sort age, and print sorted name and age... 我需要输入数据,打印未排序的名称和年龄,排序名称,打印已排序的名称未排序的年龄,排序年龄以及打印已排序的名称和年龄...

How can I? 我怎样才能?

  1. Sort an array of strings successfully? 成功对字符串数组进行排序?
  2. Keep the appropriate ages with the corresponding strings? 使用相应的字符串保留适当的年龄?
  3. Print the sorted strings without sorting the ages and strings at the same time? 打印排序的字符串而不同时对年龄和字符串进行排序?

     #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 

The full will be stored in an array of strings, a two dimensioned array of characters. 全部内容将存储在字符串数组(二维字符数组)中。 The ages will be stored in an array of integers. 年龄将存储在整数数组中。 Manage the arrays as parallel arrays . 将数组作为并行数组进行管理 Data entry will be from the keyboard and will read the full name followed by the age. 数据输入将从键盘输入,并读取全名和年龄。 Data entry will terminate when the arrays are full or when nothing is entered for the full name. 当阵列已满或没有输入全名时,数据输入将终止。 Use a subroutine to enter the data and pass the arrays to the subroutine, do not use global arrays. 使用子例程输入数据,并将数组传递给子例程,不要使用全局数组。 Once the data is completely entered, use another subroutine to print out the arrays to the screen. 数据输入完毕后,使用另一个子例程将阵列打印到屏幕上。 Then use a subroutine to sort the data on the full names, ascending order. 然后,使用子例程将数据按全名(升序)排序。 Reuse the print subroutine and print the sorted data out to the screen. 重新使用打印子例程,然后将分类的数据打印到屏幕上。 Write another subroutine which sorts the data on age as the primary sort and full name as the secondary sort. 编写另一个子例程,该例程将关于age的数据排序为主要排序,将全名作为次要排序。 Finally reuse the print subroutine to print the data to the screen. 最后,重用print子例程将数据打印到屏幕上。 The main program will call the data entry function, followed by the print function, the name sort function, the print function, the age sort function and finally the print function. 主程序将调用数据输入功能,然后调用打印功能,名称排序功能,打印功能,年龄排序功能,最后是打印功能。 All data will be passed to the functions, no global data 所有数据将传递给函数,无全局数据

**** UPDATED CODE ************ ****更新代码************

    #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

I will try and address your 3 sub-questions: 我将尝试解决您的3个子问题:

1. How do I Sort an array of strings successfully? 1.如何成功对字符串数组进行排序?

To sort anything you need a way of comparing the individual components. 要对任何内容进行排序,您需要一种比较各个组件的方法。 To sort strings you need to be able to compare two strings and in C you do this by calling the strcmp() function. 要对字符串进行排序,您需要能够比较两个字符串,在C语言中,您可以通过调用strcmp()函数来做到这一点。

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

Description 描述

The strcmp() function compares the two strings s1 and s2 . strcmp()函数比较两个字符串s1s2 It returns an integer less than, equal to, or greater than zero if s1 is found, respectively, to be less than, to match, or be greater than s2 . 如果分别找到s1小于,匹配或大于s2 ,则它返回小于,等于或大于零的整数。

The strncmp() function is similar, except it only compares the first (at most) n bytes of s1 and s2 . 除了只比较s1s2的前n个字节(最多)之外, strncmp()函数类似。

Return Value 返回值

The strcmp() and strncmp() functions return an integer less than, equal to, or greater than zero if s1 (or the first n bytes thereof) is found, respectively, to be less than, to match, or be greater than s2 . 如果发现s1 (或其前n个字节)分别小于,匹配或大于s2 ,则strcmp()strncmp()函数将返回小于,等于或大于零的整数。 。

So here's a code example that illustrates how you compare strings in C: 因此,下面的代码示例说明了如何在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);
    }

With this you should be able to modify your existing algorithm for sorting ages to sort strings. 有了它,您应该能够修改现有的算法,以对年龄进行排序以对字符串进行排序。 Here's an example I found on Google . 这是我在Google上找到的示例

2. How do I keep the appropriate ages with the corresponding strings? 2.如何保持带有相应字符串的适当年龄?

To keep different data together in C you use a struct . 为了将C中的不同数据保持在一起,可以使用struct So if you wanted to keep a name and age together you would make a datastructure along the lines of this: 因此,如果您想将姓名和年龄保持在一起,则可以按照以下方式建立数据结构:

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;
}

Now it gets annoying having to type struct in front of Person every time so most people just use typedef like this: 现在,每次必须在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. How do I print the sorted strings without sorting the ages and strings at the same time? 3.如何打印排序后的字符串而不同时对年龄和字符串进行排序?

The at the same time part is ambiguous, do you mean that you don't want to change the original ordering of your inputs? 同时部分是模棱两可的,是否意味着您不想更改输入的原始顺序?

In any case you have a couple options. 无论如何,您都有两种选择。 You can either make a copy of all of your inputs and then sort the copy, by either age or name and then print the copy. 您可以复制所有输入内容,然后按年龄或姓名对副本进行排序,然后打印副本。 Or you can sort your original data after you have printed it and its ordering no longer matters to you since you've already printed it. 或者,您可以在打印原始数据后对其进行排序,而对原始数据的排序对您而言已不再重要,因为它已经被打印出来了。

Note: I'm trying to enable you to solve this problem yourself instead of just writing the code for you. 注意:我正在尝试使您自己解决此问题,而不仅仅是为您编写代码。 I'm pretty sure this is some type of assignment/homework that you're working on and your username suggests you're new to C... 我很确定这是您正在从事的某种作业/家庭作业,并且您的用户名表明您是C的新手。

For extra points: 对于加分:

The typedef syntax I used in the explanation for the 2nd part I used this example: 我在第二部分的说明中使用的typedef语法使用此示例:

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

This syntax is used to say that I want to create a type called struct Person_s and here is its definition inside of the curly braces { ... definition ... } but please rename the type from struct Person_s to Person (which is the part at the end). 该语法用于说我想创建一个名为struct Person_s的类型,这是花括号{ ... definition ... }内的{ ... definition ... }但请将该类型从struct Person_s重命名为Person (这是一部分在末尾)。

Perhaps a different example of how to use typedef will help: 也许如何使用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;
}

We did the same with the struct Person_s earlier: 我们之前对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;

Note: This is a simplification in an attempt to make it clear for a beginner, I'm glossing over some things... Go easy on me SO! 注意:这是简化操作,目的是让初学者更清楚一点,我在掩盖一些事情……对我来说,轻松一点吧!

You're required to manage the arrays in parallel, apparently. 显然,您需要并行管理阵列。 It would be much better to use a struct, as per my original answer. 按照我的原始答案,使用结构会更好。

But you can't. 但是你不能。 So, you have to have two arrays. 因此,您必须有两个数组。 The principles are still the same, it's just a bit messier. 原理仍然相同,只是有点混乱。 Use strcmp to compare name strings, and compare the ages manually. 使用strcmp比较名称字符串,并手动比较年龄。

Now, technically your specification asks for two sorting subroutines. 现在,从技术上讲,您的规范要求两个排序子例程。 This means you'll have one for ages, which sorts an array of int , and another for names, which sorts an array of char* . 这意味着您将有一个用于年龄,它对int数组进行排序,另一个用于名称,对char*数组进行排序。

Sorting integers ( note that this follows your sorting algorithm, which isn't actually a bubble sort ): 对整数进行排序( 请注意,这遵循您的排序算法,实际上并不是冒泡排序 ):

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;
      }
    }
  }
}

Note that I'm using the size_t type for array index counters because it is guaranteed to be large enough for any array. 请注意,我将size_t类型用于数组索引计数器,因为可以保证它对于任何数组都足够大。

Personally, I would probably use an unsigned int type to represent age, since a person with a negative age doesn't make much sense. 就个人而言,我可能会使用unsigned int类型来表示年龄,因为年龄为负数的人没有多大意义。

And here's the same thing, but using strcmp on strings: 这是同一件事,但是在字符串上使用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;
      }
    }
  }
} 

This isn't quite enough, because we need to ensure that the pairs of names and ages are kept together when we're sorting... so we pass in both arrays whenever we sort, and whenever we swap, we apply the swap to... both arrays. 这还不够,因为我们需要确保在排序时将成对的名称和年龄保持在一起...因此, 无论何时进行排序和交换,我们都将两个数组都传递给我们,将交换应用于... 两个数组。

Now, if we put it all together, it will look something like this: 现在,如果我们将它们放在一起,它将看起来像这样:

// 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;
}

Since you are required to sort on name, print, and then primary sort on age but secondary sort on age, we can take advantage of a feature of bubblesort. 由于要求您先按名称,打印方式进行排序,然后再按年龄进行主要排序,然后再根据年龄进行次要排序,所以我们可以利用冒泡排序的功能。

It is a stable sort , so when we resort an array on a different criterion, an elements that are equal (under the new sort order) will be kept in the same order (relative to each other) that the old sort sorted them in. 这是一种稳定的排序 ,因此当我们使用其他条件对数组进行排序时,相等的元素(在新的排序顺序下)将保持与旧排序对其进行排序的顺序(彼此相对)。

This means we can simply sort on age the second time, and so long as we remember that name and age both have to be rearranged, that's all we need to do :) 这意味着我们可以简单地第二次对年龄进行排序,只要我们记住名称和年龄都必须重新排列,这就是我们需要做的:)


Extra for experts: you can actually rewrite the bubble sort method so that you can reuse it for both strings and int . 专家的额外建议:您实际上可以重写冒泡排序方法,以便可以将其同时用于string和int You can do that using void * and casts. 您可以使用void *和强制类型转换来实现。 It would be much better to use a struct type, though. 不过,使用struct类型会更好。

To sort strings, use strcmp() to make the comparisons. 要对字符串排序,请使用strcmp()进行比较。

to also sort the alternate/parallel array, at the same time so names and ages are all sorted according to the name: 同时对交替/并行数组进行排序,以便根据名称对名称和年龄进行排序:

in the code that performs the swap in the bubble sort algorithm when sorting the names: 在对名称进行排序时在冒泡排序算法中执行交换的代码中:

add code to also swap the associated entries in the alternate/parallel array (the ages) 添加代码还可以交换交替/并行数组(年龄)中的相关条目

this will be made much easier if the bubble sort uses array indexing rather than pointers, as the indexes would also work in the alternate/parallel array 如果冒泡排序使用数组索引而不是指针,这将变得更加容易,因为索引也可以在交替/并行数组中使用

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

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