Mwater07 Ответов: 2

Как мне ... вычислить точечное произведение массива структуры


Я пытаюсь написать программы на C++, которые вычисляют точечное произведение двух заданных векторов. В векторах a и b в массив структур(row и col) будут храниться только ненулевые элементы. Каждый раз я получаю нерелевантные результаты. Правильный результат должен быть 50. Пожалуйста, совет.
Заранее спасибо.
<pre>#include <iostream>
#include <vector>
using namespace std;

const int n=10; /* vector size */
struct element {
int index; /* original index of non-zero array element */
int value ; /* integer non-zero value at index x */
};

element row[n];
element col[n];

vector<int> a={0,0,7,0,5,0,0,8,0,4,-1};
vector<int> b={0,0,0,5,6,0,0,0,0,5,-1};

void generate_row_and_col()
{
    for (int i=0; i<=n; i++)
    {
        if(a[i]!=0)
        {
            row[i].index=i;
            row[i].value=a[i];
        }
    }
    for (int j=0; j<=n; j++)
    {
        if(b[j]!=0)
        {
           col[j].index=j;
           col[j].value=b[j];
        }
    }
}
int dotproduct()
{
/* calculate the dot product of row and col output the result*/
int i=0;
int j=0;
int product=0;
while(row[i].index!=-1 && col[j].index!=-1)
{
    if(row[i].index == col[j].index)
    {
        product=product+row[i].value*col[j].value;
        i++;
        j++;
    }
    else if(row[i].index<col[j].index)
    {
        i++;
    }
    else
    {
        j++;
    }
}
return product;
}

int main()
{
    generate_row_and_col() ;
    int r;
    r=dotproduct();
    cout<<"result="<<r<<endl;
    return 0;
}


Что я уже пробовал:

Я думаю, что не могу правильно прочитать векторы в массиве структур.

Nelek

Я не понимаю, что вы пытаетесь сделать. То, что я думаю, что вы говорите, не соответствует тому, что я вижу в вашем коде.

Было бы неплохо, если бы вы отредактировали вопрос и дали немного больше объяснений. И пример" что это должно быть " матрицы / векторов на каждом шаге.

CPallini

Извините, а какова логика отказа от нулевых значений в пользу мусора?

2 Ответов

Рейтинг:
2

CPallini

Вы пытаетесь усложнить простое дело. Попробуй

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


// Please note: error handling (e.g. a.size()!=b.size()) left as exercise
int dot(const vector<int> & a, const vector <int> &b)
{
  int dp = 0;
  for (size_t n = 0; n< a.size(); ++n)
  {
    dp += a[n]*b[n];
  }
  return dp;
}


int main()
{
  vector<int> a={0,0,7,0,5,0,0,8,0,4};
  vector<int> b={0,0,0,5,6,0,0,0,0,5};
  int dp = dot(a,b);

  cout << "result = " << dp << endl;
}


Рейтинг:
14

Jochen Arndt

В вашем коде есть три ошибки.

Первые два: у вас есть фиксированный размер массива 10 для row и col но имеют доступ к 11 элементам (вне связанного доступа) и не инициализировали все элементы:

for (int i=0; i<=n; i++)
{
    // Not all row elements are initialised
    if(a[i]!=0)
    {
        // Out of bound access here when i == 10
        row[i].index=i;
        row[i].value=a[i];
    }
}
// And similar for col
for (int j=0; j<=n; j++)
{
    if(b[j]!=0)
    {
        col[j].index=j;
        col[j].value=b[j];
    }
}
Следующее-Это здесь:
while(row[i].index!=-1 && col[j].index!=-1)
где вы проверяете index член за то, что он -1. Но это никогда не будет так, потому что индекс просто работает от 0 до n (предполагая, что все элементы были инициализированы). Вы, возможно, захотите, чтобы проверить членов значение для -1 здесь.

Так что вам придется:

  • Набор n до 11
  • Скопируйте все элементы из векторов в row и col (при необходимости проверьте размер массива и перерыв после копирования -1)
  • Регистрация value член для того, чтобы быть -1 вместо index элемент (или установите оба элемента на приведенном выше шаге равными -1, если элемент вектора равен -1)


Mwater07

Спасибо. Я сделал изменения, которые вы предложили в коде, он работает нормально. Но, как вы уже сказали, во время инициализации массивов row и col в функции generate_row_and_col я инициализирую только индексы с ненулевыми элементами , остальные из них не инициализируются. Это не вызывает никаких ошибок в этой программе,но с точки зрения хорошей практики программирования эти индексы со значениями 0 не инициируются, и массивы будут выглядеть так(мусор,мусор, 7, мусор, 5, мусор, мусор...). Можем ли мы просто ограничить функцию generate_row_and_col, чтобы мы могли хранить только ненулевые индексы значений.
Спасибо

Jochen Arndt

Где вы читаете: "с точки зрения хорошей практики программирования эти индексы со значениями 0 не инициируются"?
Хорошей практикой является инициализация всех переменных.

Если массив будет позже использоваться для других целей, у вас возникнут проблемы, и вы можете не помнить, что они получены из-за того, что не инициализировали все члены.