Jump to content
Sign in to follow this  
ricardoneves93

Imprimir vectores em ficheiros txt

Recommended Posts

ricardoneves93

Bom dia, estou a fazer um projecto que é simular todo o funcionamento do euromilhões. porém ainda estou naquela parte de criar uma random key, onde crio um vector com 5 numeros de 1 a 50 e outro para as estrelas, com 2 numeros de 1 a 11, o problema é o seguinte, quando imprimo as keys, dá tudo bem, excepto certas vezes que dá um numero repetido, o que nao e pretendido. já tentei fazer um ciclo para averiguar se o numero n+1 = n, porem este nao esta a funcionar devidamente, podem-me ajudar, ou dar uma ideia de como fazer este ciclo?

Cumps, Ricardo Neves :cheesygrin:

Share this post


Link to post
Share on other sites
pmg

Sugestão: em vez de arranjares números aleatórios no intervalo pretendido e verificar se não há repetidos; arranja um array com todos os números possíveis (um para os números 1 a 50, outro para as estrelas de 1 a 11), baralha o array e escolha os N (5 ou 2) primeiros números.

Quer pretendas continuar a fazer a verificação de duplicados, ou pretendas mudar de método, se meteres aqui o teu código é mais fácil ajudar-te.


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
HappyHippyHippo

Sugestão: em vez de arranjares números aleatórios no intervalo pretendido e verificar se não há repetidos; arranja um array com todos os números possíveis (um para os números 1 a 50, outro para as estrelas de 1 a 11), baralha o array e escolha os N (5 ou 2) primeiros números.

eu acho que isso seria uma solução demasiado complexa para um problema simples como este. a solução implementada pelo @ricardoneves93 é suficiente.

Quer pretendas continuar a fazer a verificação de duplicados, ou pretendas mudar de método, se meteres aqui o teu código é mais fácil ajudar-te.

sim claro. solucionar o problema neste momento seria como olhar para um carro estacionado a 20 metros de distância e dizer o porque que não arranca.


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
ricardoneves93

Desde já, obrigado pela ajuda, eu vou colocar aqui o meu código, para que se torne mais facil:

#include <iostream>
#include <time.h>
#include <vector>
#include <fstream>
using namespace std;


int main()
{   vector <int> keyvec;
    vector <int> starvec;
int key, star, a, i, b, c;

srand ( time(NULL) ); //semente

//ciclo para criar 5 numeros random[1-50]
for (a = 0; a < 5; a++)
{
	key = rand() % 50 + 1;

	keyvec.push_back(key);

}

//ciclo para criar 2 numeros random[1-11]
for (b = 0; b < 3; b++)
{
	star = rand() % 11 + 1;
	starvec.push_back(star);
}

    ofstream keys;
	keys.open("Prize_keys.txt");

	keys << "Chave do Concurso: ";

	//ciclo que imprime no ficheiro o vector keyvec
	for (i = 0; i <= 4; i++)
{ 
	keys << keyvec[i] << " ";

}

	keys << "-  ";
	//ciclo que imprime no ficheiro o vector starvec
	for (c = 0; c <= 1; c++)
    {
        keys << starvec[c] << " ";
    }


       keys.close();

return 0;

}

PS:Se acharem que estou a complicar em alguma coisa, digam por favor :thumbsup:

Share this post


Link to post
Share on other sites
bsccara

A melhor solução é a apontada pelo pmg pois estás a obter os números aleatórios calculando o módulo dum número aleatório entre 0 e RAND_MAX (pelo  menos 32767). Como podes deduzir se te sair a série 100,23,50,12,45 da função rand() vais ter o módulo 50 igual a 0,23,0,12,45, ou seja irias obter duas vezes o nº 1 (0 + 1 no código).

O algoritmo do pmg garante-te que não terás números repetidos; da maneira que estás a fazer não tens essa garantia. Pensa na maneira como é feita a extracção dos jogos da Santa Casa; após cada número sair ele é retirado da tombola. É a mesma coisa.

Share this post


Link to post
Share on other sites
HappyHippyHippo

novamente volto a apontar que apesar da solução do pmg ser válida, continua a achar que esta solução é mais simples:

int main() {
  int valores[5];
  int i = 0, j = 0, check = 0;
  srand(time(NULL));
  while (i < 5) {
      valores[i] = (rand() % 50) + 1;
      check = 1;
      for(j = 0; j < i - 1; j++) {
         if (valores[j] == valores[i])
           check = 0;
      }
      if (check)
        i++;
  }
}

do que

int main() {
  int valores[50];
  int i = 0, j, k, aux;

  for (i = 1; i <= 50; i++)
    valores[i-1] = i;

  // "super" algoritmo de "baralhamento" com base na função rand()
  for (i = 0; i < 50*100; i++) {
    j = rand() % 50;
    k = rand() % 50;

    aux = valores[j];
    valores[j] = valores[k};
    valores[k] = aux;
  }
}

talvez sou demasiado velho para aceitar a segunda hipótese ou pensar que na primeira opção tem um aspecto que demore menos tempo ...


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
pmg
for (i = 0; i < 50*100; i++) 

Yikes!, baralha com o algoritmo de Knuth!

 /* devolve um valor uniformemente distribuido no intervalo [0, n[ */
int randto(int n) {
  int r, maxr = (RAND_MAX / n) * n;
  do r = rand(); while (r >= maxr);
  return r % n;
}
void shuffle(int *a, size_t n) {
  for (size_t k = n; k > 1; k--) {
    int r = randto(k);
    swap(a + k - 1, a + r); /* swap mesmo que a + k - 1 seja o mesmo que a + r */
  }
}

Mas para escolher 5 valores distintos de entre 50 o ciclo interno para verificação também serve.

De qualquer maneira, tanto um como o outro demoram menos tempo a executar que a tecla Enter a ir para baixo ...


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
pikax

que use Mother-of-All ou Xorshift :thumbsup:

http://www.stat.fsu.edu/pub/diehard

http://en.wikipedia.org/wiki/George_Marsaglia

ftp://ftp.forth.org/pub/C/mother.c

http://www.agner.org/random

http://www.jstatsoft.org/v08/i14/paper

cheguei a fazer um programa do genero, e utilizei um vector para armazenar as 50 posições, e andava a baralha-lo +30 vezes :)

chave gera_chave()
{
    vector<uint>::iterator it;

    uint temp;

    vector<uint> v_chaves;

    v_chaves.push_back(gera_random(50));


    for(int i=0;i<4;i++)
    {
        do
        {
            random_shuffle(numeros.begin(),numeros.end(),p_myrandom);
            temp=numeros.back();
            it = find (v_chaves.begin(), v_chaves.end(), temp);
        }while(it!=v_chaves.end());
        v_chaves.push_back(temp);
    }

    vector<uint> v_est;
    for(int i=0;i<2;i++)
    {
        do
        {
            random_shuffle(estrelas.begin(),estrelas.end(),p_myrandom);
            temp=estrelas.back();
            it = find (v_est.begin(), v_est.end(), temp);
        }while(it!=v_est.end());
        v_est.push_back(temp);
    }

    sort(v_chaves.begin(),v_chaves.end());
    sort(v_est.begin(),v_est.end());

    return chave(v_chaves[0],v_chaves[1],v_chaves[2],v_chaves[3],v_chaves[4],v_est[0],v_est[1]);
}

http://www.portugal-a-programar.pt/index.php?showtopic=45606


Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Share this post


Link to post
Share on other sites
bsccara

novamente volto a apontar que apesar da solução do pmg ser válida, continua a achar que esta solução é mais simples:

...

talvez sou demasiado velho para aceitar a segunda hipótese ou pensar que na primeira opção tem um aspecto que demore menos tempo ...

Não tem nada a ver com a idade porque eu também já tou com uma boa dose de caruncho. :thumbsup:

O meu raciocínio é que a minha definição de uma sequência aleatória é uma em que, com um tamanho suficientemente grande, todos os possíveis valores ocorrem o mesmo número de vezes. Repara que não garante que os valores não se repetirão.

Quando é feito o módulo duma série aleatória, os valores possíveis dentro da série irão ser comprimidos, pelo que a ocorrência de duplicações aumenta.

Logo, se bem que seja apenas uma probabilidade estatística, parece-me possível que a série aleatória gere consecutivamente valores que ao serem reduzidos pelo módulo sejam iguais. No limite é estatisticamente possível que o algoritmo que indicaste nunca termine.

Devo frisar que matemática não é uma paixão minha, longe disso, mas julgo que o meu raciocínio está correcto.

Share this post


Link to post
Share on other sites
ricardoneves93

Yikes!, baralha com o algoritmo de Knuth!

 /* devolve um valor uniformemente distribuido no intervalo [0, n[ */
int randto(int n) {
  int r, maxr = (RAND_MAX / n) * n;
  do r = rand(); while (r >= maxr);
  return r % n;
}
void shuffle(int *a, size_t n) {
  for (size_t k = n; k > 1; k--) {
    int r = randto(k);
    swap(a + k - 1, a + r); /* swap mesmo que a + k - 1 seja o mesmo que a + r */
  }
}

Mas para escolher 5 valores distintos de entre 50 o ciclo interno para verificação também serve.

De qualquer maneira, tanto um como o outro demoram menos tempo a executar que a tecla Enter a ir para baixo ...

peço desculpa, mas o que queres dizes com: int valores[5];---> nao estas a definir um vector, tas a aceder á 5ª posicao do vector? se sim porque?

Share this post


Link to post
Share on other sites
pmg

peço desculpa, mas o que queres dizes com: int valores[5];---> nao estas a definir um vector, tas a aceder á 5ª posicao do vector? se sim porque?

Nao fui eu quem disse isso, foi o Hippo.

Como o codigo do Hippo esta apontado como C, posso-te responder que a linha em questao

int valores[5]; // cria array com espaco para 5 elementos

faz exactamente o que perguntas: ou seja define um array chamado valores com espaco para 5 valores de tipo int. Para aceder ao 5 elemento seria com "valores[4]" numa meio duma instrucao, por exemplo

a = valores[4]; // acede ao quinto elemento

A diferenca entre as duas é que a primeira "instrucao" comeca com um tipo.


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
HappyHippyHippo

Nao fui eu quem disse isso, foi o Hippo.

na realidade não vejo nenhum post com essa info ...  🤔


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
ricardoneves93

Graças á vossa ajuda, ja tou a evoluir um bocado, porém ainda nao esta totalmente funcional, a minha ideia era fazer em "4 partes", primeiro ver se o valor da posição 0 é igual á posição 1, 2, 3, 4. a seguir ver se o valor da posição 1 é igual à posição 2, 3, 4 e assim sucessivamente. Vou postar aqui o fragmento de codigo que faz isso, porem ainda esta um bocado confuso e nao funciona correctamente:

{while (y <= 4)

{while (d <= r)

{if(keyvec[d] == keyvec[d+1])

{do

{

keyvec[d] = key;

}

while (keyvec [d] == keyvec[d+1]);

}

d++;

}

r--;

}

y++;

}

Se souberem uma forma de estes ciclos ficarem mais organizados, ou se virem erros(que vao encontrar) digam alguma coisa :confused:

Cumps Ricardo Neves

Share this post


Link to post
Share on other sites
bsccara

Onde foste buscar esta ideia do

{while (y <= 4)

em vez de

while (y <= 4) {

?

E as variáveis y, d, r e key são inicializadas a quê ?

Share this post


Link to post
Share on other sites
pmg

Onde foste buscar esta ideia do

{while (y <= 4)

Ehehehehe LOL!

O primeiro { não "pertence" ao while ... "pertence", por exemplo, ao main.

O ricardoneves usa uma indentação um bocado esquisita ... mas mais nada :D:confused:


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
bsccara

O ricardoneves usa uma indentação um bocado esquisita ... mas mais nada :D:confused:

Olha que não é só esse o problema; vê o código correctamente indentado. O ciclo exterior nunca termina.

{
  while (y <= 4)
  {
    while (d <= r)
    {
      if(keyvec[d] == keyvec[d+1])
      {
        do
        {
          keyvec[d] = key;
        } while (keyvec [d] == keyvec[d+1]);
      }
      d++;
    }
    r--;
  }
  y++;
}

Share this post


Link to post
Share on other sites
pmg
O ciclo exterior nunca termina.

A meu ver, termina.

Com a minha indentação, o código fica assim

while (y <= 4) {
    /* coisas que não mudam o y */
    y++;
}

Que me parece bem ... :confused:

As coisas que não mudam o y são

while (d <= r) {
    /* coisas que não mudam o d, nem o r */
    d++;
}

Que me parece bem ... :D

As coisas que não mudam o d nem o r são

if (keyvec[d] == keyvec[d + 1]) {
    do {
        keyvec[d] = key;
    } while (keyvec[d] == keyvec[d + 1]);
}

Que também não me parece mal ... :D

O código completo é então

{ // chaveta extra, do main?
    while (y <= 4) {
        while (d <= r) {
            if (keyvec[d] == keyvec[d + 1]) {
                do {
                    keyvec[d] = key;
                } while (keyvec[d] == keyvec[d + 1]);
            }
            d++;
        }
        y++;
    }
} // chaveta extra, do main?


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
bsccara

Andamos a perder tempo com um pormenor: repara que no código postado originalmente apenas existe uma chaveta depois de 'y++', logo essa instrução é exterior ao ciclo (considerando que a primeira e última chaveta são para ignorar)...

Share this post


Link to post
Share on other sites
pmg

Oops ... pois é. Algures no meio de tanta confusao cheguei até a perder o r--.

Bom, que isto sirva de licao para mim. Quando alguem usar indentacao esquisita, nao tentar descortinar a olho.


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
ricardoneves93

isto esta-se a tornar dificil, decidi fazer de outra forma, mas mesmo assim nao esta a funcionar direito, desta vez á medida que vai construindo o vector, vai verificando se os numeros sao iguais por exemplo neste vector parcialmente construido [2|3|2......, o que vai ser feito é: 2=3? nao 2=2? é, entao cria outro random de 1 a 5 e percorre o ciclo ate que o 3º elemento seja diferente de 2, mas ha um problema, se ele criar o 3 vai dar true, porem é igual ao 2º elemento.

Aqui esta o codigo:

r e x  sao inicializados a zero

while (r <= 4)

{

do

{

keyvec [r] = rand() % 5 + 1;

if(keyvec [r] == keyvec [r - x])

{

keyvec [r] = rand() % 5 + 1;

}

x++;

}

while ( x <= r);

r++;

x = 1;

                }

Cumps Ricardo Neves

Share this post


Link to post
Share on other sites
pikax
Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

while (r <= 4)
	{
		do
		{
			keyvec [r] = rand() % 5 + 1;

			if(keyvec [r] == keyvec [r - x])
			{
				keyvec [r] = rand() % 5 + 1;
			}
			x++;
		}

		while ( x <= r);
		r++;
		x = 1; 
                 }

Seria menos confuso se em vez de gerares a chave no array, gerares a chave numa varivel temporaria e depois quando passar no "teste", entao po-la na posicao correcta do array.

bool verificaArray(int *chave,int valor,int size_arr)
{
    for(int i=0;i<size_arr;i++)
        if(chave[i]==valor)
            return true;
    return false;
}

//.......

    for(int i=0; i<4;i++)
    {
        temp = rand() % 50 + 1;
        while(verificaArray(keyvec,temp,4))
        {
            temp=rand()%5+1;
        }
        keyvec[i]=temp;
    }

isto esta-se a tornar dificil, decidi fazer de outra forma, mas mesmo assim nao esta a funcionar direito, desta vez á medida que vai construindo o vector, vai verificando se os numeros sao iguais por exemplo neste vector parcialmente construido [2|3|2......, o que vai ser feito é: 2=3? nao 2=2? é, entao cria outro random de 1 a 5 e percorre o ciclo ate que o 3º elemento seja diferente de 2, mas ha um problema, se ele criar o 3 vai dar true, porem é igual ao 2º elemento.

Aqui esta o codigo:

r e x  sao inicializados a zero

//.....

Cumps Ricardo Neves

Quando chegas ao do{...}while; ele ira fazer uma verificacao se existem numeros repetidos, porem tas a gerar um numero novo a cada passagem no array.


Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Share this post


Link to post
Share on other sites
ricardoneves93

Bom como com um ciclo nao estava a resultar decidi fazer de uma forma mais directa, e o que é certo e que funciona ;)

#include <iostream>

#include <time.h>

#include <vector>

#include <fstream>

using namespace std;

int main()
{   vector <int> keyvec;
    vector <int> starvec;
int key, star, a, i, b, c, x = 0, r=0;

srand ( time(NULL) ); //semente

//ciclo para criar 5 numeros random[1-50]

for (a = 0; a < 5; a++)
        {
                key = rand() % 50 + 1;

                keyvec.push_back(key);
               
        }



//ciclos que verificam se existe algum numero igual (keyvec)
do

	{
		if (keyvec [1] == keyvec [0])
			{
				keyvec[1] = rand() % 5 + 1;
			}
	}
	while (keyvec [1] == keyvec [0]);

do

	{
		if ((keyvec [2] == keyvec [1]) || (keyvec [2] == keyvec [0]))
			{
				keyvec[2] = rand() % 5 + 1;
			}
	}
	while ((keyvec [2] == keyvec [1]) || (keyvec [2] == keyvec [0]));

do

	{
		if (((keyvec [3] == keyvec [2]) || (keyvec [3] == keyvec [1])) || (keyvec [3] == keyvec [0]))
			{
				keyvec[3] = rand() % 5 + 1;
			}
	}
	while (((keyvec [3] == keyvec [2]) || (keyvec [3] == keyvec [1])) || (keyvec [3] == keyvec [0]));

do

	{
		if ((((keyvec [4] == keyvec [3]) || (keyvec [4] == keyvec [2])) || (keyvec [4] == keyvec [1])) || (keyvec [4] == keyvec [0]))
			{
				keyvec[4] = rand() % 5 + 1;
			}
	}
	while ((((keyvec [4] == keyvec [3]) || (keyvec [4] == keyvec [2])) || (keyvec [4] == keyvec [1])) || (keyvec [4] == keyvec [0]));





//ciclo para criar 2 numeros random[1-11]
for (b = 0; b < 3; b++)
{
	star = rand() % 11 + 1;
	starvec.push_back(star);
}

//ciclo que verifica se existe algum numero igual (startvec)
if (starvec[0] == starvec[1])
	{ do 
		{
			(starvec[1] = star);
		}

	while (starvec[0] == starvec[1]);
}

    ofstream keys;
	keys.open("Prize_keys.txt");

	keys << "Chave do Concurso: ";

	//ciclo que imprime no ficheiro o vector keyvec
	for (i = 0; i <= 4; i++)
{ 
	keys << keyvec[i] << " ";

}

	keys << "-  ";
	//ciclo que imprime no ficheiro o vector starvec
	for (c = 0; c <= 1; c++)
    {
        keys << starvec[c] << " ";
    }


       keys.close();

return 0;

}

Share this post


Link to post
Share on other sites
HappyHippyHippo

foi -te apresentadas soluções em menos de 10 linhas ... porquê que estás a fazer dessa maneira ??


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.