我正在尝试使用标准商和余数算法实现代码,即:
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;
}
答案 0 :(得分:1)
当您将BinaryA除以2并尝试再次调用除法时,您必须将BinaryA返回到其原始状态,以便您可以验证它是否为奇数。 所以,在这两种情况下:
else if(BinaryA==one){
BinaryA[0]=0;
}
else if(BinaryA.size()>1)
pop_front(BinaryA);'
你必须保留丢失的位并在递归的Division返回后恢复它。