• 写一段程序,找出数组中第k大小的数,输出数所在的位置。


    写一段程序,找出数组中第k大小的数,输出数所在的位置。例如{2,4,3,4,7}中,第一大的数是7,位置在4。第二大、第三大的数都是4,位置在1、3随便输出哪一个均可。函数接口为:int   find_orderk(const int * narry,  const int n,  const int k)    
    要求算法复杂度不能是O(n^2)  

    参考答案:

    1

    #include   <stdio.h>
    #include   <stdlib.h>
    #include   <time.h>
    /***************************************
      输入:   n:数组元素的个数   k:第几大的数
                  a:待查找的数组元素
      ****************************************/
    #define   N   100
    void Rand_select(int*, int, int);
    int partition(int*, int, int);
    int swap(int&, int&);
    int k, ans;
    int main()
    {
     int n, a[N], i;
     while (scanf("%d%d", &n, &k) != EOF)
     {
      srand(time(NULL));
      k--;
      for (i = 0; i < n; i++)
       scanf("%d", a + i);
      Rand_select(a, 0, n - 1);
      printf("%d/n", ans);
     }
     return 0;
    }

    void Rand_select(int a[], int p, int q)
    {
     int m;
     if (p <= q)
     {
      m = partition(a, p, q);
      if (k == m)
      {
       ans = a[m];
       return;
      }
      else if (k > m)
       Rand_select(a, m + 1, q);
      else
       Rand_select(a, p, m - 1);
     }
    }

    int partition(int a[], int p, int q)
    {
     int last, i;
     if (q != p)
      swap(a[rand() % (q - p) + p], a[p]);
     for (i = p + 1, last = p; i <= q; i++)
      if (a[i] >= a[p])
       swap(a[i], a[++last]);
     swap(a[last], a[p]);
     return last;
    }

    int swap(int &p, int &q)
    {
     int temp = p;
     p = q;
     q = temp;
     return 0;
    }

    2可以先用快速排序进行排序,其中用另外一个进行地址查找 代码如下,在VC++6.0运行通过。   
      //快速排序  

      #include <iostream>      
      using namespace std;  
       
      int Partition (int *L,int low,int   high)  
      {  
      int temp = L[low];  
      int pt =  L[low];  
       
      while (low  <  high)  
      {  
      while (low < high && L[high] >= pt)  
          --high;  
      L[low]  =  L[high];  
      while (low < high && L[low] <= pt)  
          ++low;  
      L[low]  =  temp;  
      }  
      L[low]   =   temp; 
      return low;  
      }  
       
      void QSort (int *L,int low, int high)  
      {  
      if  (low < high)  
      {  
      int pl = Partition (L,low,high);      
      QSort (L, low, pl - 1);  
      QSort (L, pl + 1, high);  
      }  
      }  
       
      int main ()  
      {  
      int narry[100],addr[100];  
      int sum = 1, t;
       
      cout << "Input  number:" <<  endl;  
      cin >> t;  
       
      while   (t != -1)  
      {  
      narry[sum]  =  t;  
      addr[sum - 1]  =  t;  
      sum++;      
      cin >> t;  
      }  
       
      sum -= 1;  
      QSort (narry,1,sum);  
       
      for  (int   i = 1; i <= sum; i++)  
      cout  <<  narry[i]  <<   '/t';  
      cout   <<   endl;  
       
      int k;  
      cout  <<  "Please   input   place   you   want:"   <<   endl;  
      cin  >>  k;  
      int aa = 1;  
      int kk = 0;  
      for  (;;)  
      {  
      if  (aa == k)  
      break;  
      if  (narry[kk]  !=  narry[kk + 1])  
      {  
      aa  +=  1;  
      kk++;  
      }  

      }  

      cout   <<   "The   NO."   <<   k   <<   "number   is:" << narry[sum - kk] << endl;  
      cout   <<   "And   it's   place   is:"   ;  
      for   (i = 0;i  < sum;i++)  
      {  
      if  (addr[i] == narry[sum - kk])  
      cout   <<   i   <<   '/t';  
      }      
      return 0;  

      }

    难得啊,居然在今天看到这个题。我去年笔试baidu的时候也作过,当时写的是这个答案,高手分析下:  
      #include   <math.h>  
      #include   <time.h>  
      #include   <string>  
      #include   <iostream>  
      #include   <vector>  
      using namespace std;     
      #define   n   10  
      #define   k   5     
      int main(int argc, char *argv[])  
      {  
      srand( (unsigned )time(NULL) );  
      if ( k > n )  
      {  
      cout << "error!"<< endl;  
      return  1;  
      }  
      vector<int>  src;  
      cout << "源" << n << "个数据如下:
    " << endl;  
      for   ( int i = 0; i < n; i++ )  
      {  
      src.push_back( rand() );  
      cout << src[i] << "   ";  
      }  
      vector<int>  maxNum; //顺序存入最大k个数,第一个为最大的,最后一个为第k大
     
      for ( i =0; i < k; i++ )  
      {  
      maxNum.push_back(-999999); //初始化maxNum,k个
    -9999999  
      }  
      for ( i = 0; i < n; i++ )  
      {  
         for ( int j = 0; j < maxNum.size(); j++ )  
         {  
           if  ( src[i] >= maxNum[j]) //比当前的大,则放入当前位置,后面的数字依次后退
     
           {  
             for  ( int i1  =  maxNum.size()-1;  i1 > j; i1-- )  
           {  
              maxNum[i1] = maxNum[i1-1];  
           }  
           maxNum[j] = src[i];  
           break;  
         }  
        }  
      }  

    cout << endl << “第” << k << “大的数字为:” << maxNum[k-1] << endl;
     return  0;  
      }  
      分析:算法对n个数字只访问一次,此部分的时间复杂度为O(n);但每访问一次,须与k个数字分别比较,所以总的时间渐复杂度为O(n*k)

    思想:1.consider   if(k>n)   exit(0)  
            2.if  number  n  is  a big one, use pile/stack sort  
          3.if  number  n is a small one ,use quick sort;  
          4;find your k number and print in the screen;      
      find_orderk(const   int*   narry,const   int   n,const   int   k)    
      {  
      if(n>k)   exit   (0);  
      sort(*narry);  
      for(i=0;i<n;i++)  
        if(i=k)  return  narry[k];  /*the number of  the  k  is  similiar  to  point*/  
      }

    ===================================================================   函数功能:返回一个第K小的元素(采用快排思想)  
      参数:(T a[]目标数组 || int l左边界 || int r右边界 ||  int  k第几小元素)
     
    ================================================================= template <class  T>  
    T  select(T a[], int  l, int  r, int  k)  
      {  
      if(l >= r)   return  a[l]; //参数错误直接返回

      int   i  =  l;  
      int   j  =  r+1;  
      T   pivot  =  a[i];  
      while(true)    
      {  
      do  
      {  
      i = i + 1;  
      }while(a[i] > pivot);  
      do  
      {  
      j = j - 1;  
      }while(a[j] < pivot);  
      if(i >= j)  
      {  
      break;  
      }  
      Swap(a[i], a[j]);  
      }  
      if(j - l + 1 == k) //
    如果当前基准适合的位置刚好是K的话,则满足了条件 返回基准值  
      {  
      return  pivot;  
      }  
      a[l] =  a[j];  
      a[j] =  pivot;  
      if(j - l + 1 < k)  
      {  
      return  select(a, j+1, r, k-j+l-1); //如果基准当前位置在K的左边则对右进行快排
     
      }  
      else  
      {  
      return select(a, l, j-1, k); //如果基准当前位置在K的右边则对左进行快排
     
      }  
      }

     

     

     

    分析程序:

    #include<stdio.h>

    class A

    {

    public:

           static int numA;

           A()

           {

                  num++;

           };

           ~A()

           {

                  num--;

           };

           virtual void print(void)

           {

                  printf("class A, mum:%d/n", num);

           }

     

           void test(void)

           {

                  printf("class A test/n");

                  print();

           }

    };

    class B:public A

    {

    public:

           static int numB;

           B()

           {

                  num--;

           };

           ~B()

           {

     

           };

           virtual void print()

           {

                  printf("class B, num:%d/n", num);

           }

     

           void test(void)

           {

                  printf("class B test/n");

                  print();

           }

    };

    class C

    {

    public:

           virtual void print()

           {

                  printf("class B/n");

           }

    };

    int A::numA = 0;

    int B::numB = 0;

    void main()

    {

           B b;

           b.print();

           b.test();

           printf("1/n");

           A *a;

           B *p= new(class B);

           p->print();

           p->test();

           printf("1/n");

           a = p;

           a->print();

           a->test();

           delete(a);

           printf("sizeof(C):%d/n", sizeof(C));

    }

     

     

     

    #include <stdio.h>

    class A1

    {

    public:

        A1(){ doSth(); }

        virtual void doSth(){printf("I am A/n");}

           void test() {doSth();}

    };

    class B1:public A1

    {

    public:

     

        virtual void doSth(){ printf("I am B/n");}

    };

     

    void main()

    {

           B1 *b = new B1;

           b->test();

    }

     

    1 用C++开发的时候,用来做基类的类的析构函数一般都是虚函数。

    class ClxBase
    {
    public
    :
        ClxBase() {};
        
    virtual
     ~ClxBase() {};

        
    virtual void
     DoSomething() { cout << "Do something in class ClxBase!" << endl; };
    };

    class ClxDerived : public
     ClxBase
    {
    public
    :
        ClxDerived() {};
        ~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; }; 

        
    void
     DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
    };

     

    void main()

    {

    ClxBase *pTest = new ClxDerived;
    pTest->DoSomething();
    delete pTest;

    }

        的输出结果是:

    Do something in class ClxDerived!
    Output from the destructor of class ClxDerived!

        这个很简单,非常好理解。
        但是,如果把类ClxBase析构函数前的virtual去掉,那输出结果就是下面的样子了:

    Do something in class ClxDerived!

        也就是说,类ClxDerived的析构函数根本没有被调用!一般情况下类的析构函数里面都是释放内存资源,而析构函数不被调用的话就会造成内存泄漏。我想所有的C++程序员都知道这样的危险性。当然,如果在析构函数中做了其他工作的话,那你的所有努力也都是白费力气。
        所以,文章开头的那个问题的答案就是--这样做是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。

  • 相关阅读:
    打造属于自己的谷歌Maps版博客公告【演示+源码】
    CentOS 更改默认启动顺序
    VC的控制台程序,如何获取输入参数和环境变量
    如何同时提供ANSI和UNICODE函数
    VC工程需要注意字符集问题
    升级firefox到最新版
    VC工程需要注意字符集问题
    如何同时提供ANSI和UNICODE函数
    使C++ Builder编译程度独立运行
    安装谷歌浏览器
  • 原文地址:https://www.cnblogs.com/byfei/p/3112245.html
Copyright © 2020-2023  润新知