คำถามนี้มีสองประเด็น: การแยกวิเคราะห์และการเรียงลำดับ
- คุณสามารถใช้ นิพจน์ทั่วไป เพื่อตรวจสอบประเภทข้อมูลที่ผู้ใช้ป้อน
- คุณสามารถใช้
cin
เพื่อแยกวิเคราะห์ข้อมูล
ขั้นแรก: ตระหนักว่าคุณไม่สามารถจำเป็นทราบประเภทของการป้อนข้อมูลของผู้ใช้ของคุณจนกว่าคุณจะได้รับทั้งหมด ~เช่น: พิจารณารายชื่อผู้ใช้ ชื่อ :
728278243
390349346
495045594
elizabeth
ดังนั้น ไม่ควรถือว่ารู้ดีที่สุดเกี่ยวกับข้อมูลขาเข้า (อาจนำไปสู่ประสบการณ์ผู้ใช้ที่น่าหงุดหงิด) แต่เลือกที่จะปฏิบัติต่อทุกอย่างเหมือนเป็นสตริงแทน จัดเก็บอินพุตดิบทั้งหมดเป็นสตริง เพื่อให้คุณสามารถเอาต์พุตในรูปแบบเดียวกับอินพุตได้ คุณสามารถใช้ say ซึ่งเป็นประเภทที่แจกแจงเพื่อสลับภายในตัวเปรียบเทียบการเรียงลำดับ หรือ พิจารณาใช้ mutliset/multimap
ที่นี่ คุณจะสร้างชุด สั่งซื้อ ดังนั้นจึงไม่จำเป็นต้องเรียงลำดับ หมายเหตุ: ความซับซ้อนในการสร้างชุดลำดับขององค์ประกอบ N หรือ สำหรับการเรียงลำดับเดี่ยวบนองค์ประกอบรายการที่ไม่เรียงลำดับ N นั้นเทียบเท่าโดยประมาณ ~> NlogN
สำหรับงานในมือของคุณ มันแทบจะไม่สำคัญเลย แต่ในความเป็นจริงแล้ว ขึ้นอยู่กับวิธีการใช้รายการ แนวทางใดวิธีหนึ่งจะเหมาะสมกว่าในแง่ของประสิทธิภาพ
หากคุณได้ใช้การถูกใจของ std::vector
แล้ว std::multimap
ก็ไม่น่าจะน่ากลัวเกินไป โดยทั่วไปแล้ว มันเป็นอาร์เรย์ที่เกี่ยวข้องกันของคู่คีย์-ค่า multi ที่นี่หมายความว่ามันสามารถเก็บหลายองค์ประกอบด้วยคีย์ เดียวกัน (ซึ่งที่นี่คุณต้องการ)
ในตัวอย่างนี้ ฉันกำลังใช้ไลบรารี boost regex เพื่อกำหนดประเภทข้อมูลอินพุต funky บางส่วน
(เช่น: sudo apt-get install libboost-regex1.46-dev
)
regex นี้อาจดูเป็นความลับ แต่มีตัวอย่างมากมายบน i/web สำหรับเกือบทุกรูปแบบที่เป็นไปได้ [หมายเหตุ: C++11 regex ค่อนข้างเป็นการแทนที่แบบดรอปอินสำหรับ boost regex เช่น: boost regex ควรเข้ากันได้กับมาตรฐาน C ++ 11 ที่เกิดขึ้นใหม่]
blah.cpp:
#include <iostream>
#include <sstream>
#include <string>
#include <list>
#include <map>
#include <set>
#include <boost/regex.hpp>
//NB: GNU gcc added *experimental support for regular expressions in TR1 v 4.3.0.
// compile with: -std=c++0x
using namespace std;
using namespace boost;
//some example input data-types (perhaps notably missing a date!)
const regex re_char("[^0-9]", regex_constants::extended); //non numeric chars
const regex re_digit("[[:digit:]]+", regex_constants::extended); //a string of only digits in range [0..9] ~ie: Z+
const regex re_xdigit("0[xX][[:xdigit:]]+", regex_constants::extended); //support hex iff starts with '0x' or '0X'
const regex re_float("[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?", regex_constants::extended); //all kinds of numbers
int main(int argc, char** argv)
{
int i, countc=0;
double d;
string str;
int element_count;
do
{
cout << "how many elements will there be? ";
if (cin >> element_count) break;
cin.clear();
cin >> str;
cout << "\033[A\033[2K" << flush;
}
while(13);
cin.ignore(128,'\n');
multimap<double, string> list_num;
multimap<double, string> list_fp;
//NB: below, by way of example, construction using the 'greater<int>' comparison class achieves _descending_ order
multimap<int, string, greater<int> > list_int;
list<string> list_str;
for (int next=0; next < element_count; next++)
{
cout << "\033[A\033[2K" << flush;
cout << "enter next element in list ["<< next+1 << "/" << element_count << "] : ";
getline (cin,str);
if (regex_match(str, re_xdigit))
{
//see all about manipulators here:
//http://www.cplusplus.com/reference/iostream/istream/operator%3E%3E/
stringstream(str) >> hex >> i;
list_int.insert(pair<int, string>(i, str));
list_num.insert(pair<double, string>(i, str));
}
else if (regex_match(str, re_digit))
{
stringstream(str) >> i;
list_int.insert(pair<int, string>(i, str));
list_num.insert(pair<double, string>(i, str));
}
else if (regex_match(str, re_float))
{
stringstream(str) >> d;
list_fp.insert(pair<double, string>(d, str));
list_num.insert(pair<double, string>(d, str));
}
if (regex_match(str, re_char)) countc++;
list_str.push_back(str);
}
cout << "\033[A\033[2K" << flush;
cout << "input: unsorted list:" << endl;
for (list<string>::iterator it=list_str.begin(); it!=list_str.end(); it++)
cout << *it << endl;
if (list_int.size() == element_count)
{
cout << endl << "output: sorted list of Z+ types:" << endl;
for (multimap<int, string>::iterator it=list_int.begin() ; it != list_int.end(); it++ )
cout << (*it).second << endl;
}
else if (list_fp.size() == element_count)
{
cout << endl << "output: sorted list of fp types:" << endl;
for (multimap<double, string>::iterator it=list_fp.begin() ; it != list_fp.end(); it++ )
cout << (*it).second << endl;
}
else if (list_num.size() == element_count)
{
cout << endl << "output: sorted list of numeric types:" << endl;
for (multimap<double, string>::iterator it=list_num.begin() ; it != list_num.end(); it++ )
cout << (*it).second << endl;
}
else //output as sorted strings ~but in _descending_ order, using reverse iterator, by way of example
{
list_str.sort(); //but best to use list_str.sort(greater<string>()); with forward iterators
cout << endl << "output: sorted list of " << (countc == element_count ? "non numeric char" : "string") << " types:" << endl;
for (list<string>::reverse_iterator it=list_str.rbegin(); it!=list_str.rend(); ++it)
cout << *it << endl;
}
return 0;
}
ตัวอย่างถูกรวบรวมและรันบน Ubuntu สิ่งบรรทัดคำสั่ง:
$
$ lsb_release -d
Description: Ubuntu 11.10
$ g++ --version
g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
$ g++ --pedantic -oblah blah.cpp -lboost_regex
$ ./blah
input: unsorted list:
4.77
2.0e+2
-.3
11
0x10
output: sorted list of numeric types:
-.3
4.77
11
0x10
2.0e+2
$
หมายเหตุ: นี่คือโค้ดตัวอย่าง:
- มีการเพิ่มประสิทธิภาพมากมายที่สามารถทำได้ที่นี่ เห็นได้ชัดว่าคุณไม่จำเป็นต้องต้องการคอนเทนเนอร์
stl
มากเท่าที่ฉันใช้อยู่
- ฉันไม่ได้จัดการกับทิศทางของการเรียงลำดับอย่างเคร่งครัด (แต่แสดงสองสามวิธีที่อาจบรรลุผลได้)
- อาจเป็นการดีที่จะสรุปฟังก์ชันการทำงานเฉพาะประเภทในออบเจ็กต์ C ++ มีคลาสพื้นฐาน & คลาสที่ได้รับสำหรับแต่ละ ประเภท ที่คุณต้องการสนับสนุน ~แต่การบ้านนี้ใช่ไหม - ดังนั้นอาจจะไม่คุ้มค่าที่จะลงเรือมากเกินไป ;)
person
violet313
schedule
13.06.2012
boost::any
ได้ อาร์กิวเมนต์เทมเพลตจะต้องส่งผ่านในเวลารวบรวม - person chris   schedule 10.06.2012vector<void>
ไม่ได้รับอนุญาต...vector<void*>
คือ และจริงๆ แล้ว ข้อกำหนดทั้งหมดดูค่อนข้างแปลก คุณแน่ใจหรือไม่ว่านี่เป็นวิธีที่ดีที่สุดในการเข้าถึง และนี่คือการบ้านเหรอ? - person Zaid Amir   schedule 10.06.2012Yes, this is homework.
จากนั้น คุณควรเพิ่มแท็กการบ้านในคำถามของคุณ - person Zaid Amir   schedule 10.06.2012