泛化不同类型矩阵的函数(例如向量双端队列、向量数组,反之亦然)

问题描述 投票:0回答:1

我创建了一个适用于向量的版本,但目前我在如何使其适应其他类型的矩阵方面处于停滞状态。我不知道是否应该,以及是否可以给出该函数指向矩阵开头和结尾的指针或迭代器,但我不知道这是否适用于像 int array[] 这样的数组?

#include <iostream>
#include <cmath>
#include <vector>
#include <deque>
#include <iterator>
#include <iomanip>

template<typename T,typename T1,typename F>
std::vector<std::vector<T>> GeneralizedKroneckerProduct(std::vector<std::vector<T>>M1, std::vector<std::vector<T>>M2, F &f ){
    int m=M1.size();
    int n=M1.at(0).size();
    int p=M2.size();
    int q=M2.at(0).size();
    std::vector<std::vector<T1>>result(m*p,std::vector<T1>(n*q));
    for(int i=0; i<m;i++){
        for(int j=0; j<n;j++){
            for(int k=0; k<p;k++){
                for(int z=0; z<q;z++){
                    result.at(i*p+k).at(j*q+z)=f(M1.at(i).at(j),M2.at(k).at(z));
                }
            }
        }
    }
    return result;
}

int main ()
{
    std::cout<<"Enter dimensions of the first matrix: ";
    int m=0,n=0;
    std::cin>>m>>n;
    std::cout<<"Enter elements of the first matrix: ";
    std::vector<std::vector<int>>A;
    std::vector<int>temp;
    int number;
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            std::cin>>number;
            temp.push_back(number);
        }
        A.push_back(temp);
        temp.clear();
    }
    std::cout<<"Enter dimensions of the second matrix: ";
    int p=0,q=0;
    std::cin>>p>>q;
    std::cout<<"Enter elements of the second matrix: ";
    std::vector<std::vector<int>>B;
    for(int i=0;i<p;i++){
        for(int j=0;j<q;j++){
            std::cin>>number;
            temp.push_back(number);
        }
        B.push_back(temp);
        temp.clear();
    }

    auto f=[](int x, int y){return x*y;};
    auto result=GeneralizedKroneckerProduct<int,int,decltype(f)>(A, B,f);
    std::cout<<"Their Kronecker product is: "<<std::endl;
    for(const auto &row:result){
        for(const auto &number:row){
            std::cout<<std::setw(5)<<number<<" ";
        }
        std::cout<<std::endl;
    }

    return 0;
}
c++ arrays matrix vector deque
1个回答
0
投票

我已经修复了,这是最终版本

#include <iostream>
#include <cmath>
#include <stdexcept>
#include <vector>
#include <deque>
#include <iterator>
#include <iomanip>

int NumDigits(int n){
    int b=0;
    if(n<1)b++;
    return n==0?1:1+b+int(std::log10(std::abs(n))+1e-10);
}

template<typename T,typename T1,typename F>
auto GeneralizedKroneckerProduct( T &P1,  T1 &P2, const F &f ){
    int br1=0,br2=0;
    /*
    if(std::end(P1)-std::begin(P1)==0)
    br1++;
    if(std::end(P2)-std::begin(P2)==0)
    br2++;
    */
     if(std::distance(std::begin(P1),std::end(P1))==0)
    br1++;
    if(std::distance(std::begin(P2),std::end(P2))==0)
    br2++;
    if(br1>0 && br2==0)
    throw::std::domain_error("First parameter does not have matrix form");
    else if(br1==0 && br2>0)
    throw::std::domain_error("Second parameter does not have matrix form");
    if(br1>0 && br2>0)
    throw::std::domain_error("Parameters do not have matrix form");
    /*auto m=std::end(P1)-std::begin(P1);
    auto n=std::end(P1[0])-std::begin(P1[0]);
    auto p=std::end(P2)-std::begin(P2);
    auto q=std::end(P2[0])-std::begin(P2[0]);
    */
    auto m=std::distance(std::begin(P1),std::end(P1));
    auto n=std::distance(std::begin(P1[0]),std::end(P1[0]));
    auto p=std::distance(std::begin(P2),std::end(P2));
    auto q=std::distance(std::begin(P2[0]),std::end(P2[0]));

    
    for(int i=1;i<m;i++){
        if (std::distance(std::begin(P1[i]),std::end(P1[i]))!=n)
        br1++;
    }
    for(int i=1;i<p;i++){
        if (std::distance(std::begin(P2[i]),std::end(P2[i]))!=q)
        br2++;
    }
    if(br1>0 && br2==0)
    throw::std::domain_error("First parameter does not have matrix form");
    else if(br1==0 && br2>0)
    throw::std::domain_error("Second parameter does not have matrix form");
    if(br1>0 && br2>0)
    throw::std::domain_error("Parameters do not have matrix form");
    
    using Tip=typename std::remove_reference<decltype(f(P1[0][0],P2[0][0]))>::type;
    std::vector<std::vector<Tip>>result(m*p,std::vector<Tip>(n*q));

    try{
    for(int i=0; i<m;i++){
        for(int j=0; j<n;j++){
            for(int k=0; k<p;k++){
                for(int z=0; z<q;z++){
                    result[i*p+k][j*q+z]=f(P1[i][j],P2[k][z]);
        
    }
    }
    }
    }}catch(...){
        throw::std::runtime_error("Unexpected problems during calculation");
    }
    return result;
}

int main ()
{
    std::cout<<"Enter dimensions of the first matrix: ";
    int m=0,n=0;
    std::cin>>m>>n;
    std::cout<<"Enter elements of the first matrix: ";
    std::vector<std::deque<double>>A(m,std::deque<double>(n));
    std::vector<int>temp;
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            std::cin>>A[i][j];
        }
    }
    std::cout<<"Enter dimensions of the second matrix: ";
    int p=0,q=0;
    std::cin>>p>>q;
    std::cout<<"Enter elements of the second matrix: ";
    std::deque<std::vector<double>>B(p,std::vector<double>(q));
    for(int i=0;i<p;i++){
        for(int j=0;j<q;j++){
            std::cin>>B[i][j];
        }
    }

    auto f=[](double x, double y){return x*y;};
    auto result=GeneralizedKroneckerProduct(A, B,f);
    std::cout<<"Their Kronecker product is: "<<std::endl;
    int max=-1;
    for(const auto &row:result){
        for(const auto &number:row){
            if(max<NumDigits(number))
            max=NumDigits(number);
        
    }}
    for(const auto &row:result){
        for(const auto &number:row){
            std::cout<<std::setw(max)<<number<<" ";
        
    }
    std::cout<<std::endl;

    }

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.