所以我的目标是读取一些数据并按人口排序,但我必须使用可以接受多种数据类型的排序。我被指示使用模板来执行此操作,但每次我传递数组"结果[i] .pop"到我的bubblesort函数我收到错误
没有匹配函数来调用'bubblesort(std :: string&)' 冒泡(结果[I] .pop);" 注意:候选人是: election.cpp:32:3:注意:模板T bubblesort(T *) T bubblesort(T ar []) ^ election.cpp:32:3:注意:模板参数扣除/替换失败:
election.cpp:106:34:注意:无法将'results [i] .election :: pop'(类型'std :: string {aka std :: basic_string}')转换为'std :: basic_string * “ 冒泡(结果[I] .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 :(得分:0)
要使你的bubblesort工作,你需要为选举结构实现大于运算符(&gt;):
struct election
{
string party;
string state;
string pop;
string reps;
int ratio;
bool operator>( election a)
{
return pop > a.pop;
}
};
现在通过传递结果数组来调用bubblesort:
bubblesort<election>(results);
旁注,你的函数应该传递大小,而不是硬编码函数中的大小(void bubblesort(T ar[], int size)
)。这为您的功能提供了更多功能和适应性。
答案 1 :(得分:0)
如果你只想对pop
进行排序,另一个答案就解决了这个问题。然而,这是一个有限的解决方案,并不会解决在任何领域排序的真正问题(今天它是“流行”,但如果明天不是这种情况,你想要对“比率”排序呢?) 。问题是,您无法提供多个operator >
来执行此操作,并且您基本上只能在pop
上进行排序。
另一个解决方案是为bubblesort
函数提供一个额外的模板参数,该参数定义了给定两个T
时要执行的操作,是否应将T
放在另一个T
之前{排序数组中的{1}}。
#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>());
}
我们基本上有两个函数,其中两个参数bubblesort函数调用通用3参数bubblesort
版本,该版本采用第三个参数,该参数描述了比较。
如果您想为“简单”案例调用bubblesort
,则使用bubblesort
的双参数版本,其中您的商品为
T
和<
<
而不是>
来解决一般情况。)例如,需要对int
数组进行排序,您只想按升序对其进行排序:
int someArray[10];
//...
bubblesort<int>(someArray, 10); // sort ascending
但是,我们不想对int,甚至std::string
进行“简单”排序。我们希望在election
上对election.pop
进行排序,而不仅仅是bubblesort
。
如果您查看上面的第一个>
函数,请注意我们使用compare_fn
替换了比较函数bubblesort
的比较。请注意,该参数默认为std::less函数对象。这就是第二个std::less
函数适用于简单类型的原因,因为<
使用bubblesort
进行比较。
但是,如果您尝试使用election
仅使用两个参数调用election
,则会遇到另一个编译器错误,基本上说明operator <
没有election
到与之比较。解决方法是
1)提供这样的运营商&lt; (与给出的其他答案类似)election
结构或
2)编写自定义比较函数。
让我们回顾一下这些解决方案。
解决方案1:
如果我们使用1),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);
}
结构将如下所示:
results
现在,pop
使用operator <
作为要排序的项目进行排序,因为election
正在使用std::less<>
中定义的operator <
。
Here is an example using overloaded < in election
但是,此解决方案与其他答案存在相同的问题,因为您只能定义一个const election&
作为参数。ratio
。例如,如果你想对pop
进行排序,那么你运气不好,或者如果你想按降序排序true
,那你就不走运了。这是上面选项2)的用法。
解决方案2:
我们可以通过提供自定义比较函数,函数对象或lambda function来定义我们要排序的内容,排序顺序等,如果第一个T
则返回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_pop
来确定项目是否出现故障。如果false
返回bubblesort
,则int main()
{
//...
bubblesort<election>(results, n, [&](const element& e1, const element& e2) { return e1.pop < e2.pop; });
}
函数会交换项目,否则会让他们独自一人。
Here is a live example with an array of 3 elections, sorted on pop
如果你想使用lambda函数而不是编写另一个比较函数,那也可以使用:
pop
上面将与函数示例做同样的事情,除了你不再需要编写一个单独的函数,因为lambda语法被用作函数。
现在,如果我们想对bubblesort
进行排序,但是降序而不是升序怎么办?简单 - 使用不同的函数或lambda调用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);
}
:
int main()
{
//...
bubblesort<election>(results, n,
[&](const element&e1, const element& e2)
{ return e1.pop > e2.pop;});
}
或使用lambda:
bubblesort
而且神奇地,pop
完成了工作,按ratio
降序排序。
Here is a live example with an array of 3 elections, sorted on pop, descending
如果您想对bool compare_ratio(const election& e1, const election& e2)
{
return e1.ratio < e2.ratio;
}
int main()
{
//...
bubblesort<election>(results, n, compare_ratio);
}
进行排序怎么办?同样的事情 - 提供不同的功能或lambda:
int main()
{
//...
bubblesort<election>(results, n,
[&](const element&e1, const element& e2)
{ return e1.ratio < e2.ratio;});
}
或使用lambda:
ratio
这将按ratio
的升序排序election results[n];
。
您的代码的另一个问题是您在定义数组时使用非标准C ++语法。你这样做了:
Variable Length Arrays
这不是标准的C ++语法,因为C ++只允许使用编译时表达式创建数组来表示项目数。您正在使用名为#include <vector>
//...
std::vector<election> results(n);
//...
bubblesort<election>(results.data(), results.size(), compare_pop)
的内容,不是标准。
相反,您可以使用标准C ++的std::vector。
{{1}}