我正在嘗試按日期對二維向量進行排序和列印,該日期以 DD-MM-YYYY 格式存盤在列中。我有一個以字串形式存盤的“預加載”票證,并首先通過它回圈以通過Username獲取票證。
從那里,我會在排序和列印之前列印將用戶的票推回二維向量。例如,我在輸入用戶名“kaya”后得到的錯誤是: 除錯斷言失敗!運算式:向量下標超出范圍 錯誤訊息]( https://i.stack.imgur.com/qG8C3.png )
即使我沒有排序就列印出向量,結果仍然很奇怪,所以我不確定是不是因為我推錯了,也影響了排序。這是我的意思的奇怪輸出:
*Search Ticket by Username
kaya
invalid. Please try again
2 RM40.0 10 15 3 5 2 kaya 15-10-2020 09:30 10:00
6 RM5.0 5 2 3 4 2 kaya 23-06-2022 08:30 09:30
2
RM40.0
10
15
3
5
2
kaya
15-10-2020
09:30
10:00
6
RM5.0
5
2
3
4
2
kaya
23-06-2022
08:30
09:30
C:\Users\Kar Yee\source\repos\DSTR_KyTest\Debug\DSTR_KyTest.exe (process 4044) exited with code 0.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . .*
我的完整代碼以及到目前為止我嘗試過的內容:
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm> // for sort()
string defaultTickets[][11] =
//ticket_id, total_amount,total_distance, total_travelTime,departure_station_id,
//arrival_station_id, user_id, user_name, date, estimated_departure_time, estimated_arrival_time
{
{"1", "RM20.0", "20", "30", "1", "5", "1", "bob", "10-10-2022", "08:30", "10:30"},
{"2", "RM40.0", "10", "15", "3", "5", "2", "kaya", "15-10-2020", "09:30", "10:00"},
{"3", "RM25.0", "5", "10", "5", "6", "1", "bob", "10-05-2022", "11:30", "012:30"},
{"5", "RM30.0", "13", "40", "1", "6", "4", "zhen Hou", "23-05-2022", "08:00", "09:00"},
{"6", "RM5.0", "5", "2", "3", "4", "2", "kaya", "23-06-2022", "08:30", "09:30"},
{"7", "RM8.0", "8", "4", "1", "3", "4", "zhen Hou", "20-05-2022", "08:45", "09:00"},
{"8", "RM10.0", "3", "10", "4", "6", "1", "bob", "10-05-2022", "09:00", "10:00"},
};
bool SortDateColumn(const std::vector<std::string>& a1,
const std::vector<std::string>& a2)
{
return atoi(a1[8].c_str()) > atoi(a2[8].c_str());
}
int main() {
int num_col = 10;
int num_row = 7;
string search_user = "";
// declare 2D vector
vector< vector<string>> ticketVector(num_row, vector<string>(num_col)); //preset row and columns
//vector< vector<string>> ticketVector();
int size = *(&defaultTickets 1) - defaultTickets;
bool valid = false;
cout << "Search Ticket by Username" << endl;
cin >> search_user;
for (int i = 0; i < size; i )
{
if (search_user == defaultTickets[i][7])
{
/*cout << "Ticket ID\t Amount Paid\t Distance\t TravelTime \tDeparture_station_id \t Arrival_station_id \tUserID \t Username" << "";
cout << "\tdate \testimated_departure_time \testimated_arrival_time" << "\n";*/
for (int x = 0; x < 11; x )
{
cout << defaultTickets[i][x] << "\t";
ticketVector.push_back({ defaultTickets[i][x] });
valid = true;
}
cout << endl;
}
if (valid == false)
{
cout << "invalid. Please try again" << endl;
}
}
//sort(ticketVector[8].begin(), ticketVector[8].end());
/*std::sort (ticketVector.begin(), ticketVector.end(), [](value& a, value& b)->bool { return a.date < b.date; });
for (auto& x : ticketVector) cout << x.date << endl;
return 0;*/
//Sort the data using the first column of each `std::vector<std::string>` as the criteria
std::sort(ticketVector.begin(), ticketVector.end(), SortDateColumn);
//print vector
for (int i = 0;i < ticketVector.size();i ) {
for (int j = 0;j < ticketVector[i].size();j )
cout << ticketVector[i][j] << "";
cout << endl;
}
}
uj5u.com熱心網友回復:
由于您的日期符合格式 DD-MM-YYYY,如果您只是將字符重新排列為 YYYYMMDD,它們可以按字典順序排列。但是,作為排序操作的一部分,您通常希望避免任何型別的動態分配或復制(例如,每次都重新構建一個字串)。
因此,您可以通過將std::string_view與std::tuple相結合來實作這一點。您可以使用 string_view 獲取相關的子字串,并使用元組將它們按正確的順序排列。元組已經支持排序。
#include <string_view>
#include <tuple>
using std::string_view;
using std::tuple;
typedef tuple<string_view, string_view, string_view> DateView;
DateView YYYYMMDD(const string& s)
{
if (s.size() != 10 || s[2] != '-' || s[5] != '-')
return {};
return DateView{
string_view(s.c_str() 6, 4), // YYYY
string_view(s.c_str() 3, 2), // MM
string_view(s.c_str() 0, 2) // DD
};
}
// Returns true if date 'a' is less than date 'b'
bool CompareDate(const string& a, const string& b)
{
return YYYYMMDD(a) < YYYYMMDD(b);
}
現在你有了排序的基礎。由于您想反向排序日期,您可以反轉CompareDate函式的結果:
int main()
{
vector<string> dates = {
"10-10-2022",
"15-10-2020",
"10-05-2022",
"23-05-2022",
"23-06-2022",
"20-05-2022",
"10-05-2022",
};
std::sort(dates.begin(), dates.end(),
[](const string& a, const string& b) { return !CompareDate(a, b); });
for (const auto& date : dates)
{
cout << date << "\n";
}
}
至于你開始的向量的實際構造,它有點混亂。ticketsVector每當您匹配名稱時,您都會將單個元素推入。結果,當您假設它們包含一整行時,您稍后會越界訪問這些向量。
與其將票證復制到一個新的向量中,為什么不實際將它們創建為一個向量呢?您可以通過行索引而不是復制來參考票證。您可能還想使用列舉來標識列,而不是使用神奇的硬編碼數字。
enum Column
{
kTicketId, kTotalAmount, kTotalDistance, kTotalTravelTime,
kDepartureStationId, kArrivalStationId, kUserId, kUserName,
kDate, kEstimatedDepartureTime, kEstimatedArrivalTime
};
vector<vector<string>> defaultTickets =
{
{"1", "RM20.0", "20", "30", "1", "5", "1", "bob", "10-10-2022", "08:30", "10:30"},
{"2", "RM40.0", "10", "15", "3", "5", "2", "kaya", "15-10-2020", "09:30", "10:00"},
{"3", "RM25.0", "5", "10", "5", "6", "1", "bob", "10-05-2022", "11:30", "012:30"},
{"5", "RM30.0", "13", "40", "1", "6", "4", "zhen Hou", "23-05-2022", "08:00", "09:00"},
{"6", "RM5.0", "5", "2", "3", "4", "2", "kaya", "23-06-2022", "08:30", "09:30"},
{"7", "RM8.0", "8", "4", "1", "3", "4", "zhen Hou", "20-05-2022", "08:45", "09:00"},
{"8", "RM10.0", "3", "10", "4", "6", "1", "bob", "10-05-2022", "09:00", "10:00"},
};
然后,您可以定義排序以對行索引進行操作:
// Sort predicate to order by date in reverse
bool SortDateColumn(int a, int b)
{
return !CompareDate(defaultTickets[a][kDate], defaultTickets[b][kDate]);
}
// Helper to output a ticket
void OutputTicket(int i)
{
const auto& ticket = defaultTickets.at(i);
for (const auto& col : ticket)
{
cout << col << " ";
}
cout << "\n";
}
這是您使用上述所有內容的程式,整理了一下:
int main()
{
string search_user;
cin >> search_user;
// Get tickets for user
vector<int> tickets;
for (int i = 0; i < defaultTickets.size(); i )
{
if (search_user == defaultTickets[i][kUserName])
{
tickets.push_back(i);
}
}
if (tickets.empty())
{
cout << "invalid. Please try again" << endl;
return -1;
}
// Sort tickets and output results
std::sort(tickets.begin(), tickets.end(), SortDateColumn);
for (int t : tickets)
{
OutputTicket(t);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/522172.html
標籤:C 排序印刷二维向量
