我目前正在尝试对阵列进行排序时遇到困难(我真的需要解决这个问题,我总是在排序数据时遇到问题)。
所以基本上我创建了一个包含“date”和“snowDepth”元素的C ++结构。我使用了bubblesort逻辑来对snowDepth元素进行排序,这非常棒,这正是我所需要的。但是,由于元素是分开的,因此日期不会改变。我怎样才能对并行数组进行排序?
数据应如下所示:
Snow Report December 12 - 18
Date Base
13 42.3
12 42.5
14 42.8
15 43.1
18 43.1
16 43.4
17 43.8
我的看起来像这样:
SNOW REPORT December 12 - 18
=======================================
DATE DEPTH
12 42.3
13 42.5
14 42.8
15 43.1
16 43.1
17 43.4
18 43.8
注意日期是如何与snowDepth元素一起排序的。我怎么能做到这一点?
好的,谢谢所有的评论!这是我的代码:
// Structure
struct Array
{
int date;
double snowDepth;
void SnowData(int d, double sD)
{
date = d;
snowDepth = sD;
}
};
// Main Function
int main()
{
/* *--------------------*
| VARIABLES |
*--------------------* */
// Constant Variables
const int NUM_ELEMENTS = 7;
const int NUM_MONTHS = 12;
// String, Numerical, and Boolean Variables
string month;
int startDate;
int endDate;
int a;
int b;
int flag = 0;
double result;
bool monthMatch = false;
// Array Variables
Array snowData[NUM_ELEMENTS];
string name[NUM_MONTHS] = {"January", "February", "March",
"April", "May", "June",
"July", "August", "September",
"October", "November", "December" };
/* *--------------------*
| USER INSTRUCTIONS |
*--------------------* */
cout << endl;
cout << "This program will keep track of the local snow conditions for 7 days." << endl;
cout << "This program will ask the user for the month, date range (must be 7 days)," << endl;
cout << "and the inches of snow reported on that date. The program will then sort" << endl;
cout << "the data from least amount of snow reported to the most." << endl;
cout << endl;
/* *--------------------*
| USER PROMPT |
*--------------------* */
// Prompt the user for the month
cout << "Enter the full name of the month: ";
cin >> month;
// Prompt the user for the starting date
cout << "Enter the starting date of the 7-day period: ";
cin >> startDate;
snowData[0].date = startDate;
// Once the user enters the start date, run a loop to initialize the rest of the dates in snowData array
for (int x = 1; x < NUM_ELEMENTS; x++)
snowData[x].date = ++startDate;
// Prompt the user for the ending date
cout << "Enter the ending date of the 7-day period: ";
cin >> endDate;
cout << endl;
// If the user does not enter the correct ending date (which is 7 days from the start date), loop will prompt the user again
if (endDate != snowData[NUM_ELEMENTS - 1].date)
{
do
{
cout << "The end date entered is not 7 days from the start date. Try again." << endl;
cout << "Enter the ending date of the 7-day period: ";
cin >> endDate;
cout << endl;
} while (endDate != snowData[NUM_ELEMENTS - 1].date);
int x = 0;
// Once the user enters the correct ending date, prompt the user for the snow depth numbers
for (int y = 0; y < NUM_ELEMENTS; y++)
{
cout << "Enter the depth of snow measured on " << month << " " << snowData[x].date << ": ";
cin >> snowData[y].snowDepth;
x++;
}
}
// Once the user enters the correct ending date, prompt the user for the snow depth numbers
else
{
int x = 0;
for (int y = 0; y < NUM_ELEMENTS; y++)
{
cout << "Enter the depth of snow measured on " << month << " " << snowData[x].date << ": ";
cin >> snowData[y].snowDepth;
x++;
}
}
/* *--------------------*
| SORTING & FORMAT |
*--------------------* */
// Sorting logic in ascending order
for (a = 1; (a <= NUM_ELEMENTS) && flag; a++)
{
flag = 0;
for (b = 0; b < (NUM_ELEMENTS - 1); b++)
{
if (snowData[b + 1].snowDepth < snowData[b].snowDepth)
{
result = snowData[b].snowDepth;
snowData[b].snowDepth = snowData[b + 1].snowDepth;
snowData[b + 1].snowDepth = result;
flag = 1;
}
}
}
// Formatted Output
cout << endl;
cout << " SNOW REPORT ";
cout << month << " " << snowData[0].date << " - " << snowData[6].date << endl;
cout << "=======================================" << endl;
cout << setw(11) << "DATE" << setw(18) << "DEPTH" << endl;
for (int x = 0; x < (NUM_ELEMENTS); x++)
cout << setw(10) << snowData[x].date << setw(18) << snowData[x].snowDepth << endl;
cout << endl;
}
答案 0 :(得分:2)
您可以为单个日期/ snowDepth对创建结构,并保留此类对的数组。之后可以在那里添加更多字段,并按您喜欢的方式排序。数据将始终保持一致。
顺便说一句:为什么泡泡排序? Quicksort要快得多。
答案 1 :(得分:1)
由于两个元素都在同一个结构中,因此这两个元素应该一起移动。你的数组应该是一个结构数组。你现在如何配置它?
答案 2 :(得分:1)
更新添加了一个基于std :: map的示例,以获得更好的衡量标准(见下文)
我不会像在数据结构上那样进行排序:)
这是我为了刷掉C ++技能的粉尘而编写的示例:) 对不起,如果我扔进厨房水槽以上。
另请注意,对于这个'tivial'数据类型,您可能使用std :: pair作为'Report'结构,std :: map作为容器类型,需要的手动编码要少得多,但我想告诉你如何如果您手动编码结构,事情就完成了:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
static struct Report
{
int date;
double base;
Report(int d, double b) : date(d), base(b) {}
bool operator<(const Report& rhs) const
{
return (date<rhs.date) || ((date==rhs.date) && (base<rhs.base));
}
friend std::ostream& operator<<(std::ostream& os, const Report& r)
{
os << "Report(" << r.date << ", " << r.base << ")";
}
} theData[] = {
Report( 13, 42.3),
Report( 12, 42.5),
Report( 14, 42.8),
Report( 15, 43.1),
Report( 18, 43.1),
Report( 16, 43.4),
Report( 17, 43.8),
};
int main(int argc, const char* args[])
{
Report *const begin = theData;
Report *const end = theData+(sizeof(theData)/sizeof(*theData));
// simpler container, take a copy for comparison
std::vector<Report> simplerData(begin, end);
// just sort it
std::sort(begin, end);
// VERIFY by printing to console
std::cout << "Verify sorted array: " << std::endl;
std::copy(begin, end, std::ostream_iterator<Report>(std::cout, "\n"));
std::cout << "=====================" << std::endl;
std::cout << "Verify unsorted copy:" << std::endl;
std::copy(simplerData.begin(), simplerData.end(), std::ostream_iterator<Report>(std::cout, "\n"));
std::cout << "=====================" << std::endl;
// Sort that as well - for fun, reversed
std::sort(simplerData.begin(), simplerData.end(), std::not2(std::less<Report>()));
std::cout << "Verify reversed copy:" << std::endl;
std::copy(simplerData.begin(), simplerData.end(), std::ostream_iterator<Report>(std::cout, "\n"));
std::cout << "=====================" << std::endl;
}
使用编译并运行:
g++ -o test test.cpp
./test
输出:
Verify sorted array:
Report(12, 42.5)
Report(13, 42.3)
Report(14, 42.8)
Report(15, 43.1)
Report(16, 43.4)
Report(17, 43.8)
Report(18, 43.1)
=====================
Verify unsorted copy:
Report(13, 42.3)
Report(12, 42.5)
Report(14, 42.8)
Report(15, 43.1)
Report(18, 43.1)
Report(16, 43.4)
Report(17, 43.8)
=====================
Verify reversed copy:
Report(18, 43.1)
Report(17, 43.8)
Report(16, 43.4)
Report(15, 43.1)
Report(14, 42.8)
Report(13, 42.3)
Report(12, 42.5)
=====================
为了完整性,这里是我在上面建议使用std :: map时的样子。请注意,按键排序是隐式的:
namespace std // hacky, google Koenig lookup...
{
template <class K, class V> static std::ostream& operator<<(std::ostream& os, const std::pair<K, V> p)
{ os << "[" << p.first << ", " << p.second << "]"; }
}
void static UsingStdMap()
{
typedef std::map<int, double> Reports;
typedef Reports::value_type Report;
static const Report initializer[] = {Report(13,42.3),Report(12,42.5),Report(14,42.8),Report(15,43.1),Report(18,43.1),Report(16,43.4),Report(17,43.8)};
Reports theMap(initializer, initializer+sizeof(initializer)/sizeof(*initializer));
std::copy(theMap.begin(), theMap.end(), std::ostream_iterator<Report>(std::cout, "\n"));
}
我提到我有点懒吗?因此,使用流操作符显示项目的hack。 要使用自定义排序,请参阅here,例如
答案 3 :(得分:1)
因为你在C ++标签下问过这个问题,所以这是C ++中的一种方式:
typedef std::pair<Date, double> SnowReportItem;
std::vector<SnowReportItem> SnowReport;
struct sort_criteria {
bool operator()(const SnowReportItem &a, const SnowReportItem &b)
{ return a.second < b.second; }
};
SnowReport.push_back(make_pair(Date("12 Feb 2011"), 42.5));
// similar ones for the others ...
std::sort(SnowReport.begin(), SnowReport.end(), sort_criteria);
另请参阅this stackoverflow question。
编辑: std :: pair.second不是函数。
答案 4 :(得分:1)
如果您的家庭作业专门用于学习编写排序算法,请替换此代码:
// Sorting logic in ascending order
...
result = snowData[b].snowDepth;
snowData[b].snowDepth = snowData[b + 1].snowDepth;
snowData[b + 1].snowDepth = result;
...
用这个:
// Sorting logic in ascending order
...
Array tmp = snowData[b];
snowData[b] = snowData[b + 1];
snowData[b + 1] = tmp;
...
如果您的作业不是学习编写排序,请使用std::sort
:
bool Array::operator<(const Array& rhs) const { return this->snowDepth < rhs.snowDepth; }
...
// Sorting logic in ascending order
std::sort(snowData, snowData+NUM_ELEMENTS);
P.S。您的数据类型Array
名称不正确。它没有数组,只有一个观察点。
答案 5 :(得分:0)
你太近了!您比较数组元素的snowDepth
值是正确的,但您不应该只是重新排列这些值。相反,您应该重新排列整个 Array
值。
而不是:
result = snowData[b].snowDepth;
snowData[b].snowDepth = snowData[b + 1].snowDepth;
snowData[b + 1].snowDepth = result;
这样做:
Array temp = snowData[b];
snowData[b] = snowData[b + 1];
snoData[b + 1] = temp;
这将移动snowDepth
值和 date
值(因为它们是同一结构的成员)。
答案 6 :(得分:0)
您已经将数据存储在结构中,因此最简单的事情实际上就是定义运算符&lt;并换取Array
类型。
struct Array
{
int date;
double snowDepth;
void SnowData(int d, double sD)
{
date = d;
snowDepth = sD;
}
friend bool operator<(const SnowData &a, const SnowData &b)
{
return a.date < b.date;
}
friend void swap(SnowData &a, SnowData &b)
{
using std::swap;
swap(a.date, b.date);
swap(a.snowDepth, b.snowDepth);
}
};
// ...later... sort the array
std::sort(snowData, snowData + NUM_ELEMENTS);