2016-11-30 6 views
-1

私の目標は、データを読み込んで人口でソートすることですが、複数のデータ型を受け入れることができるソートを使用する必要があります。テンプレートを使用してこれを行うように指示されましたが、配列 "results [i] .pop"を私のbubblesort関数に渡すたびにエラーが表示されます構造体の配列でテンプレートBubblesortを使用する際のトラブル

'bubblesort :: T文字列&) ' bubblesort(results [i] .pop); " メモ:候補は: election.cpp:32:3:メモ:テンプレートT bubblesort(T *) T bubblesort ) ^ election.cpp:32:3:注:テンプレート引数の控除/置換に失敗しました:

election.cpp:106:34:注:結果[i] .election :: popを変換できませんここで

コードです:

struct election 
{ 

    string party; 
    string state; 
    string pop; 
    string reps; 
    int ratio; 
    bool operator>(election a) 
    { 
     return pop > a.pop; 
    } 
}; 

今すぐバブルソートを呼び出す:

#include <iostream> 
#include <iomanip> 
#include <string> 
#include <cstdlib> 
#include <fstream> 
#include <stdlib.h> 
using namespace std; 

struct election { 

string party; 
string state; 
string pop; 
string reps; 
int ratio; 
}; 


template <typename T> 
void bubblesort(T ar[]) 
{ 

//Bubblesort 
int n = 51; 
int swaps = 1; 
    while(swaps) 
    { 
    swaps = 0; 
      for (int i = 0; i < n - 1; i++) 
      { 
        if (ar[i] > ar[i + 1]) 
        { 
          swap(ar[i],ar[i+1]); 
          swaps = 1; 
        } 
      } 
    } 
//End Bubblesort 

} 


void delete_chars(string & st, string ch) 
{ 
    int i = st.find(ch); 
    while (i > -1) 
    { 
      st.replace(i,1,""); 
      i = st.find(ch); 
    } 
} 



int main() 
{ 
int i = 0; 
int n = 51; 
election results[n]; 

int population[n]; 
int electoralVotes[n]; 
int ratio[n]; 
string st; 
fstream inData; 

//Read in Data from Text File 
inData.open("electionresults.txt"); 



//Print Array as is 
cout << "Array Printed As is" << endl; 
cout << left << setw(10) << "Party" << setw(20) << "State" << setw(20) <<  "Population" << setw(15) << "Representatives" << endl; 
for (int i = 0; i < n; i++) 
{ 
    getline(inData,st); 
    results[i].party = st.substr(0,1); 
    results[i].state = st.substr(8,14); 
    results[i].pop = st.substr(24,10); 
    results[i].reps = st.substr(40,2); 
    cout << left << setw(10) << results[i].party << setw(20) <<  results[i].state << setw(20) << results[i].pop << setw(15) << results[i].reps << endl; 
} 

//Array Sorted by Population 
cout << "Array Sorted By Population" << endl; 
cout << endl; 
cout << endl; 
cout << left << setw(10) << "Party" << setw(20) << "State" << setw(20) <<    "Population" << setw(15) << "Representatives" << endl; 



for(int i = 0; i < n; i++){ 
bubblesort<string>(results[i].pop); 
} 
+0

あなたのテンプレート関数は 'T'を返すと宣言しています。 'T'を返すテンプレート関数には' return'ステートメントはありません。さらに、バソート関数が何かを返す理由はありません。さらに、関数bubblesotsはパラメータとして配列をとります。 'main()'がそれを呼び出すとき、 'main()'は配列をパラメータとして渡すのではなく、何か他のものを渡します。コード全体が完全に間違っています。テンプレートを勉強するのにもっと時間を費やす必要があります。ここには多すぎる問題があります。 –

+0

これはテンプレートを使った初めてのことです。 Tの代わりに関数をvoidに変更しましたが、同じエラーが表示されます。 – Nar1y

+0

それは、多くの中から一つの問題に過ぎませんでした。 –

答えて

0

あなたのバブルソートが機能するためには、あなたは選挙の構造体の演算子(>)以上を実装する必要があります結果配列を渡すことにより:

bubblesort<election>(results); 

Aあなたの関数は、関数のサイズをハードコーディングするのではなく、サイズを渡す必要があります(void bubblesort(T ar[], int size))。これにより、より多くの機能と適応性が得られます。

+0

ありがとうございました!私はまだこれで新しいので、実際の助けを借りるよりも爽やかです。 – Nar1y

+0

@ Nar1yなぜあなたは嘲笑されましたか?また、他のフィールドのいずれかをソートする必要がある場合はどうしますか?複数の 'operator>'は不可能なので、あなたはできません。スレッドの主要部分の私のコメントはこれに対処しました。 – PaulMcKenzie

+0

@ Nar1y - 私は答えを提供する時間を取ったし、うまくいけばもっと一般的な方法で問題を解決する方法を説明した。詳しい説明があるので、これをチェックしてください。 – PaulMcKenzie

0

popで並べ替えたい場合は、もう1つの回答で問題が解決しました。しかし、それは限られた解決策であり、あらゆる分野(今日では "ポップ")でのソートの本当の問題に対処することはできませんが、明日でなければ「比率」でソートするのはどうでしょうか? 。問題は、これを行うために複数のoperator >を提供することができず、基本的にはpopの並べ替えのみに固執していることです。

別の解決策は、一Tがソートされた配列内の他T前に配置すべきかどうか、2 T「sを与えられた場合に何をすべきかを定義する追加のテンプレートパラメータでbubblesort機能を提供することです。

#include <functional> 
#include <algorithm> 
//... 
template <typename T, typename cmp> 
void bubblesort(T ar[], int n, cmp compare_fn) 
{ 
    int swaps = 1; 
    while (swaps) 
    { 
     swaps = 0; 
     for (int i = 0; i < n - 1; i++) 
     { 
      if (!compare_fn(ar[i], ar[i + 1])) 
      { 
       std::swap(ar[i], ar[i + 1]); 
       swaps = 1; 
      } 
     } 
    } 
} 

// keep our original 2 param bubble sort, but let it call the one above 
template <typename T> 
void bubblesort(T ar[], int n) 
{ 
    // call general version using < 
    bubblesort(ar, n, std::less<T>()); 
} 

我々は、基本的に2つのパラメータバブルソート機能は、比較を記述する第三のパラメータを取る一般的な3パラメータbubblesortバージョンを呼び出す二つの機能を有します。

bubblesortの2つのパラメータバージョンは、あなたのアイテムが配列で

  1. ある「シンプル」の場合、用bubblesort
  2. を呼び出したいときは、<
  3. を使用して Tを比較することができます使用されています
  4. 昇順で並べ替える必要があります(そのため、通常のケースでは<で、>ではありません)。たとえば、

は、intの配列をソートする必要があり、あなたは、単に昇順で、それをソートしたい:

int someArray[10]; 
//... 
bubblesort<int>(someArray, 10); // sort ascending 

をしかし、私たちは「シンプル」の並べ替えを行うにはしたくありませんint、またはさらにstd::string。私たちはelectionを並べ替えたいだけでなく、election.popに並べ替えたいと思います。

最初のbubblesort関数を見ると、>を使用して比較を置き換え、関数compare_fnを呼び出すことに注意してください。パラメータはデフォルトでstd::less関数オブジェクトに設定されていることに注意してください。これは、std::less<を使用して比較するため、2番目のbubblesort関数が単純な型に対して機能する理由です。あなたがelectionを使用して2つのパラメータのみを使用してbubblesortを呼び出すためにしようとした場合

しかし、あなたは基本的にelectionは、と比較する一切operator <を持っていないことを示す、別のコンパイラエラーに遭遇します。その解決策は、カスタム比較関数を書く)election構造体又は

2に与えられた他の回答と同様、オペレータ<()を提供するため)のいずれか

1です。

だから、これらの解決策をそれぞれ考えてみましょう。


解決方法1:

我々は1を使用している場合)、election構造体は次のようになります。

struct election 
{ 
    std::string party; 
    std::string state; 
    std::string pop; 
    std::string reps; 
    int ratio; 
    bool operator <(const election& e) const { return pop < e.pop; } 
}; 

int main() 
{ 
    //... 
    bubblesort<election>(results, n); 
} 

これは、ソートする項目としてpopを使用して、今の並べ替えになりますresultsoperator <std::less<>によって使用されているelectionで定義されているため)。

Here is an example using overloaded < in election

しかし、この解決策は、その中であなたが唯一のパラメータとしてconst election&を取る1 operator <を定義することができ、他の回答と同じ問題があります。例えばratioでソートしたい場合は、運が悪い、またはpopを降順で並べ替える場合は不運です。これは上記のオプション2)が使用される場所です。


解決方法2:

我々は最初の場合trueを返すカスタム比較関数、関数オブジェクト、またはlambda functionを提供することにより、など、ソート順を、上ソートするかを定義することができますTは、比較関数に渡される2番目のTの前に来る必要があります。それ以外の場合はfalseです。

の機能を試してみましょう:今どうなる

bool compare_pop(const election& e1, const election& e2) 
{ 
    return e1.pop < e2.pop; // if e1.pop comes before e2.pop, return true, else false 
} 

int main() 
{ 
    //... 
    bubblesort<election>(results, n, compare_pop); 
} 

何がこのパラメータとして比較関数をとりbubblesortの最初のバージョンを呼び出すということです。 bubblesortテンプレート関数は、compare_popを呼び出して、アイテムの順序が間違っているかどうかを判断します。 compare_popfalseを返した場合、bubblesort関数はアイテムをスワップします。そうしないと、それらはそのまま残されます。あなたはラムダ関数を使用する代わりに、別の機能を比較する書き込みをしたい場合は

Here is a live example with an array of 3 elections, sorted on pop

、それはあまりにも動作します:

int main() 
{ 
    //... 
    bubblesort<election>(results, n, [&](const element& e1, const element& e2) { return e1.pop < e2.pop; }); 
} 

は、上記のことを除いて、関数の例と同じことを行いますラムダ構文が関数として使用されるので、別個の関数を書く必要はなくなりました。

Example using lambda syntax


だから今、私たちは何をpopでソートしたいのですが、降順と昇順でない場合は?

int main() 
{ 
    //... 
    bubblesort<election>(results, n, 
       [&](const element&e1, const element& e2) 
       { return e1.pop > e2.pop;}); 
} 

と魔法、bubblesortは降順でソートpopに、仕事をしていません:

bool compare_pop_up(const election& e1, const election& e2) 
{ 
    return e1.pop > e2.pop; // if e1.pop comes after e2.pop, return true, else false 
} 

int main() 
{ 
    //... 
    bubblesort<election>(results, n, compare_pop_up); 
} 

やラムダを使用して: - シンプルな異なる機能やラムダとbubblesortを呼び出します。

Here is a live example with an array of 3 elections, sorted on pop, descending

何がratioでソートしたい場合は?これはratioの昇順でratioにソートします

int main() 
{ 
    //... 
    bubblesort<election>(results, n, 
       [&](const element&e1, const element& e2) 
       { return e1.ratio < e2.ratio;}); 
} 

bool compare_ratio(const election& e1, const election& e2) 
{ 
    return e1.ratio < e2.ratio; 
} 

int main() 
{ 
    //... 
    bubblesort<election>(results, n, compare_ratio); 
} 

やラムダを使用して: - 同じことを別の関数やラムダを提供しています。


コードのその他の問題は、非標準のC++構文を使用して配列を定義していることです。あなたはこれをやっている:

election results[n]; 

C++の配列のみがアイテムの数を示すために、コンパイル時の式を使用して作成することができますように、これは、標準C++構文ではありません。 Variable Length Arraysという名前のものを使用しています。これはではなく、標準です。

代わりに、std::vector(標準C++)を使用できます。

#include <vector> 
//... 
std::vector<election> results(n); 
//... 
bubblesort<election>(results.data(), results.size(), compare_pop) 
関連する問題