0

次のスニペットがあるとします。

int compareFoo(std::string** a, std::string** b) {
    return (**a).compare(**b);
}

int main() {
    std::string** foo = new std::string*[3];
    foo[0] = new std::string("a");
    foo[1] = new std::string("c");
    foo[2] = new std::string("b");
    sort(foo,foo+3,compareFoo);
    for (int i = 0; i < 3; i++) {
        std::cout << *foo[i] << std::endl; // print acb
    }
}

sortの3番目のパラメータ(compare)を省略した場合、メモリアドレスの観点からソートされた3つの文字列が得られますが、これは意図した方法ではありません。しかし、メモリアドレスを比較しないようにcompareFoo関数をパラメータ化するにはどうすればよいですか。

void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);

cplusplus.comでのSortの説明は非常にあいまいで、与えられた例は単純です。イテレータが必要ですが、スタンドコンテナでしか動作しないということですか?ありがとうございました

4

4 に答える 4

2

I'd reconsider whether all of this pointer manipulation is really what you want. This isn't Java or C#. In C++, you do not allocate from the free store ("the heap") by default. Just create your array automatically and store the strings directly. In other words, you'd end up with something like this:

#include <algorithm>
#include <string>
int main(){
    std::string foo [] = {
        "a",
        "c",
        "b"
    };
    std::sort(foo, foo + 3);
    for(int i = 0; i < 3; i++){
        std::cout << foo[i] << '\n'; // print abc
    }
}

Compared to your version, this

  • Is faster
  • Uses less memory (no extra pointer overhead)
  • Doesn't leak memory
  • Is more readable to people familiar with C++
  • Removes any fears about possible null pointers
  • Requires less code
  • Works better with optimizing compilers
于 2012-09-24T04:32:32.460 に答える
1

比較関数は、比較するために2つの項目を取り、最初の項目が2番目の項目よりも小さい場合にtrueを返します。あなたの場合、それはこのように機能します:

#include <string>
#include <algorithm>
#include <iostream>

using std::sort;

bool compareFoo(std::string* a,std::string* b){
  return *a < *b;
}

int main(){
  std::string** foo = new std::string*[3];
  foo[0] = new std::string("a");
  foo[1] = new std::string("c");
  foo[2] = new std::string("b");
  sort(foo,foo+3,compareFoo);
  for(int i=0;i<3;i++){
    std::cout << *foo[i] << std::endl; 
  }

  // Remember to delete things that you dynamically allocate.
  delete foo[0];
  delete foo[1];
  delete foo[2];
  delete [] foo;
}
于 2012-09-24T04:22:59.233 に答える
1

std :: sortは3つのことを取り入れます:

  1. 開始を表すランダムアクセスイテレータ
  2. 終わりを表すランダムアクセスイテレータ
  3. 2つのものを取り込んで比較し、結果を返す関数

つまり、これは、ランダムアクセスイテレータテンプレートに続くものなら何でも機能できることを意味します。つまり、ポインタなので、配列は問題なく機能するはずです。

ただし、現在のコードでは、1つのレベルの間接参照が多すぎるため、これを試してください

#include <string>
#include <algorithm>
#include <iostream>

using std::sort;

bool compareFoo(std::string a,std::string b){
  return *a < *b; //note the difference
}

int main(){
  std::string* foo = new std::string[3];
  foo[0] = std::string("a");
  foo[1] = std::string("c");
  foo[2] = std::string("b");
  sort(foo,foo+3,compareFoo);
  for(int i=0;i<3;i++){
    std::cout << *foo[i] << std::endl;
  }
}

ただし、この場合、比較関数を提供する必要はありません。この関数は自動的に<演算子を使用します。

于 2012-09-24T04:23:39.700 に答える
0
bool compareFoo(std::string * lhs, std::string * rhs)
{
    return *lhs < *rhs;
}

イテレータが必要ですが、スタンドコンテナのみで作業するということですか?

いいえ。イテレータは概念です。ポインターはイテレーターの概念の要件を満たしているため、イテレーターです。

于 2012-09-24T04:24:14.140 に答える