2

特定の方法で構造体をソートしようとしています。次の構造体でわかるように、フィールドはproduct名前でソートされています。

       a   -   $13.00
 a.0|100   -   $3.00
 a.1|100   -   $6.00
 a.2|100   -   $4.00
       b   -   $25.00
 b.0|100   -   $2.00
 b.1|100   -   $10.00
 b.2|100   -   $13.00

名前による並べ替えを維持するにはどうすればよいかと思いますがproduct、同時に、各製品をprice.

これが私がこれまでに持っているものです:

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

struct st_ex { 
    char product[16];
    float price;
};

int struct_cmp_by_product(const void *a, const void *b) { 
    struct st_ex *ia = (struct st_ex *)a;
    struct st_ex *ib = (struct st_ex *)b;
    return strcmp(ia->product, ib->product);
} 

int main() { 
    struct st_ex structs[] = {
        {"b", 25}, 
        {"b.0|100", 2}, 
        {"b.1|100", 10},
        {"b.2|100", 13},
        {"a", 13},
        {"a.0|100", 3},
        {"a.1|100", 6},
        {"a.2|100", 4},
    };  
    size_t structs_len = sizeof(structs) / sizeof(struct st_ex);
    qsort(structs, structs_len, sizeof(struct st_ex), struct_cmp_by_product);    
    size_t i;
    for(i=0; i<structs_len; i++) 
        printf("%8s   -   $%.2f\n", structs[i].product, structs[i].price);
    return 0;
}

更新: 価格で並べ替えていますが、名前でグループ化しています。例b:25>a:13

       b   -   $25.00
 b.2|100   -   $13.00
 b.1|100   -   $10.00
 b.0|100   -   $2.00
       a   -   $13.00
 a.1|100   -   $6.00
 a.2|100   -   $4.00
 a.0|100   -   $3.00
4

4 に答える 4

0

最も簡単な方法は、struct_cmp_by_product. を実行する代わりに、製品名を比較します (製品名の長さに応じて、メンバーの部分文字列でstrcmp使用したい場合があります)。strcmpproduct

st_exただし、組み合わせたときに実際の製品名を与える 2 つのメンバーを保持することにより、この区別を型内にエンコードすることをお勧めします。

 struct st_ex {
      char product[ 4 ]; // product group
      char subgroup[ 12 ]; // sub group
      float price;
 }

 int struct_cmp_by_product(const void *a, const void *b) { 
    struct st_ex  const *ia = a; // do not cast away const-ness!
    struct st_ex const *ib = b;
    int x = strcmp(ia->product, ib->product);
    if (!x) {
        return ia->price > ib->price;
    }
    return x;
} 
于 2012-06-10T21:25:22.193 に答える
0

重要なのは、農産物の名前を識別できるようにすることです。もちろん、これは製品名の形式に依存します。ここに書かれていることが正確である場合、それは前に来る単語が.あればそれを意味します. 比較関数を少しずつ構築しましょう。

int struct_cmp_by_product(const void *a, const void *b) { 
    struct st_ex *ia = (struct st_ex *)a;
    struct st_ex *ib = (struct st_ex *)b;

まず、どこで.発生するかを見つける必要があります。

    size_t len_a, len_b;
    char *a_dot, *b_dot;
    a_dot = strchr(ia->product, '.');
    b_dor = strchr(ib->product, '.');
    if (a_dot)
        len_a = a_dot - ia->product;
    else
        len_a = strlen(ia->product);
    if (b_dot)
        len_b = b_dot - ib->product;
    else
        len_b = strlen(ib->product);

次に、2 つの製品名が等しいかどうかを確認する必要があります。

    int res; /* define above */
    if (len_a == len_b && strncmp(ia->product, ib->product, len_a) == 0)
    {
        /* then check for price */
    }
    else
        return strcmp(ia->product, ib->product);

価格を比較する部分は次のように単純に与えられます。

        if (ia->price < ib->price)
            return -1;
        if (ia->price > ib->price)
            return 1;
        return 0;

そして最後に関数を閉じます:

}

注: エラー チェックを行っていないか、タイプミスがある可能性があります。コードを使用する前に、コードを理解していることを確認してください。コピペだけじゃない。

于 2012-06-10T21:30:41.140 に答える
0

宿題?この種のものをCで書く人はもういますか?

目標が何であるかを考えてみてください。製品名が異なっていても、価格に違いはないため、名前の比較結果を返します。

価格が問題になるのは、製品名が同じ場合のみです。

したがって、2 つの問題を修正する必要があります。、、およびを製品の「名前」として同等に比較するstrcmp(3)必要があることを知っている、よりアプリケーションを意識した の代替が必要です。そしてもちろん、平等の場合、価格の比較を追加する必要があります。以下のコードは比較関数を置き換え、テスト済みです。ちなみに、プレーン C で作業している場合は、変換をキャストする必要はありません。bb.0|100b.0|200void *

int baseproductname(const char *a, const char *b) {
    for(;;) {
        int c = *a;
        int d = *b;
        if (c == '.')
            c = 0;
        if (d == '.')
            d = 0;
        if(c != d || !c || !d)
            return c - d;
        ++a;
        ++b;
    }
}

int productorder(const struct st_ex *a, const struct st_ex *b) {
    int n = baseproductname(a->product, b->product);
    printf("%s <=> %s is %d\n", a->product, b->product, n);
    if (n)
        return n;
    if (a->price > b->price)
        return -1;
    return a->price < b->price;
}

int struct_cmp_by_product(const void *a, const void *b) {
  return productorder(a, b);
}
于 2012-06-10T21:24:39.227 に答える
0
int struct_cmp_by_product(const void *a, const void *b) {
    struct st_ex *ia = (struct st_ex *)a;
    struct st_ex *ib = (struct st_ex *)b;
    int rc;
    size_t len_a, len_b, len;

    len_a = strcspn(ia->product, ".");
    len_b = strcspn(ib->product, ".");
    len = (len_a > len_b) ? len_a : len_b; /* assuming ascii */
    rc = strncmp(ia->product, ib->product, len);
    if (rc) return rc;

    if (ia->price > ab-price) rc = 1;
    else if (ia->price < ab-price) rc = -1;
    return rc;
}

更新: strcmp() -->> strncmp + サイズの計算

于 2012-06-10T21:31:57.540 に答える