Ir ao conteúdo

C++ Ler tamanho da entrada para criar vetores


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

Posts recomendados

Postado

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;
}

 

  • Solução
Postado

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
Postado
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
Postado
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.

Postado

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

Postado

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.

 

 

Postado
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

 

Postado
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?

Postado

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
Postado
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
Postado
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...

Postado

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;

 

Postado
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).

Postado
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
Postado
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

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!