Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: [C++] Pick funktio

Sivun loppuun

Syntty [17.06.2009 17:54:42]

#

Elikkäs, onko Pick funktiota joka valitsisi annetusta listasta yhden vaihtoehdon. Tähän funktioon olen DM kielessä ja tässä on esimerkki miten tuota käytetää DM:sssä.

var/A = pick("A","B","C","D","E")

//Eli muuttuja A olisi joku parametrien kirjaimista.

Tästä linkistä löytyy lisää tietoa.

http://www.byond.com/docs/ref/info.html#/proc/pick

Antti Laaksonen [17.06.2009 20:45:21]

#

C++ ei sisällä valmiiksi moista funktiota, mutta sen voi tehdä itse. Haluatko arpoa yhden merkin vai yhden merkkijonon?

Syntty [17.06.2009 20:55:46]

#

Merkkijonon.

Antti Laaksonen [17.06.2009 21:02:54]

#

Tässä on yksi ratkaisu:

#include <iostream>
#include <cstdlib>
#include <ctime>

std::string lista[] = {"apina", "banaani", "cembalo"};

int main(void) {
    srand(time(0));
    std::cout << lista[rand() % 3] << "\n";
}

Siis vaihtoehdot laitetaan taulukkoon ja sitten niistä arvotaan yksi.

Syntty [17.06.2009 21:15:13]

#

Aah! Kiitos tästä. Tulen tätä tarvitsemaan jatkossa.

Sisuaski [17.06.2009 22:09:40]

#

Jos haluat käyttöösi jotain tuota pick-funktiota muistuttavaa, voit tehdä sellaisen C:stä perityillä muuttuvan mittaisilla argumenttilistoilla:

#include <cstdarg>
#include <cstdlib>
#include <ctime>
#include <iostream>

using namespace std;

#define MAX_PICK_ARGS 16
const char* pick_impl(const char* first, ...)
{
        const char* choises[MAX_PICK_ARGS] = {first};
        int count=1;

        va_list ap;
        va_start(ap,first);
        while(const char* str = va_arg(ap,const char*))
                choises[count++] = str;
        va_end(ap);

        return choises[rand()%count];
}
#define pick(...) pick_impl(__VA_ARGS__, NULL)

int main()
{
        srand(time(0));
        cout << pick("a", "b", "c", "d") << endl;
}

Pick on tässä toteutettu macrona, joka kutsuu funktiota pick_impl lisäten argumenttilistan perään nullin, jotta pick_impl tietää, koska parametrit loppuvat (argumenttilistat eivät tarjoa mahdollisuutta kysyä listan kokoa). Funktio pick_impl käyttää Antin ehdottamaa ideaa, eli se vain sijoittaa parametrit taulukkoon, ja valitsee sieltä satunnaisesti.


Vastaavan toiminnallisuuden voisi myös helpohkosti toteuttaa tulevan C++-standardin variadic templateilla, joita ainakin GCC jo tukee. Tällöin tuosta saisi helposti myös geneerisemmän version, jonka argumentit voisivat olla mitä tahansa (samaa) tyyppiä, ja toteutus olisi myös tyyppiturvallisempi - nyt missään ei tarkisteta, että kaikki annetut parametrit ovat merkkijonoja.

User137 [17.06.2009 22:58:30]

#

Antti Laaksonen kirjoitti:

std::cout << lista[rand() % 3] << "\n";

Sen suuremmin C:tä tuntematta..

rand() % 3

rand() palauttaa siis desimaaliluvun [0..1[
% ottaa siitä kokonaisluku moduluksen 3:sta...
vai?? :p

Edit: Toisinsanoen
rand() palauttaa siis suuren kokonaisluvun.

os [17.06.2009 23:01:49]

#

http://letmegooglethatforyou.com/?q=c rand&l=1

Zeeli [17.06.2009 23:51:31]

#

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <vector>

template<typename T>
T pickFromVector(std::vector<T> vec) {
	if(vec.size() > 0) {
		return vec.at(rand() % vec.size());
	} else {
		return 0;
	}
}

int main() {
	srand((unsigned int)time(0));

	std::vector<int> intVector;

	intVector.push_back(5);
	intVector.push_back(10);
	intVector.push_back(15);
	intVector.push_back(20);
	intVector.push_back(25);

	int valinta = pickFromVector(intVector);

	std::cout << "Valittu luku on:" << valinta << "\n" << std::endl;
	std::cin.get();
	return 1;
}

Sisuaski [18.06.2009 03:26:20]

#

Tulipa toteutettua tämä ehdottamani C++0x-versio. Kääntö onnistuu GCC:llä vivulla -std=c++0x.

#include <cstdlib>
#include <ctime>
#include <iostream>

using namespace std;

template<class T>
T get_nth(int, T x)
{
        return x;
}

template<class T,class...A>
T get_nth(int n, T x, A... rest)
{
        return n==0 ? x : get_nth(n-1, rest...);
}

template<class T,class...A>
T pick(T x, A... rest)
{
        int count = 1+sizeof...(A);
        return get_nth(rand() % count, x, rest...);
}

int main()
{
        srand(time(0));
        cout << pick(5,10,15,20,25) << endl;
        cout << pick('a','b','c','d') << endl;
        cout << pick("sieni", "karhu", "kuusi") << endl;
}

Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta