Jump to content

# C++ Produto Escalar e multiplicação de vetor por escalar c++

## Recommended Posts

Boa noite galera,

Sou iniciante em programação em C++, como eu consigo multiplicar dois vetores e imprimir o somatório de todos eles? Tentei fazer o código mas nao desenvolvi...

Ex de entrada:

2 3

1 2 3

4 5 6

Saída: 32 ==== 1*4 + 2*5 + 3*6

#include <iostream>
using namespace std;
int main() {
int a, n, b = 0;
cin>>a>>n;

int k[n];
int l[n];
int m[n];

for(int i = 0; i<n; i++){
cin>>k[i];
}
for(int i = 0; i<n; i++){
cin>>l[i];
}
for(int i = 0; i<n; i++){
if(a == 1){
m[i] = k[i] + l[i];
cout<<m[i]<<" ";
}
if(a == 2){
m[i] = k[i] * l[i];
cout<<m[i]<<" ";
} 

##### Share on other sites

Você leu a definição Do produto?

A saída, mais simples, acontece em duas fases:

Determine o produto a partir da definição, imprime seu valor,

após, imprime as operações sem calcular só mostra.

1 hora atrás, Artivis Sob disse:

Saída:

32 ==== 1*4 + 2*5 + 3*6

Você tem os saberes necessário, a lógica é a mesma que usa com lápis e papel... A única diferença é que o resultado vem primeiro, então não existe fórmula: é um loop para calcular e outro em seguida para mostrar as operações.

>.<

• 1
##### Share on other sites

@Artivis Sob E se a entrada for 3 e 2 ou qualquer outro? Tente usar uma representação de matriz NxM onde N = linha e M = coluna. Para a entrada dos valores use dois loops (um dentro do outro). No cálculo também, mas inverta os índices e deixe o loop externo como das colunas e o interno das linhas assim,

int soma = 0;
...
for(int i = 0; i < m; i += 1){
int produto = 1;
for(int j = 0; j < n; j += 1){
produto *= matriz[j][i];
}
soma += produto;
}

• 1
• 1
##### Share on other sites

@Augusto CesarC Com o enunciado é até mais simples, só precisa de um loop para calcular.

Na primeira operação só tem que mostrar a soma dos vetores,

cout << A[i] + B[i] << " ";

Na segunda acumule a soma do produto: soma += A[i] * B[i]. E na outra mostre a multiplicação, p.ex: numero * A[i].

##### Share on other sites

@Midori No caso do a == 3, o enunciado pede somente 1 entrada, só que como eu coloco fora do for? porque quando eu realizo numero * A[i] ele continua recebendo valores

##### Share on other sites

@Augusto CesarC Antes do loop teste a opção escolhida e se for 3 apenas informe um número, p.ex,

vector<float> A;
vector<float> B;
..
cin >> operacao >> tamanho;
A = Vetor(tamanho);

if(operacao == 3){
cin >> numero;
}else{
B = Vetor(tamanho);
}
for(int i = 0; i < tamanho; i += 1){
...

Vetor() é uma função vector que pode ser usada para acrescentar os números e retornar o vetor.

##### Share on other sites

@Augusto CesarC Existe duas condições para 3 operações:

LER 2 vetor (v1, v2) para 1-Soma de Vetores OU 2- Produto Escalar.

LER 1 vetor (v1),  após leitura do vetor (v1), ler um número para 3-Produto de Vetor por Escalar

*Não é novidade.é isso que tem o quadro no enunciado.

Condicional: IF ou SWITCH

A vantagem em switch é porque as operações são representadas por valores sucessivos e podemos imaginar que ela salta de uma operação para outra sem a necessidade de avaliar as condições anteriores como se imagina acontecer em estruturas IF onde uma condição é avaliada após a outra.

Minimamente...

switch( a ){
case 1:
case 2: for(n); for(n); break;
case 3: for(n);  scanf; break;
default:
}

Se em IF:

if( (1 == a)||(2 == a) ){
for(n);
for(n);
} else {
for(n); scanf;
}

##### Share on other sites

Para calcular as operações eu usaria só um loop com as condições dentro,

for(int i = 0; i < n; i += 1){
if(operacao == 1){
...
}
if(operacao == 3){
...
}else{
...
}
}

Em vez do else também podia ser outro if para a operação 2.

##### Share on other sites

Pontuarei switch também nos comandos de cálculo, porém as coisas ficaram divertidas.

Minimamente...

nsaida= n;
for( n ){
switch( a ){
case 1: vr(n) = (v1 + v2); break
case 2: a= 4;
nsaida= 1;
case 4: vr(0)+= (v1 * v2); break;
case 3: vr(n) = (es * v1); break;
default: break;
}       }
printf vr(0);
for( 1...nsaida ) printf ' ' vr(nsaida); 

##### Share on other sites

Em 06/05/2021 às 09:03, Midori disse:

Com o enunciado é até mais simples, só precisa de um loop para calcular.

@Midori o enunciado é ainda mais simples só precisa de um loop de cálculo na terceira opção, porque a constante vem depois do vetor. Nos dois primeiros não é preciso nenhum loop e as operações devem ser executadas durante a leitura do segundo vetor.

##### Share on other sites

@arfneto Com esse post me deu uma ideia e dá para deixar ainda mais simples e não usar nenhum loop separado para isso. Só vai precisar do loop da entrada dos valores e um vetor.

##### Share on other sites

10 minutos atrás, Midori disse:

@arfneto Com esse post me deu uma ideia e dá para deixar ainda mais simples e não usar nenhum loop separado para isso. Só vai precisar do loop da entrada dos valores e um vetor.

Sim. Apenas no caso da multiplicação por escalar precisa de outro loop porque o valor vem DEPOIS e não antes. Se mudar a entrada para passar a constante na primeira linha aí estarão os 3 casos cobertos...

Se passar

3 3 2
1 2 3

Ao invés de

3 3
1 2 3
2

como está no exemplo.

##### Share on other sites

@arfneto Se fizer um loop para a entrada de n * 2 não precisa de outro nem para a operação 3. E a entrada pode ficar como no enunciado.

##### Share on other sites

2 minutos atrás, Midori disse:

@arfneto Se fizer um loop para a entrada de n * 2 não precisa de outro nem para a operação 3. E a entrada pode ficar como no enunciado.

atente para o que eu expliquei: não precisa de nenhum loop nas dois primeiros casos. NENHUM. E apenas um no terceiro e que poderia ser abolido se mudasse a entrada. Quer que eu acrescente um exemplo?

##### Share on other sites

7 minutos atrás, arfneto disse:

Quer que eu acrescente um exemplo?

Sim, como ficaria?

##### Share on other sites

Recortando e colando de outro programa que eu postei hoje, porque não vou escrever de novo...

Assim vai ficar um pouco mais comprido.

Mas eis o que importa:

• vai ler uma operação e um valor incialmente e depois pode ou não ler outro vetor
• o arquivo de entrada está fixo como "entrada.txt"

Para o caso de soma ou escalar vai ler outro vetor

    if (operacao != 3)
{   // soma ou produto escalar
const char* mascara = "%d"; // para scanf()
for (unsigned i = 0; i < limite; i += 1)
{
// va ler o mesmo numero de elementos
res = fscanf(E, "%d", &outro[i]);
if (res != 1)
{
fclose(E);
return -7; // deu m.
}
// leu o elemento
if (operacao == 1) // soma
serie[i] = serie[i] + outro[i];
else
produto_escalar += serie[i] * outro[i];
};  // for()
mostra_vetor(limite, outro, "Segundo vetor:");
if (operacao == 1)
mostra_vetor(limite, serie, "Vetor soma:");
else
printf("\nProduto Escalar = %d\n", produto_escalar);
}

E claro que tem que ler todos os valores. MAs ao ler já pode calcula a parcela do produto escalar ou somar o novo valor ano vetor original.

NÃO precisa de outro loop. Apenas do óbvio e inevitável loop de leitura.

Só isso:

            if (operacao == 1) // soma
serie[i] = serie[i] + outro[i];
else
produto_escalar += serie[i] * outro[i];

Mas se a opção for 3 precisa de outro loop. Claro que o cara podia ter passado o fator junto na primeira linha e aí não precisaria de outro loop. Era isso o que eu tentava explicar.

Se a operação for 3 então

    else
{
int constante = 0;
int res = fscanf(E, mascara, &constante);
if (res != 1) return -6; // nao veio a constante
printf("Fator escalar para multiplicar o vetor: %d\n",
constante);
for (unsigned i = 0; i < limite; i += 1)
serie[i] = serie[i] * constante;
mostra_vetor(limite, serie, "Vetor resultante");

};

precisa varrer o vetor de novo pra multiplicar porque quando leu o vetor original não sabia o valor da constante...

ok?

Eis  um exemplo completo mas acho que não precisa mais...

Spoiler


#define LIMITE_ 30
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

int         le_serie(unsigned, int*, FILE*);
int 	    mostra_vetor(int, int*, const char*);

int main(void)
{
const char* oper[] =
{
"nada",
"Soma de dois vetores",
"Produto escalar",
"Multiplicacao de vetor por escalar"
};

int         serie[LIMITE_]; // pra guardar o vetor
int         outro[LIMITE_]; // pode ter um segundo
int         operacao = 0; // 1 2 3
unsigned    limite = 0;
const char* nome_arquivo = "entrada.txt"; // entrada padrão

FILE* E = fopen(nome_arquivo, "r");
if (E == 0) return -1; // nao abriu
const char* mascara = "%d %d"; // para scanf()
int res = fscanf(E, mascara, &operacao, &limite );
if (res != 2) return -2; // bobagem: nao leu os valores
// por sanidade
if (limite > LIMITE_) limite = LIMITE_;
if (operacao < 1 || operacao > 3) return -3;
printf("Entrada: \"%s\" Tamanho do vetor: %d Operacao: \"%s\"\n",
nome_arquivo, limite, oper[operacao]);
res = le_serie(limite, serie, E);
if (res != limite)
{
// nao conseguiu ler os caras todos
fclose(E);
return -4;
}
mostra_vetor(limite, serie, "Vetor original");

// lido o vetor original, roda a operacao
int produto_escalar = 0; // pode nao ser usado
if (operacao != 3)
{   // soma ou produto escalar
const char* mascara = "%d"; // para scanf()
for (unsigned i = 0; i < limite; i += 1)
{
// va ler o mesmo numero de elementos
res = fscanf(E, "%d", &outro[i]);
if (res != 1)
{
fclose(E);
return -7; // deu m.
}
// leu o elemento
if (operacao == 1) // soma
serie[i] = serie[i] + outro[i];
else
produto_escalar += serie[i] * outro[i];
};  // for()
mostra_vetor(limite, outro, "Segundo vetor:");
if (operacao == 1)
mostra_vetor(limite, serie, "Vetor soma:");
else
printf("\nProduto Escalar = %d\n", produto_escalar);
}
else
{
int constante = 0;
int res = fscanf(E, mascara, &constante);
if (res != 1) return -6; // nao veio a constante
printf("Fator escalar para multiplicar o vetor: %d\n",
constante);
for (unsigned i = 0; i < limite; i += 1)
serie[i] = serie[i] * constante;
mostra_vetor(limite, serie, "Vetor resultante");

};
fclose(E);
return 0;
}

int 	mostra_vetor(int N, int* V, const char* msg)
{
if (msg != NULL) printf("%s\n", msg);
printf("Vetor[%d]:\n[ ", N);
for (int i = 0; i < N - 1; i += 1) printf("%2d,  ", V[i]);
printf("%2d ]\n\n", V[N - 1]);
return 0;
};

// le a serie 'serie' a partir do arquivo com o 'limite' de valores
int         le_serie(unsigned limite, int* serie, FILE* E)
{
if (E == NULL) return -1; // nao abriu
const char* mascara = "%d"; // para scanf()
unsigned    lidas = 0;
int         res = res = fscanf(E, mascara, &serie[lidas]);
if (res != 1) return -2; // bobagem: nao veio o primeiro numero
lidas = 1;
while (!feof(E))
{
res = fscanf(E, mascara, &serie[lidas]);
if (res != 1) break; // acabou?
lidas += 1;
if (lidas >= limite) break; // nao cabe mais
};  // while()
return lidas;
}

// fim de main

• 1
• 1
##### Share on other sites

51 minutos atrás, arfneto disse:

NÃO precisa de outro loop. Apenas do óbvio e inevitável loop de leitura.

Quando me refiro a usar um loop é esse com a leitura assim,

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

int main(){
vector<float> A;
float soma = 0;
int operacao;
int n;

cin >> operacao >> n;

for(int i = 0, j = 0; i < (n * 2); i += 1){
float numero;
if(operacao == 3){
if(i <= n){
cin >> numero;
}
}else{
cin >> numero;
}
if(i < n){
A.push_back(numero);
}else{
if(operacao == 1){
cout << numero + A[j] << " ";
}
if(operacao == 3){
cout << numero * A[j] << " ";
}
else{
soma += numero * A[j];
}
j += 1;
}
}
if(operacao == 2){
cout << soma << endl;
}
return 0;
}

##### Share on other sites

Não entendi porque mudou a linguagem. E não entendi o programa. Talvez você deva postar um programa completo.

Mudar a linguagem não vai mudar o enunciado. Você está lendo a operação, mas aí tem que ler o vetor original para DEPOIS ler a constante.

for(int i = 0, j = 0; i < (n * 2); i += 1){
float numero;
if(operacao == 3){
if(i <= n){
cin >> numero;
}
}else{
cin >> numero;
}

Sinteticamente:

• precisa de um loop pra ler o vetor original.
• Se vai usar a multiplicação  por escalar precisa de outro a menos que mude a ordem da entrada
• Se vai usar produto escalar ou soma precisa de um loop para ler o outro vetor a menos que se contente em ler elementos alternados de um e outro.

Então precisa de dois loops.

O programa que eu te mostrei vai produzir as saídas esperadas para os 3 casos.

##### Share on other sites

@arfneto Não mudei a linguagem, o tópico é sobre C++ e o programa está completo. Não precisa de outro loop.

##### Share on other sites

7 minutos atrás, Midori disse:

@arfneto Não mudei a linguagem, o tópico é sobre C++ e o programa está completo. Não precisa de outro loop. Entendi. Eu só vi trechos de código e não achei que fosse um programa em C++. my bad

Mas dobrar o loop para ler os dois vetores e fazer de conta que os dois vetores são um só não é muito diferente de dois loop se tanto. Isso foi engraçado! Muito bem.

• 1
##### Share on other sites

Em 07/05/2021 às 16:55, Midori disse:

Não mudei a linguagem, o tópico é sobre C++ e o programa está completo. Não precisa de outro loop

Entendo.

Está certo de que funciona para a operação 3? Como seria a entrada nesse caso? Parece estar errado.

Vou deixar um outro exemplo, desta vez em C++ com um loop só mas usando uma máquina de estados. pode ser interessante ter algo assim no forum.

#define LIMITE_ 30
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
using iit = istream_iterator<int>;

int main(void)
{
iit         inicio{ cin };
iit         FIM{};
unsigned    operacao;
unsigned    limite;
int         produto_escalar = 0;
int         k = 0;
vector<int> V{};
unsigned    vIx = 0; // indice para o vetor
auto        estado = 0; // para a maquina de estados

if (inicio == FIM) return -1; // vazio
int     valor = 0;
while (true)
{
switch (estado)
{
case 0: // le operacao
operacao = *inicio++;
if (inicio == FIM) return -10;
estado = 1;
break;

case 1: // le tamanho
limite = *inicio++;
if (limite > LIMITE_) limite = LIMITE_;
if (inicio == FIM) return -11;
estado = 2;
break;

case 2: // lendo vetor inicial
valor = *inicio++;
if (inicio == FIM) return -12;
V.push_back(valor);
if (V.size() >= limite)
{
if (operacao == 3)
estado = 4;
else
{
vIx = 0;
estado = 3;
}
}
break;

case 3: // lendo vetor adicional
valor = *inicio++;
if (operacao == 1) // soma
V[vIx++] += valor; // soma na posicao
else
produto_escalar += valor * V[vIx++];

if (vIx >= limite)
{   // processou todos
if (operacao == 1)
{   // vai mostrar o resultado
vIx = 0;
estado = 6;
break;
}
cout << produto_escalar << "\n";
return 0;
}
else
{
if (inicio == FIM) return -13;
}
break;

case 4: // inicia multiplicacao por escalar k
k = *inicio;
estado = 5;
break;

case 5: // multiplica todos por K
V[vIx++] *= k; // * K
if (vIx >= limite)
{
vIx = 0;
estado = 6;
}
break;

case 6: // mostra o vetor depois da operacao
cout << V[vIx++] << " ";
if (vIx >= limite)
{
return 0;
}
break;

default: // sei nao
cout << estado << ": erro! ";
return -500;
break;
};  // switch()
};  // while()
return -1;
};

E uma outra versão mais verbosa que ajuda a ver os testes:

Spoiler

#define LIMITE_ 30
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
using iit = istream_iterator<int>;

int main(void)
{
const char* oper[] =
{   "nada", "Soma de dois vetores",
"Produto escalar", "Multiplicacao de vetor por escalar" };
iit        inicio { cin };
iit        FIM {};
unsigned    operacao;
unsigned    limite;
int         produto_escalar = 0;
int         k = 0;
vector<int> V{};
unsigned    vIx = 0; // indice para o vetor
auto        estado = 0; // para a maquina de estados

if (inicio == FIM) return -1; // vazio
int     valor = 0;
while (estado < 9)
{
switch (estado)
{
case 0: // le operacao
operacao = *inicio++;
if (inicio == FIM) return -10;
cout << "Operacao: " << oper[operacao] << "\n";
estado = 1;
break;

case 1: // le tamanho
limite = *inicio++;
if (limite > LIMITE_) limite = LIMITE_;
if (inicio == FIM) return -11;
cout << "Tamanho: " << limite << "\n\n";
cout << "Vetor  Original: [ ";
estado = 2;
break;

case 2: // lendo vetor inicial
valor = *inicio++;
if (inicio == FIM) return -12;
cout << valor << " ";
V.push_back(valor);
if (V.size() >= limite)
{
cout << "]\n";
if (operacao == 3)
estado = 4;
else
{
vIx = 0;
cout << "Vetor Adicional: [ ";
estado = 3;
}
}
break;

case 3: // lendo vetor adicional
valor = *inicio++;
cout << valor << " ";
if (operacao == 1) // soma
V[vIx++] += valor; // soma na posicao
else
produto_escalar += valor * V[vIx++];

if (vIx >= limite)
{   // processou todos
if (operacao == 1)
{   // vai mostrar o resultado
cout << "]\nVetor   Soma:    [ ";
vIx = 0;
estado = 6;
break;
}
cout << "]\nProduto Escalar = " << produto_escalar << "\n";
return 0;
}
else
{
if (inicio == FIM) return -13;
}
break;

case 4: // inicia multiplicacao por escalar k
k = *inicio;
cout << "Fator " << k << "\n";
estado = 5;
break;

case 5: // multiplica todos por K
V[vIx++] *= k; // * K
if (vIx >= limite)
{   cout << "Vetor Resultante: [ ";
vIx = 0;
estado = 6;
}
break;

case 6: // mostra o vetor depois da operacao
cout << V[vIx++] << " ";
if (vIx >= limite)
{   cout << "]\n";
return 0;
}
break;

default: // sei nao
cout << estado << ": erro! ";
return -500;
break;
};  // switch()
};  // while()
return -1;
};

Eis uns resultados

Clube$> echo " >> 1 3 >> 1 2 3 >> 4 5 6 " | ./tst Operacao: Soma de dois vetores Tamanho : 3 Vetor Original : [1 2 3] Vetor Adicional : [4 5 6] Vetor Soma : [5 7 9] Clube$  >

Clube$> echo " >> 2 3 >> 1 2 3 >> 4 5 6 " | ./tst Operacao: Produto escalar Tamanho : 3 Vetor Original : [1 2 3] Vetor Adicional : [4 5 6] Produto Escalar = 32 Clube$  >

Clube$> echo " >> 3 3 >> 1 2 3 >> 2" | ./tst Operacao: Multiplicacao de vetor por escalar Tamanho : 3 Vetor Original : [1 2 3] Fator 2 Vetor Resultante : [2 4 6] Clube$  >

Clube$> echo "3 6 1 2 3 4 5 6 3" | . / tst Operacao : Multiplicacao de vetor por escalar Tamanho : 6 Vetor Original : [1 2 3 4 5 6] Fator 3 Vetor Resultante : [3 6 9 12 15 18] Clube$  >

Clube$> echo "3 6 1 2 3 4 5 6 3" | . / tst Operacao : Multiplicacao de vetor por escalar Tamanho : 6 Vetor Original : [1 2 3 4 5 6] Fator 3 Vetor Resultante : [3 6 9 12 15 18] Clube$  >

##### Share on other sites

58 minutos atrás, arfneto disse:

Como seria a entrada nesse caso? Parece estar errado.

A entrada é como no enunciado e o funcionamento é simples, como o loop tem o dobro de n dá para carregar o primeiro vetor e depois (testando as operações) calcular as próximas entradas com o que foi armazenado. O que parece errado?

##### Share on other sites

2 horas atrás, Midori disse:

A entrada é como no enunciado e o funcionamento é simples, como o loop tem o dobro de n dá para carregar o primeiro vetor e depois (testando as operações) calcular as próximas entradas com o que foi armazenado. O que parece errado?

Não sou eu que vou corrigir isso, não trabalha para mim tampouco, mas esse trecho é problemático e seria flagrado em qualquer revisão de código séria:

    for (int i = 0, j = 0; i < (n * 2); i += 1) {
float numero;
if (operacao == 3) {
if (i <= n) {
cin >> numero;
}
}
else {
cin >> numero;
}
if (i < n) {
A.push_back(numero);
}
else {
if (operacao == 1) {
cout << numero + A[j] << " ";
}
if (operacao == 3) {
cout << numero * A[j] << " ";
}
else {
soma += numero * A[j];
}
j += 1;
}
};  // for()

• Na prática, para demonstrar sua tese de usar um único loop criou outra variável --- j --- dentro do loop e roda UM for com DOIS índices só que um índice roda depois do outro já que  o índice j é para o segundo vetor e o que está escrito aí é:
• lê n valores
• se a opção envolver um segundo vetor le mais n valores, o segundo vetor
• se a opção for 3 --- multiplicação do vetor por escalar --- então só lê mais um número, o óbvio fator da multiplicação

Isso:

        if (operacao == 3) {
if (i <= n) {
cin >> numero;
}
}
else {
cin >> numero;
}

quer dizer isso:

        if ( (operacao != 3) || ( operacao == 3 && i<=n ) ) cin >> numero;

já que se para i de 0 a n-1 está lendo o obrigatório primeiro vetor. E para a multiplicação por escalar vai ler o n-ésimo valor que vai ser a constante.

Entenda que isso envolve uma ineficiência potencial: se forem 2 milhões de elementos o loop vai testar a toa 999.999 vezes a mesma coisa. É mais eficiente fazer como no exemplo em C que eu postei: lê o vetor. Se existir o segundo vetor lê os valores, senão lê a constante. É mais legível também.

E se existir um segundo vetor já vai preparando o produto escalar ou somando os vetores, de modo que ao final do loop tem a resposta pronta. É o mínimo de operações.

Esse teste:

        if (i < n) {
A.push_back(numero);
}
else {
if (operacao == 1) {
cout << numero + A[j] << " ";
}
if (operacao == 3) {
cout << numero * A[j] << " ";
}
else {
soma += numero * A[j];
}
j += 1;
}

Não poderia estar dentro do loop. É mais um caso de forma x função: para justificar a tese de um único loop o loop roda (n*2) vezes, no entanto de 0 a n-1 faz uma coisa --- push_back() --- e na outra metade, para i de n a 2n-1 opera com os vetores. Só que testa SEMPRE se i<n.

E isso por si só  também está errado:

            if (operacao == 1) {
cout << numero + A[j] << " ";
}
if (operacao == 3) {
cout << numero * A[j] << " ";
}
else {
soma += numero * A[j];
}
j += 1;

Se a operação for 1 não poderá ser 3 já que ela não é alterada dentro do if (em nenhum lugar na verdade, já que o programa executa uma única operação.

Assim sendo não tem sentido testar de novo operacao se for 1... Pode apostar que não vai ser 3.

Podia ser apenas

            if (operacao == 1) // soma
cout << numero + A[j] << " ";
else
if (operacao == 3) // mult. por escalar
cout << numero * A[j] << " ";
else    // produto escalar
soma += numero * A[j];
j += 1; // o loop dentro do loop para dizer que so tem um for: incrementa i E j
• por alguma razão o vetor é de float o que não parece ser o caso no enunciado a julgar pelos valores fornecidos no exemplo.

• Um outro problema é a declaração

        float numero;

isso porque nesse trecho

    for (int i = 0, j = 0; i < (n * 2); i += 1) {
float numero;
if (operacao == 3) {
if (i <= n) {
cin >> numero;
}
}
else {
cin >> numero;
}
if (i < n) {
A.push_back(numero);
}

não tem como o compilador saber se no momento do push_back() numero vai estar inicializado. Isso é um comportamento perigoso e sempre é flagrado por revisores de código (pessoas) ou analisadores sintáticos ou mesmo os compiladores...

Exemplo

*********************************************************************
ch>  cl /c /Wall /D__STDC_WANT_SECURE_LIB__ /EHsc midori.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29914 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

midori.cpp
midori.cpp(27): warning C4365: 'argument': conversion from 'int' to \
'const unsigned int', signed/unsigned mismatch
midori.cpp(30): warning C4365: 'argument': conversion from 'int' to \
'const unsigned int', signed/unsigned mismatch
midori.cpp(33): warning C4365: 'argument': conversion from 'int' to \
'const unsigned int', signed/unsigned mismatch
C:\Users\toninho\source\repos\ConsoleApplication43\midori\midori.cpp(27) :\
warning C4701: potentially uninitialized local variable 'numero' used
ch>
ch>
ch> 

E aí está o warning C4701

Note que em muitas empresas e escolas warnings são tratados como erros usando /Wx na compilação.

Um outro erro:

Se esse programa passar por um algoritmo de correção automática, como desses sites de programming contest tipo URI que às vezes aparece aqui, veja o que acontece no final:

echo "
2 3
1 2 3
4 5 6
" | ./tst | od -xc

Vai rodar o exemplo do enunciado para a operação 2, produto escalar:

toninho@DSK-2009:~/projects/mapa$echo " 2 3 1 2 3 4 5 6 " | ./tst | od -xc 0000000 3233 000a 3 2 \n 0000003 E está certo: 32 é o produto escalar. Mas para a operação 1: toninho@DSK-2009:~/projects/mapa$ echo "

1 3
1 2 3
4 5 6
" | ./tst | od -xc
0000000    2035    2037    2039
5       7       9
0000006

A soma vai mesmo dar o vetor 5 7 9. Mas lá se foi o '\n" ao final. Mesmo caso para a operação 3:

echo "
3 3
1 2 3
2
" | ./tst | od -xc

que vai mostrar

toninho@DSK-2009:~/projects/mapa$toninho@DSK-2009:~/projects/mapa$ echo "
3 3
1 2 3
2
" | ./tst | od -xc
0000000    2032    2034    2036
2       4       6
0000006
toninho@DSK-2009:~/projects/mapa\$ 

Ou seja

    if (operacao == 2) cout << soma << endl;

Devia ser claro

    if (operacao == 2)
cout << soma << endl;
else
cout "\n";

Eis seu programa, ligeiramente alterado, sem esses problemas:

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

int main() {
vector<float> A;
int soma = 0;
int operacao;
int n;

cin >> operacao >> n;
for (int i = 0, j = 0; i < (n * 2); i += 1) {
float numero = 0;
if ( (operacao != 3) || ( operacao == 3 && i<=n ) ) cin >> numero;
if (i < n)
A.push_back(numero);
else
{
if (operacao == 1) // soma
cout << numero + A[j] << " ";
else
if (operacao == 3) // mult. por escalar
cout << numero * A[j] << " ";
else    // produto escalar
soma += numero * A[j];
j += 1;
}
};  // for()
if (operacao == 2)
cout << soma << endl;
else
cout << "\n";
return 0;
}

No entanto persiste o problema de lógica: cada loop tem metade dos testes a toa e não passaria em muitas revisões.

Entendeu a diferença entre usar uma FSA (maquina de estados)  e o tradicional, como está no exemplo (em C) que eu mostrei antes?

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

• ### Recently Browsing   0 members

No registered users viewing this page.

• ### Livros      • ### Cursos

GRÁTIS: Como ganhar dinheiro montando computadores Redes TCP/IP Arquitetura de redes • ### Últimos artigos

• 0
• • • • ### 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

### Mais

×

• Newsletter

• #### Cursos

• VIP
×
• Create New...