zoukankan      html  css  js  c++  java
  • 小程序员的趣味题(一)

    1.在排序数组中,找出某整数出现的次数


    问题定义:给定一个整数数组arr,数组中元素的个数是n,数组arr已经排好序,要在arr中找到某个某个整数x出现的次数,比如arr[] = {1,2,2,3,5,10},找到2的出现次数就是2。

    问题分析相必看到有序数组的字样,想到利用二分应该是很顺利成章的事了。我们可以利用二分搜索求出x在arr中出现的第一个位置lo和最后一个位置hi,然后计算hi-lo+1的值就是x在arr出现的次数了,当然也有可能x并没有在arr中出现过,这时hi和lo都等于-1。时间复杂度是两个二分的复杂度:2*O(log n)。看看代码是怎么实现的吧!!

    相关代码:

    View Code
     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 //求上届,返回值是-1表示在arr中没找到x
     6 int upper_bound(int *arr,int n,int x)
     7 {
     8     bool flag = false;//用于判断x是否存在于arr中
     9     int lo,hi,mid;
    10     lo = 0 ; hi = n-1;
    11     while(lo <= hi)
    12     {
    13         if(hi - lo == 0)
    14         {
    15             if(arr[lo] == x)
    16             {
    17                 flag = true;
    18             }
    19             break;
    20         }
    21         mid = (lo + hi + 1) / 2;//求上界要保证能取到最大值
    22         if(arr[mid] <= x)
    23         {
    24             if(arr[mid] == x)//x在arr中出现过
    25                 flag = true;
    26             lo = mid;
    27         }
    28         else
    29         {
    30             hi = mid - 1;
    31         }
    32     }
    33     if(flag)
    34         return lo;
    35     return -1;
    36 }
    37 
    38 //求下界,返回值是-1表示在arr中没找到x
    39 int lower_bound(int *arr,int n,int x)
    40 {
    41     bool flag = false;//用于判断x是否存在于arr中
    42     int lo,hi,mid;
    43     lo = 0 ; hi = n-1;
    44     while(lo <= hi)
    45     {
    46         if(hi - lo == 0)
    47         {
    48             if(arr[lo] == x)
    49             {
    50                 flag = true;
    51             }
    52             break;
    53         }
    54         mid = (lo + hi) / 2;
    55         if(arr[mid] >= x)
    56         {
    57             if(arr[mid] == x)
    58                 flag = true;
    59             hi = mid;
    60         }
    61         else
    62         {
    63             lo = mid + 1;
    64         }
    65     }
    66     if(flag)
    67         return lo;
    68     return -1;
    69 }
    70 //计算x在arr中的出现次数
    71 void count(int *arr,int n,int x)
    72 {
    73     int hi = upper_bound(arr,n,x);
    74     int lo = lower_bound(arr,n,x);
    75     if(hi != -1)
    76     {
    77         cout<<x<<" 在数组中出现了 "<<hi - lo +1 <<" 次 !!"<<endl;
    78     }
    79     else
    80     {
    81         cout<<x<<" 在数组中出现了 0 次 !!"<<endl;
    82     }
    83 }
    84 int main()
    85 {
    86     int arr1[] = {1,2,2,3,5,6};
    87     count(arr1,6,4);
    88     count(arr1,6,2);
    89 
    90     cout<<endl;
    91     int arr2[] = {0,1};
    92     count(arr2,2,0);
    93 
    94     cout<<endl;
    95     int arr3[] = {1};
    96     count(arr3,1,1);
    97     return 0;
    98 }

    小结:有人也提到了这样解法,即:先利用二分找到x在arr中出现的第一个位置lo,然后从lo下一位置开始向后直到下标达到n-1或者找到不等于x的情况结束,每前进一步,x出现的次数加 1,这样也能求出x在arr中出现的次数,但是不要忘了这种情况,即arr = {1,1,1,1,1,1},然后x = 1,那么这时利用这种方法的时间复杂度就是O(n+log n) 了。也就是说在最坏的情况下,时间复杂度太高。

     

    2.去掉字符串中多余的空格


    问题描述:给定一个字符串数组,要求去掉首部和尾部的所有空格,字符串中间的空格出现1次以上只保留一个空格,比如str[] = “  Wo  shi Vincent  ”,经过处理后应为“Wo shi Vincent”。

    问题分析:这是一个简单的字符串处理的问题,显然开头、结尾、和中间的空格处理方式是不一样的,我的思路是遍历一遍字符数组,首先处理开头的空格,方法是:全部删除;然后是字符串中间的空格,方法是:遇到空格,值保留第一个空格;遍历结束后,新串的最后一个字符是空格,就代表是原字符串尾部有空格存在,所以要去掉。如此一来就完事了,值需要遍历一遍,时间复杂度是O(n)。

    相关代码:

    View Code
     1 #include <iostream>
     2 #include <cstring>
     3 
     4 using namespace std;
     5 
     6 void remove_extra_space(char *str) 
     7 {
     8     int Start = 0 , End = strlen(str);
     9     int NewStart = 0;
    10     while(Start < End)
    11     {
    12         //去掉开头的空格
    13         if(Start == 0)
    14         {
    15             while(Start < End && str[Start] == ' ')
    16             {        
    17                 Start++;
    18             }
    19         }
    20         //处理中间的空格,多个空格值保存一个
    21         if(str[Start] == ' ')
    22         {
    23             str[NewStart++] = str[Start++];
    24             while(Start < End && str[Start] == ' ')
    25             {
    26                 Start++;
    27             }
    28         }
    29         //复制非空格的字符
    30         else
    31         {
    32             str[NewStart++] = str[Start++];    
    33         }
    34     }
    35     //去掉末尾的空格
    36     if(str[NewStart-1] == ' ')
    37     {
    38         str[NewStart-1] = '\0';
    39     }
    40 }
    41 
    42 int main()
    43 {
    44     char str[] = "  wo  shi Vincent  ";
    45     remove_extra_space(str);
    46     cout<<str<<"@@@@@@"<<endl;
    47     return 0;
    48 }

    3.求1024!的结果中末尾有多少个0


    问题分析:首先1024!呀,是多么大的一个数呢??想求出来结果然后在看末尾有多少0是不现实的,我们可以分析要求的是:末尾有多少个0。那么的0的个数有什么决定的呢?10 = 2 * 5 ,显然一对(2 , 5)就能凑出一个末尾0,也就是说末尾0的个数是由因子2和5的个数决定的,更确切的说是由因子的个数决定的(考虑一下为什么吧!?),那么1~1024这1024个数中包含多少个因子5呢?显然这1024个数有的包含1个因子5,有的包含两个因子5(5^2 = 25),有得包含三个因子5(5^3 = 125),有的包含4的因子5(5^4 = 625)。那么一共包含多少因子5呢?

    包含一个因子5的数有 1024 / 5 = 204 个。

    包含两个因子5的数有 1024 / 25 = 40 个。

    包含三个因子5的数有 1024 / 125 = 8 个。

    包含四个因子5的数有 1024 / 625 = 1 个。

    也就是说1~1024这1024个数一共包含因子5的个数是: sum =  204 + 40 + 8 + 1 个。

    小结:注意类似的问题可以借鉴这个题的解题思路~~~~~~

     

    4.给定能随机生成整数1到5的函数,写出能随机生成整数1到7的函数


    问题分析:现在给了一个能随机生成1~5的随机函数,怎样利用这个已知条件生成一个1~7的随机函数呢?既然要生成的是随机数那么生成1,2,3,4,5,6,7的概率就应该是一样的。显然现在光生成1~5之间的数就不够了,我们想到应该要加大生成数的范围,并且加大范围的同时还要保证每个数产生的概率一样,于是有这样一种方法用这个表达式来扩大生成数范围:rand5()*5+rand5(),新的数据范围变成:6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30.并且可以看出来这个25个数出现的可能性是一样的,于是我们可以只用6~26之间的21个数变成1~7这7个数,于是就是要每3个数对应一个数,即:

    6,7,8对应1

    9,10,11对应2

    …………

    24,25,26对应7

    这种变化对应的方式是(6 - 3)/ 3 = 1,(7 - 3) / 3 = 1,(8-3) / 3 = 1.看看代码吧:

    相关代码:

    View Code
    1 int rand7()
    2 {
    3     int i;
    4     //直到产生6~26之间的数跳出循环
    5     while((i=rand5()*5+rand5()) > 26) ;
    6     return (i-3)/3;
    7 }

     


     学习中的一点总结,欢迎拍砖哦^^


     

  • 相关阅读:
    java第19次
    Unity3D常用的生命周期函数
    Unity3D结合ZXing生成中间带图标的二维码并保存
    Unity查看当前内存使用情况(针对移动端开发)
    Unity 获取鼠标悬停位置下的UI或3D物体对象
    【Unity3D】获取鼠标在三维空间(世界坐标系)的位置
    【Unity3D—C#】按下任意按键,返回按键的名称 以及 KeyCode键码详解
    Unity UGUI获取鼠标在屏幕的准确点击位置
    ML-Agent:通过TF#使用训练完成的模型数据
    对《ml-agent:Win10下环境安装》更新
  • 原文地址:https://www.cnblogs.com/BeyondAnyTime/p/2625767.html
Copyright © 2011-2022 走看看