Ir ao conteúdo
  • Cadastre-se

C++ Ler tamanho da entrada para criar vetores


Clancy Gilroy
Ir à solução Resolvido por V!OLADOR,

Posts recomendados

Olá, tenho uma questão que é a seguinte:

Escreva uma função que recebe dois vetores de inteiros e um inteiro informando o tamanho destes
vetores. Ou seja, sua função vai assumir que os vetores fornecidos possuem o mesmo tamanho.
Sua função deve retornar o maior valor armazenado em algum dos dois vetores.
Em outras palavras, se A é o conjunto de valores armazenados no primeiro vetor e B é o conjunto
de valores armazenados no segundo vetor, então valor que a função deve retornar é
max (fmax(A); max(B)g) ; onde max(X) e o maior valor do conjunto X.

 

eu fiz da forma abaixo, mas como eu não tenho nenhuma inicialização está dando um erro, eu acho que precisa de alguma classe c++ pra ler o tamanho da entrada, alguém pode me ajudar?

#include <iostream>
#include <cstdlib>

using namespace std;

int maiorval(int A[], int B[], int tam){
	
	int i;
	int max_a = -99999;
	int max_b = -99999;
	
	for(i=0 ; i<tam ; i++){
        srand(i);
        cout<<rand()<<endl;
    }
	
	for(i=0;i<tam;i++){
		if(A[i] > max_a)
			max_a = A[i];
		if(A[i] > max_b)
			max_b = B[i];
	}
	
	if(max_a>max_b)
		return max_a;
	else 
		return max_b;
}

int main(){
	
	int i;
	int A[i];
	int B[i];
	int maior, maiorvalor, tam;
	
	cout << "Digite o tamanho do vetor" << endl;
	cin >> tam;
	
	maior = maiorval(A, B, tam);
	
	cout << "Maior valor e " << maior << endl;
	
	return 0;
}

 

Link para o comentário
Compartilhar em outros sites

  • Solução

Há vários errinhos. Primeiro, se A e B vão ter tamanhos variáveis determinados pelo usuário, você deve usar ponteiros e alocar memoria dinamicamente, por exemplo,

 

int *A = new int[tam];
int *B = new int[tam];

 

E lembre-se de liberar os recursos alocados ao final,

 

delete[] A;
delete[] B;

return 0;

 

Segundo, os vetores no seu caso estariam vazios -- ou, sendo muito otimista, com lixo oriundo da memoria alocada (dependendo do compilador). Em nenhum momento você atribuiu valores. Os elementos aleatórios produzidos por rand devem ser dados a ambos, A e B, por exemplo,

 

A[i] = rand();

 

O mesmo pra B. A inicialização de números aleatórios, feito por srand, pode ser feito apenas uma vez, fora do for. Você pode utilizar, por exemplo,

 

srand(time(NULL));

 

Ou seja, usar o retorno de time como inicializador. Apenas certifique-se de que está gerando números aleatórios diferentes pra cada caso, A e B.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

48 minutos atrás, rafaelst07 disse:

Escreva uma função que recebe dois vetores de inteiros e um inteiro informando o tamanho destes
vetores. Ou seja, sua função vai assumir que os vetores fornecidos possuem o mesmo tamanho.
Sua função deve retornar o maior valor armazenado em algum dos dois vetores.
Em outras palavras, se A é o conjunto de valores armazenados no primeiro vetor e B é o conjunto
de valores armazenados no segundo vetor, então valor que a função deve retornar é
max (fmax(A); max(B)g) ; onde max(X) e o maior valor do conjunto X

 

Em C++ vetores são declarados como... vector. Trata-se de algo chamado template class e pode ser um vetor de qualquer coisa, por exemplo de int.

Está certo de que é para usar essas coisas como int[]? Isso são arrays em C e vector em C++ tem 40 anos já.

Exemplo
 

#include <iostream>
#include <vector>
using namespace std;

int maior_valor(vector<int>, vector<int>) { return 0; }; // ou mesmo
int maior_valor(int N, int A[], int B[]) { return 0; };

int main(void)
{
	vector<int> A;
	vector<int> B;
	return 0;
}

 

adicionado 11 minutos depois

Sobre a lógica do programa, as chamadas a rand() e srand() estão totalmente fora de contexto.

 

Seu objetivo é escrever essa função
 

int maior_valor(vector<int>, vector<int>) { return 0; }; // ou mesmo
int maior_valor(int N, int A[], int B[]) { return 0; };

 

Note que em C++ você pode declarar várias funções com o mesmo nome. Isso se chama overload.

 

E dentro dessa função você procura o maior valor presente nos vetores e retorna. Só isso.

 

Se quer preencher o vetor com valores aleatórios faça isso antes de chamar a função, em, main() nesse caso.

 

E se vai preencher com valores aleatórios porque chatear o usuário perguntando o tamanho do vetor e não usar um valor aleatório também para o tamanho, já que o enunciado nada fala sobre ler valores?

 

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

10 horas atrás, arfneto disse:

 

Em C++ vetores são declarados como... vector. Trata-se de algo chamado template class e pode ser um vetor de qualquer coisa, por exemplo de int.

Está certo de que é para usar essas coisas como int[]? Isso são arrays em C e vector em C++ tem 40 anos já.

Exemplo
 


#include <iostream>
#include <vector>
using namespace std;

int maior_valor(vector<int>, vector<int>) { return 0; }; // ou mesmo
int maior_valor(int N, int A[], int B[]) { return 0; };

int main(void)
{
	vector<int> A;
	vector<int> B;
	return 0;
}

 

adicionado 11 minutos depois

Sobre a lógica do programa, as chamadas a rand() e srand() estão totalmente fora de contexto.

 

Seu objetivo é escrever essa função
 


int maior_valor(vector<int>, vector<int>) { return 0; }; // ou mesmo
int maior_valor(int N, int A[], int B[]) { return 0; };

 

Note que em C++ você pode declarar várias funções com o mesmo nome. Isso se chama overload.

 

E dentro dessa função você procura o maior valor presente nos vetores e retorna. Só isso.

 

Se quer preencher o vetor com valores aleatórios faça isso antes de chamar a função, em, main() nesse caso.

 

E se vai preencher com valores aleatórios porque chatear o usuário perguntando o tamanho do vetor e não usar um valor aleatório também para o tamanho, já que o enunciado nada fala sobre ler valores?

 

 

 

entendi, então nesse caso não precisaria de ponteiros, certo? por que acho que não precisaria de ponteiros mesmo nessa questão...

adicionado 2 minutos depois
1 hora atrás, Flávio Pedroza disse:

int main(){
	

	int maior, maiorvalor, tam;
	
	cout << "Digite o tamanho do vetor" << endl;
	cin >> tam;
	int A[tam];
	int B[tam];
	
	maior = maiorval(A, B, tam);
	
	cout << "Maior valor e " << maior << endl;
	
	return 0;
}

 

nesse teu caso ainda ficou com erro...

adicionado 3 minutos depois

refiz conforme o que vcs me passaram, nesse exemplo eu tirei a possibilidade de digitar o tamanho do vetor

#include <iostream>
#include <cstdlib>
#include <time.h>

using namespace std;

int maiorval(int A[], int B[], int tam){
	
	int i;
	int max_a = -99999;
	int max_b = -99999;
	
	/*for(i=0 ; i<tam ; i++){
        srand(i);
        cout<<rand()<<endl;
    }*/
    srand(time(NULL));
	
	for(i=0;i<tam;i++){
		if(A[i] > max_a)
			max_a = A[i];
		if(A[i] > max_b)
			max_b = B[i];
	}
	
	if(max_a>max_b)
		return max_a;
	else 
		return max_b;
}

int main(){
	
	int maior, maiorvalor, tam;
	
	tam = 5;
	
//	cout << "Digite o tamanho do vetor" << endl;
//	cin >> tam;

	int A[tam]=rand();
	int B[tam]=rand();
	
	maior = maiorval(A, B, tam);
	
	cout << "Maior valor e " << maior << endl;
	
	return 0;
}

 

adicionado 4 minutos depois

mas ainda continua com um erro, e aqui diz que é na parte do rand(), que não tem um inicializador.

Link para o comentário
Compartilhar em outros sites

Não pode escrever assim, @Flávio Pedroza


tam nesse caso deve ser uma constante que possa ser avaliada em tempo de compilação, não um valor a ser lido quando o programa está executando.

 

image.png.26fd849beecb99a0e7c21851d911c013.png

 

Para usar algo assim
 

#include <iostream>
#include <vector>

using namespace std;

int main(void)
{
	int tam = 8;
	vector<int>A(tam);
	vector<int>B(tam + 3);
	cout << "Tamanhos: A: " << A.size()
		<< " B: " << B.size() << endl;
	cout << "Colocando -998 e -999 no final de A e B\n";
	A[A.size() - 1] = -998;
	B[B.size() - 1] = -999;
	cout << "Ultimos elementos de A e B: " <<
		A[A.size() - 1] << " e " <<
		B[B.size() - 1] << "...\n";
	return 0;
}

 

que mostra
 

Tamanhos: A: 8 B: 11
Colocando -998 e -999 no final de A e B
Ultimos elementos de A e B: -998 e -999...

 

Como esperado.

 

Porque funciona?

 

vector é uma classe e um dos possíveis construtores é esse do exemplo: um int como tamanho, avaliado claro em tempo de execução.

Veja todos em vector em CPlusPlus.com
 

image.thumb.png.52186ecdbd7ffe0175d845adbc8dc749.png

Link para o comentário
Compartilhar em outros sites

O compilador sempre tem razão, @rafaelst07 😁.

 

Você deve chamar srand pra fazer a inicialização antes de usar rand pela primeira vez.

 

Se tam = 5, então A[5] = rand( ) tampouco faz sentido, certo? você deve chamar rand dentro de um laço de maneira que cada um dos 5 elementos tenha um número aleatório diferente.

 

 

Link para o comentário
Compartilhar em outros sites

13 minutos atrás, rafaelst07 disse:

entendi, então nesse caso não precisaria de ponteiros, certo? por que acho que não precisaria de ponteiros mesmo nessa questão

 

Se usar vector não. Se usar int* ou int[] sim. Trata-se de dançar conforme a música

 

14 minutos atrás, rafaelst07 disse:

nesse teu caso ainda ficou com erro


Está errado. Veja o que expliquei

 

Link para o comentário
Compartilhar em outros sites

35 minutos atrás, V!OLADOR disse:

O compilador sempre tem razão, @rafaelst07 😁.

 

Você deve chamar srand pra fazer a inicialização antes de usar rand pela primeira vez.

 

Se tam = 5, então A[5] = rand( ) tampouco faz sentido, certo? você deve chamar rand dentro de um laço de maneira que cada um dos 5 elementos tenha um número aleatório diferente.

 

 

ainda estou com dúvidas nesse lance do rand, já que eu vi pouca coisa sobre, eu refiz aqui sem ter que usar o rand, ficou assim:

#include <iostream>
#include <cstdlib>

using namespace std;

int maiorval(int A[], int B[], int tam){
	
	int i;
	int max_a = -99999;
	int max_b = -99999;
	
	for(i=0;i<tam;i++){
		if(A[i] > max_a)
			max_a = A[i];
		if(A[i] > max_b)
			max_b = B[i];
	}
	
	if(max_a>max_b)
		return max_a;
	else 
		return max_b;
}

int main(){
	
	int i;
	int A[]={1, 2, 3, 4, 5, 8};
	int B[]={2, 3, 4, 5, 6, 9};
	int maior, maiorvalor, tam = 6;
	
	maior = maiorval(A, B, tam);
	
	cout << "Maior valor e " << maior << endl;
	
	return 0;
}

tem como me explicar melhor como usar o rand a partir desse código?

Link para o comentário
Compartilhar em outros sites

Basicamente, "rand" significa "random" em inglês e retorna valores aleatórios a cada chamada. Ou seja, em A[0] = rand() e A[1] = rand(), muito provavelmente, A[0] != A[1].

 

Mas algoritmos que geram números (pseudo) aleatórios precisam de um inicializador, em inglês usa-se o termo "seed" (semente).

 

Essa é a função de srand, fornecer um inicializador, um número, do qual o algoritmo poderá criar outros números aleatórios. E sempre deve ser chamado, ou seja inicializado, antes do uso do algoritmo.

 

Você é livre pra escolher um inicializador. O tempo, de time(NULL), é um parâmetro que funciona bem em casos simples.

 

Caso, use por exemplo srand(3), então, com um inicializador constante, os mesmos números aleatórios serão criados a cada execução do programa. Dependendo da implementação, claro.

 

Por isso chama-se gerador de números pseudo aleatórios.

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

9 minutos atrás, rafaelst07 disse:

tem como me explicar melhor como usar o rand a partir desse código?

 

Esse código fica sem sentido se vai usar rand() para preencher o vetor. Qual o propósito de colocar valores se não vai usar?

Esse é um programa em C. C++ tem 40 anos e não é preciso escrever assim. Te mostrie um exemplo.

 

De volta a rand()

 

rand() retorna um número inteiro entre 0 e RAND_MAX, um número bem grande. Você tem um livro? um manual? Um site de referência?

 

Vou aumentar o exemplo que te mostrei antes

 

Saida
 

Tamanhos: A: 8 B: 11
Colocando -998 e -999 no final de A e B
Ultimos elementos de A e B: -998 e -999...

RAND_MAX = 32767
nO vetor tem 6 elementos: [ 41 18467 6334 26500 19169 15724  ]

 

O exemplo alterado

 

#include <iostream>
#include <vector>

using namespace std;

int main(void)
{
	int tam = 8;
	vector<int>A(tam);
	vector<int>B(tam + 3);
	cout << "Tamanhos: A: " << A.size()
		<< " B: " << B.size() << endl;
	cout << "Colocando -998 e -999 no final de A e B\n";
	A[A.size() - 1] = -998;
	B[B.size() - 1] = -999;
	cout << "Ultimos elementos de A e B: " <<
		A[A.size() - 1] << " e " <<
		B[B.size() - 1] << "...\n";

	int a[6]; // sao 6 int mas nao tem o tamanho
	tam = sizeof(a) / sizeof(a[0]);
	cout << "\nRAND_MAX = " << RAND_MAX << endl;
	cout << "nO vetor tem " << tam << " elementos: [ ";
	for (int i = 0; i < tam; i += 1)
	{
		a[i] = rand();
		cout << a[i] << " ";
	};
	cout << " ]\n";
	return 0;
}

 

É só isso.

 

Se vai usar tamanho dinâmico precisa alocar a memória de acordo

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

2 horas atrás, V!OLADOR disse:

Basicamente, "rand" significa "random" em inglês e retorna valores aleatórios a cada chamada. Ou seja, em A[0] = rand() e A[1] = rand(), muito provavelmente, A[0] != A[1].

 

Mas algoritmos que geram números (pseudo) aleatórios precisam de um inicializador, em inglês usa-se o termo "seed" (semente).

 

Essa é a função de srand, fornecer um inicializador, um número, do qual o algoritmo poderá criar outros números aleatórios. E sempre deve ser chamado, ou seja inicializado, antes do uso do algoritmo.

 

Você é livre pra escolher um inicializador. O tempo, de time(NULL), é um parâmetro que funciona bem em casos simples.

 

Caso, use por exemplo srand(3), então, com um inicializador constante, os mesmos números aleatórios serão criados a cada execução do programa. Dependendo da implementação, claro.

 

Por isso chama-se gerador de números pseudo aleatórios.

 

 

bom, refiz mais uma vez, só que agora eu conseui resolver o problema do rand que você me explicou, muito obrigado, agr ficou assim:

#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

int maiorval(int A[], int B[], int tam){
	
	int i;
	int max_a = -99999;
	int max_b = -99999;
	
	for(i=0;i<tam;i++){
		if(A[i] > max_a)
			max_a = A[i];
		if(A[i] > max_b)
			max_b = B[i];
	}
	
	if(max_a>max_b)
		return max_a;
	else 
		return max_b;
}

#define tam 5

int main(){
	
	int i;
	int maior, maiorvalor;
	int A[tam];
	int B[tam];
	
	srand(time(NULL));
	
	//a seguir a geração de números aleatórios
	for(i=0;i<tam;i++){
		A[i] = rand() % 10;
		B[i] = rand() % 10;
	}
	cout << "veotres" << endl;	
	//print dos vetores
	for(i=0;i<tam;i++){
		cout << A[i] << endl;
		cout << B[i] << endl;
	}
	
	maior = maiorval(A, B, tam);
	
	cout << "Maior valor e " << maior << endl;
	
	return 0;
}

a questão é, eu não sei se o funcionamento do program está correto, já que o @arfneto mostrou outra possibilidade de fazer, não tenho certeza se é assim mesmo...

Link para o comentário
Compartilhar em outros sites

Sempre às ordens, patrão. Parece correto. Basta compilar e executar. Você escreve os valores de A e B na tela e checa se o resultado de maiorval é consistente.

 

PS: Apenas escreva os valores de A e B na tela de maneira que possa distingui-los, 🤣, tipo:

 

std::cout << "A[" << i << "] = " << A[i] << std::endl;

 

Link para o comentário
Compartilhar em outros sites

3 horas atrás, arfneto disse:

Não pode escrever assim, @Flávio Pedroza


tam nesse caso deve ser uma constante que possa ser avaliada em tempo de compilação, não um valor a ser lido quando o programa está executando.

 

image.png.26fd849beecb99a0e7c21851d911c013.png

 

 

Em alguns compiladores isso é permitido - os que seguem o padrão c99 (não é o caso do visual studio).

Link para o comentário
Compartilhar em outros sites

2 horas atrás, Clancy Gilroy disse:

a questão é, eu não sei se o funcionamento do program está correto, já que o @arfneto mostrou outra possibilidade de fazer, não tenho certeza se é assim mesmo

 

É raro você poder apontar para uma solução melhor. Às vezes "certa" já é controverso.

 

Umas coisas eu posso dizer com certeza sobre a sua solução:
 

  • "vetores" está escrito errado ;) 
    cout << "veotres" << endl;
  • sobre essa construção
	for(i=0;i<tam;i++){
		if(A[i] > max_a)
			max_a = A[i];
		if(A[i] > max_b)
			max_b = B[i];
	}
	
	if(max_a>max_b)
		return max_a;
	else 
		return max_b;

 

  • Não é esperto calcular de fato o máximo valor em cada vetor e ter variáveis separadas e tal. A resposta da função é o maior valor no geral. Não há razão para esses if e esses cálculos todos.
     
  • Desde 1989 é possível declarar variáveis no comando for. E isso foi uma pressão da comunidade, porque variáveis soltas pelo programa e usadas apenas para controle de loops eram e são uma bomba relógio. Em especial umas chamadas "i", "aux" e por aí vai. :) Elas continuam vivas depois do loop e podem ser reaproveitadas por engano, gerando bugs infernais. É um mini-caso das variáveis globais, proibidas em quase todo círculo sério, seja empresa ou academia
    Compare com essa função, que dá o mesmo resultado,claro

     
    int maiorval(int A[], int B[], int tam)
    {
    	int max = INT_MIN; // o menor possivel int
    	for (int i = 0; i < tam; i++)
    	{
    		if (A[i] > max)	max = A[i];
    		if (B[i] > max)	max = B[i];
    	};	//for()
    	return max;
    };

    E entenda que é mais fácil de ler e muito mais rápida de executar.
     
  • incluir e compilar time.h toda vez, apenas para gerar nova semente para o gerador de números aleatórios chamando srand() com a hora é um certo exagero nesse tipo de programa. Não vai levar a nada.

    Isso no geral é importante no caso absolutamente contrátio: gerar uma semente constante EXATAMENTE para reproduzir a série de números gerados. A razão é simples mas muitas vezes desprezada: quando você está testando um programa é muito bom poder reproduzir as sequências aleatórias durante os testes, para por exemplo poder comparar as versões de algoritmos distintos. E se usar sementes distintas, por exemplo chamando srand() com a hora, já era. Nunca vai poder reproduzir um teste e comparar os tempos.

    Pense bem: se fosse gerar aqui 3 vetores de 5000 int entre 1 e 30.000 para testar 4 rotinas de lista ligada distintas, não ia preferir que cada rotina usasse exatamente os memsos 15.000 números "aleatórios"? Assim é na prática.
     
2 horas atrás, Flávio Pedroza disse:

Em alguns compiladores isso é permitido - os que seguem o padrão c99 (não é o caso do visual studio).

 

Sim. Mas em geral não é boa ideia, em especial para quem está aprendendo: Isso mascara o fato de se estar alocando algo e onde estar alocando. E não por acaso se vê mais isso em programas de estudantes. 

 

Isso economiza um tempo dos instrutores em ensinar a mecânica de alocação, stack, heap. E não cria nenhum benefício real, exceto esse para os instrutores,  até onde eu vejo. E deixa esse aprendizado para depois, como quando o cara for tentar emprego em um lugar onde isso não é permitido. Ou for fazer um programa de pesquisa na pós-graduação e descobrir que o orientador não pode nem ouvir falar nisso. Em geral na academia, como em programas de pesquisa, não se vê isso.

 

Como aqui é um forum frequentado em especial por estudantes e iniciantes, vou lembrar que Visual Studio não é um compilador, assim como Code::Blocks, Dev C++, Visual Studio Code e Eclipse não são. O compilador da Microsoft é um tal CL, e os outros IDE podem usar qualquer compilador, desde que configure de acordo, seja o gcc, o CLang outros compiladores como os da Intel, e o próprio CL. Apenas o Visual Studio até onde eu sei é vinculado a um certo compilador no caso de C ou C++.

 

E um IDE é totalmente opcional. Em projetos muito grandes a geração de código --- builds --- é em geral automatizada e se usam outras ferramentas para gerar código, como CMake (que a própria Microsoft usa) e Make. 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

1 hora atrás, arfneto disse:

Sim. Mas em geral não é boa ideia, em especial para quem está aprendendo: Isso mascara o fato de se estar alocando algo e onde estar alocando. E não por acaso se vê mais isso em programas de estudantes. 

De fato não é recomendável, mas só quis clarificar VLA (Variable Length Arrays) são sim possíveis e suportado por quase todos os compiladores.

 

 

 

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!