Ada dua aspek untuk pertanyaan ini: penguraian & pengurutan.
- Anda dapat menggunakan ekspresi reguler untuk memeriksa tipe data input pengguna.
- Anda dapat menggunakan
cin
untuk mengurai data.
Pertama: sadari bahwa Anda tidak harus mengetahui jenis masukan pengguna Anda sampai Anda menerima semuanya ~misalnya: pertimbangkan daftar pengguna nama :
728278243
390349346
495045594
elizabeth
Oleh karena itu, sebaiknya jangan berasumsi bahwa Andalah yang paling tahu tentang data yang masuk (dapat menyebabkan pengalaman pengguna yang membuat frustrasi) namun sebaliknya, lebih memilih untuk memperlakukan semuanya sebagai sebuah string. Simpan semua masukan mentah sebagai string sehingga Anda dapat menghasilkan keluaran dalam format yang sama dengan masukan. Anda dapat menggunakan, katakanlah, tipe yang disebutkan untuk beralih ke dalam pembanding pengurutan atau pertimbangkan untuk menggunakan mutliset/multimap
. di sini Anda akan membuat set terurut. jadi tidak perlu disortir. NB: kompleksitas untuk membangun kumpulan N elemen atau yang terurut, untuk satu pengurutan pada N elemen daftar yang tidak disortir, kira-kira setara ~> NlogN
Untuk tugas yang sedang Anda kerjakan, hal ini tidak menjadi masalah, namun pada kenyataannya tergantung pada bagaimana daftar tersebut digunakan, satu pendekatan atau lainnya akan jauh lebih tepat dalam hal kinerja.
Jika Anda sudah pernah menggunakan yang seperti std::vector
maka std::multimap
seharusnya tidak terlalu menakutkan. Secara longgar, ini adalah rangkaian pasangan nilai kunci yang terkait. multi di sini artinya dapat menyimpan banyak elemen dengan kunci sama (yang Anda inginkan di sini).
Dalam contoh ini saya menggunakan pustaka regex boost untuk menentukan beberapa tipe data masukan funky.
(misalnya: sudo apt-get install libboost-regex1.46-dev
)
regex ini mungkin tampak misterius tetapi ada banyak contoh di i/web untuk hampir semua pola yang bisa dibayangkan. [NB: Regex C++11 merupakan pengganti drop-in untuk boost regex. yaitu: boost regex harus kompatibel dengan standar C++11 yang sedang berkembang]
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;
}
Contoh telah dikompilasi & dijalankan di Ubuntu. Hal-hal baris perintah:
$
$ 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
$
NB: Ini contoh kodenya:
- Ada banyak optimasi yang bisa dilakukan di sini. Anda jelas tidak membutuhkan
stl
container sebanyak yang saya gunakan.
- Saya tidak secara ketat membahas arah hal tersebut (tetapi tunjukkan beberapa cara yang dapat dicapai).
- Mungkin juga bagus untuk merangkum fungsionalitas tipe spesifik dalam objek C++; punya kelas dasar & kemudian kelas turunan untuk setiap jenis yang ingin Anda dukung ~tetapi pekerjaan rumah ini kan? -jadi mungkin tidak layak untuk berlebihan;)
person
violet313
schedule
13.06.2012
boost::any
. Argumen templat harus diteruskan pada waktu kompilasi. - person chris   schedule 10.06.2012vector<void>
tidak diperbolehkan...vector<void*>
diperbolehkan. Dan sebenarnya seluruh persyaratan tampak agak aneh. Apakah Anda yakin ini adalah cara terbaik untuk melakukan pendekatan? Dan apakah ini pekerjaan rumah? - person Zaid Amir   schedule 10.06.2012Yes, this is homework.
Maka Anda harus menambahkan tag pekerjaan rumah ke pertanyaan Anda - person Zaid Amir   schedule 10.06.2012