二进制加法算法

时间:2017-10-11 19:09:59

标签: c++ algorithm

我正在尝试使用标准商和余数算法实现代码,即:

function divide(x,y)
   if x=0: return (q,r)=(0,0)
   (q,r)=divide(floor(x/2),y)
   q=2*q, r=2*r
   if x is odd: r=r+1
   if r>=y: r=r-y, q=q+1
   return (q,r)

这里有一个c ++代码是我函数的相关部分

bool compareVector(const vector<int> &A, const vector<int> &B){
   if(A.size()<B.size())
      return(1==0);
   if(A.size()>B.size())
      return(1==1);
   for(int i=A.size()-1;i>=0;i--){
      if (A[i]>B[i])
         return(1==1);
      if(A[i]<B[i])
         return(1==0);
      }
   return(1==1);
}

struct QandR{
vector<int> r;
vector<int> q;
};


QandR Division(vector<int> BinaryA, const vector<int> & BinaryB, QandR &x){
   vector<int> one, zero;
   one.clear();
   one.push_back(1);
   zero.clear();
   zero.push_back(0);

   if(BinaryA==zero){
     return x;
   }
   else if(BinaryA==one){
      BinaryA[0]=0;
   }
   else if(BinaryA.size()>1)
      pop_front(BinaryA);
   x=Division(BinaryA,BinaryB,x);
   x.q=addBinary(x.q,x.q);
   x.r=addBinary(x.r,x.r);
   if(BinaryA[0]==1)
      x.r=addBinary(x.r,one);
   if(compareVector(x.r,BinaryB))
   {
      x.r=Subtract(x.r,BinaryB);
      x.q=addBinary(x.q,one);
   }
      return x;
}

然而,这根本不起作用,例如BinaryA = {1,0,1,1}和BinaryB = {0,1}。这是13/2所以q应该是{0,1,1},r应该是{1}。但我的代码输出r = {1}和q = {0,1}。我不明白发生了什么。上面使用的所有未定义的函数都有效。另外,有一种更简单的方法可以在c ++中返回两个值,如果有的话我会很高兴知道。谢谢。

添加是整个代码

#include <iostream>
#include <string> //this is only used for the user to insert a number
#include <stdlib.h> //this is used to convert the user iputed string to a vector
#include <vector>
#include <algorithm>
using namespace std;

void CleanArray(vector<int> & Array){           //CleanArray() is mainly for the Multiply function where we need to keep removing the enteries 
   for(int i=0;i<Array.size();i++){ 
      Array[i]=0;         //of a vector<int> Array. And then I clean some of the other struct vector<int>'s for saft
}

}






    vector<int> addBinary(vector<int> A,vector<int> B){             //addBinary() adds two struct vector<int>'s and returns a new struct vector<int>
        vector<int> C;      // C is our carry array but we take advantage of the fact that after we carry to a new column we nolonger need the old one so we 
            // can also use C to store our answere.

        C.assign(A.size()+1,0);
        CleanArray(C);
        for(int i=0; i<B.size();i++){       //Case 1 we are adding the first part where we are adding columns and we still have vector<int> A and vector<int> B
            if(C[i]+B[i]+A[i]==3){  
                C[i]=1;
                C[i+1]=1;
            }
            else if(B[i]+A[i]+C[i]==2){ 
              C[i]=0;   
             C[i+1]=1;
            }
            else if(B[i]+ A[i]+C[i] ==1){
                C[i]=1; 
                 }


        }

        for(int i=B.size();i<A.size();i++){ //Case 2 we adding where vector<int> B has been exasted and we only have vector<int> A and vector<int> C.
            if(C[i]+A[i]==2){
             C[i]=0;
                C[i+1]=1;
            }
            else if(A[i]==1){
                C[i]=1;
            }
       } //                    this is fine but not necessary. 

    if(C[C.size()-1]==0)    // We want to change C's member length_a if the aswere is one bigger then the size of A.size().  
       C.pop_back();
        return C;
    }

    vector<int> Subtract(vector<int> A, vector<int> B){             // this function is almost exactly the same as Multiply() using a vector<int> C to hold the value of A-B
        vector<int> C;
        C.assign(A.size(),0);
        CleanArray(C);
    //   reverse(B.begin(), B.end());
       for(int i=A.size()-B.size();i>0;i--)
          B.push_back(0);
    // reverse(B.begin(), B.end());
        for(int i=A.size()-1;i>=0;i--){
            if((A[i]+B[i])==2)
                C[i]=0;
            else if(A[i]==1 && B[i]==0)
                C[i]=1;
            else if(B[i]==1 && A[i]==0){
                C[i]=1;
                int j=0;
                int k=i+1;
                while(j==0){            //we need this while loop bc when we have 0-1 this changes all values of 
                    if(C[k]==1){        //C[i+1] to the next C[]==1, changing all of those to 1 so ex 1000-1=0111
                        C[k]=0;
                        j++;
                    }
                    else if(C[k]==0){
                        C[k]=1;
                        k++;
                    }   
    //              if(i==C.size()-1 && C.size()>1) // this removes the zero's in front of the numberso the answer is not like 001 but 1. 
      //             C.pop_back();  
                }
            }
        //  else           this was the problem with subtraciton 
        //      C[i]=0;   ""   "    "     "     "         "
        }  
       int i=C.size()-1;
       while(C[i]==0 && i!=0){
          C.pop_back();
          i--;
       }

        return C;
    }




    vector<int> Multiply(const vector<int> & A, const vector<int> &B){ // This also uses the concept of having a vector<int> C to store the values of the succesive additions of the rows
        vector<int> C;
        C.assign(A.size(),0);
        for(int j=0;j<B.size();j++){
          vector<int> D;
          D.assign(A.size(),0);
            for(int i=0;i<A.size();i++){
             if(B[j]==1)                    
                    D[i]=A[i];
               // this makes a new row if B[j]==1 so if 1110101*1=1110101(0...0) there are j zero's in
          }
          D.insert(D.begin(),j,0); 
            C=addBinary(D,C);           //this adds the pervious value of C with the next row.
       }      
         return C;

    }


    void pop_front(vector<int> & A){

       reverse(A.begin(),A.end());
       A.pop_back();
       reverse(A.begin(),A.end());

    }

    bool compareVector(const vector<int> &A, const vector<int> &B){
       if(A.size()<B.size())
          return(1==0);
       if(A.size()>B.size())
          return(1==1);
       for(int i=A.size()-1;i>=0;i--){
          if (A[i]>B[i])
             return(1==1);
          if(A[i]<B[i])
             return(1==0);
          }
       return(1==1);
    }

    struct QandR{
    vector<int> r;
    vector<int> q;
    };


    QandR Division(vector<int> BinaryA, const vector<int> & BinaryB, QandR &x){
       vector<int> one, zero;
       one.clear();
       one.push_back(1);
       zero.clear();
       zero.push_back(0);

       if(BinaryA==zero){
         return x;
       }
       else if(BinaryA==one){
          BinaryA[0]=0;
       }
       else if(BinaryA.size()>1)
          pop_front(BinaryA);
       x=Division(BinaryA,BinaryB,x);
       x.q=addBinary(x.q,x.q);
       x.r=addBinary(x.r,x.r);
       if(BinaryA[0]==1)
          x.r=addBinary(x.r,one);
       if(compareVector(x.r,BinaryB))
       {
          x.r=Subtract(x.r,BinaryB);
          x.q=addBinary(x.q,one);
       }
          return x;
    }


    /*
    vector<int> modexp(vector<int> x,vector<int> y, vector<int> N){
       vector<int> one;
       vector<int> r;
       vector<int> q;
       one.push_back(0);
       if(y.size()==1 && y[1]==0)
          return one;
       y.pop_back();
       vector<int> z=modexp(x,y,N);
       if(y[0]==1){
          vector<int> D=Multiply(z,z);
          Division(D,N,q,r);
          z=q;
          return z;
       }
       else{
          vector<int> C =Multiply(Multiply(z,z),x);
          Division(C,N,q,r);
          z=q;
          return z;
       }

    }
    */
    int main(){

       int arraya[4]={1,1,0,1};
       int arrayb[2]={1,1};
       vector<int> a(arraya,arraya+4);
       vector<int> b(arrayb,arrayb+2);
       for(int i=0;i<a.size();i++){
          cout<<a[i]<<" ";
       }
       cout<<endl;
       pop_front(a);
       for(int i=0;i<a.size();i++)
          cout<<a[i]<<" ";
       cout<<endl;
       QandR x;
       x.r.clear();
       x.q.clear();
       x.r.push_back(0);
       x.q.push_back(0);
       x=Division(a,b,x); 
       for(int i=0;i<x.r.size();i++){
          cout<<x.r[i]<<" ";
       }
       cout<<endl;
       for(int i=0;i<x.q.size();i++)
          cout<<x.q[i]<<" ";
       cout<<endl;
       return 0;
    }

1 个答案:

答案 0 :(得分:1)

当您将BinaryA除以2并尝试再次调用除法时,您必须将BinaryA返回到其原始状态,以便您可以验证它是否为奇数。 所以,在这两种情况下:

else if(BinaryA==one){
BinaryA[0]=0;
}
else if(BinaryA.size()>1)
pop_front(BinaryA);'

你必须保留丢失的位并在递归的Division返回后恢复它。