zoukankan      html  css  js  c++  java
  • 离散数学——数论算法

          最近在复习离散数学,这篇文章是《离散数学及其应用》第六版中第三章 算法、整数、和矩阵中涉及到的几个算法,我想了一下,光看看也起不到什么作用,于是自己动手写了一下,下面的代码都是我自己按照书上的伪代码写出来的,初步验证没什么问题,如果有什么问题就请告知我一下,谢谢!

    一、十进制到任意进制数据转换

      根据进制转换规则:十进制到n进制整数部分除n取余向上书写,小数部分乘n取整向下书写,实际上整数部分就是用的短除法,这个算法实际上就是贪心算法的一个实例,由于是向上书写,我们可以借助栈这种特殊的数据结构很方便的就可以实现向上书写了:

      

      

    #include<iostream>
    #include<stack>
    #include<stdlib.h>

    std::stack<int> converson(int n,int base){
      if(10==base)
        exit(1);
      if(base<=1)
        exit(1);

      std::stack<int> result;
      int temp;

      while(n){
        temp=n%base;
        result.push(temp);
        n/=base;
      }

      return result;
    }

    int main(){
      int data=241;
      std::stack<int> result;

      result=converson(data,2);

      while(!result.empty()){
        std::cout<<result.top();
        result.pop();
      }

    std::cout<<std::endl;
    return 0;

    }

          还有上述代码在base大于的时候还应注意出栈是的表示方法,不过上述代码还有改进的地方,比如说函数返回的是一整个栈,返回时会涉及到变量作用域的生命周期,在返回前内存会开一个临时栈来保存原来的那个栈然后再拷贝给接受者,很耗费内存和时间,所以也可以使用引用或者指针或者全局栈来提高效率,这里就不详述了。

    二、基于二进制的整数加法

      想象一下当我们两个十进制的数相加时,都是从地位到高位逐位相加,但是如果超过基数10我们就需要进位,二进制当然也是一样的,根据二进制的规则,当两个数相加超过2的时候我们也需要进位,相当简单:

      

    #include<algorithm>
    #include<iostream>
    #include<vector>

    void converson(int n,std::vector<int> &binary_result){
      int temp;

      while(n){
        temp=n%2;
        binary_result.push_back(temp);
        n/=2;
      }

    }

    void add(int m,int n,std::vector<int> &result){
      std::vector<int> a;
      std::vector<int> b;
      converson(m,a);
      converson(n,b);

      while(a.size()<b.size())
        a.push_back(0);
      while(a.size()>b.size())
        b.push_back(0);

      int c=0;
      int d;
      std::vector<int>::iterator it1=a.begin(),it2=b.begin();

      while(it1!=a.end() && it2!=b.end()){
        d=(*it1+*it2+c)/2;
        result.push_back(*it1+*it2+c-2*d);
        c=d;
        ++it1;  
        ++it2;
      }
      result.push_back(c);
      std::reverse(result.begin(),result.end());

    }

    int main(){
      int a=45;
      int b=65;
      std::vector<int> result;
      add(a,b,result);

      for(auto e:result)
      std::cout<<e;
      std::cout<<std::endl;

      return 0;
    }

    同样在这儿我们借助了vector这个数据结构,比较方便,但注意最后加法完成后一定要反转一下;

    三、基于二进制的乘法

      

      下面就直接给代码了:

      

    #include<algorithm>
    #include<iostream>
    #include<vector>

    void converson(int n,std::vector<int> &binary_result){
      int temp;

      while(n){
        temp=n%2;
        binary_result.push_back(temp);
        n/=2;
      }
    }

    int multiply(int m,int n){
      std::vector<int> result;
      //std::vector<int> a;
      std::vector<int> b;
      //converson(m,a);
      converson(n,b);

      for(int i=0;i<b.size();++i){
        if(b[i])
          result.push_back(m<<i);
        else
          result.push_back(0);
      }
      int temp=0;

      for(int i=0;i<result.size();++i)
        temp+=result[i];

      return temp;
    }

    int main(){
      int a=45;
      int b=56;

      std::cout<<multiply(a,b)<<std::endl;

      return 0;
    }

    四、整数除法和取模运算

      原理:其实也是一个贪心算法,a=q*d+r; 当给定a和d时,从a中尽可能多的减去d,减的次数商,剩下的就是余数;

      

    #include<iostream>

    void division(int a,int d){
      int q=0;
      int r=a;
      while(r>d){
        r-=d;
        ++q;
      }

      if(a<0 && r>0){
        q=-(q+1);
        r=d-r;
      }

      std::cout<<q<<' '<<r;
    }

    int main(){
      division(45,8);

      return 0;
    }

  • 相关阅读:
    Ugly Numbers
    Present
    Out of Hay
    Stars(树状数组或线段树)
    Humble Numbers
    Wireless Network
    Rank List
    Argus
    食物链
    Antenna Placement
  • 原文地址:https://www.cnblogs.com/mascotxi/p/4595286.html
Copyright © 2011-2022 走看看