Ir ao conteúdo
  • Cadastre-se

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


Posts recomendados

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

 

Link para o comentário
Compartilhar em outros 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. 

>.<

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros 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;
}

 

  • Curtir 1
  • Confuso 1
Link para o comentário
Compartilhar em outros 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].

Link para o comentário
Compartilhar em outros 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.

 

Link para o comentário
Compartilhar em outros 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;
}

 

Link para o comentário
Compartilhar em outros 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); 

 

Link para o comentário
Compartilhar em outros 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.

Link para o comentário
Compartilhar em outros 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.

Link para o comentário
Compartilhar em outros 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?

Link para o comentário
Compartilhar em outros 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

 

 

  • Curtir 1
  • Haha 1
Link para o comentário
Compartilhar em outros 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;
}

 

Link para o comentário
Compartilhar em outros 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. 

 

 

 

Link para o comentário
Compartilhar em outros 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. :D 

 

Isso foi engraçado! Muito bem.

 

 

  • Haha 1
Link para o comentário
Compartilhar em outros 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++ :D 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$  >

 

Link para o comentário
Compartilhar em outros 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?

Link para o comentário
Compartilhar em outros 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 :D 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?

 

 

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

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!