Jump to content
  • Sign Up

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


Artivis Sob
 Share

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

 

Link to comment
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. 

>.<

 

 

  • Curtir 1
Link to comment
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;
}

 

  • Curtir 1
  • Confuso 1
Link to comment
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].

Link to comment
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.

 

Link to comment
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;
}

 

Link to comment
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.

Link to comment
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); 

 

Link to comment
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.

Link to comment
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.

Link to comment
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.

Link to comment
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?

Link to comment
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

 

 

  • Curtir 1
  • Haha 1
Link to comment
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;
}

 

Link to comment
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. 

 

 

 

Link to comment
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. :D 

 

Isso foi engraçado! Muito bem.

 

 

  • Haha 1
Link to comment
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++ :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 to comment
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?

Link to comment
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 :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 to comment
Share on other sites

Create an account or sign in to comment

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

Create an account

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

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

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

×
×
  • Create New...

Redes-Wi-Fi-capa-3d-newsletter.png

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!