数组算法

时间:2020-03-10
本文章向大家介绍数组算法,主要包括数组算法使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

数组算法

  • 完美洗牌算法
  • 窗口大小为K的最大子数组和
  • 寻找最小的k个数
  • 寻找和为定值的两个数

完美洗牌算法

c语言随机数如何产生:

利用srand((unsigned int)(time(NULL))是一种方法,因为每一次运行程序的时间是不同的。

在C语言里所提供的随机数发生器的用法:现在的C编译器都提供了一个基于ANSI标准的伪随机数发生器函数,用来生成随机数。它们就是rand()和srand()函数。这两个函数的工作过程如下:

1) 首先给srand()提供一个种子,它是一个unsigned int类型,其取值范围从0~65535;

2) 然后调用rand(),它会根据提供给srand()的种子值返回一个随机数(在0到32767之间)

3) 根据需要多次调用rand(),从而不间断地得到新的随机数;

4) 无论什么时候,都可以给srand()提供一个新的种子,从而进一步“随机化”rand()的输出结果。

下面是0~32767之间的随机数程序:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>//使用当前时钟做种子

void main( void )
{

  int i;
  srand( (unsigned)time( NULL ) ); //初始化随机数
  for( i = 0; i < 10;i++ ) //打印出10个随机数
    printf( " %d\n", rand() );
}

完美洗牌算法:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>//使用当前时钟做种子
    
int main () {
    int arr[10] ={2,5,3,23,5,4,22,44,776,45};
    int temp;
    int index;
        int i;
    srand((unsigned)time(NULL));//初始化随机数
    for(i=10-1;i>=0;i--)
    {    
        temp = arr[i];
        index = rand() %(i + 1);//生成0-i的随机数
        //rand() % 10:生成[0,9]的整数随机数
        //rand() % 10+5:生成[5,14]的整数随机数
        arr[i] = arr[index];
        arr[index] = temp;
    }
    for(i=0;i<10;i++)
    {    
        printf("%d\n",arr[i]);
    }
    return 0;
}

窗口大小为K的最大子数组和:利用滑动窗口

#include <stdio.h>

#define k 3 //定义滑动窗口的大小
    
int main () {
    int list[15] = {5,23,86,21,43,67,45,34,58,23,102,123,11,22,1};
    int i = 0;//数组下标
    int j; //滑动窗口的起始头
    int sum = 0;  //临时结果
    int maxsum = sum; //最后的结果
    while(i+k-1<15){
        int tempi = i;
        for(j = i;j<tempi+k;j++)
        {
            sum = sum +list[j];
        }
        if(sum>maxsum) maxsum = sum;
        sum = 0;
        i++;
    }
    printf("%d\n",maxsum);
}

寻找最小的k个数

假定最小的k个数,遍历数组以后的n-k个数,依次替换掉这k个数里的最大值。

#include <stdio.h>
    
#define size 2 //k个数
int arr[10] ={2,5,3,23,5,4,22,44,776,45};    
int minarr[size] = {2,5};

int Getmaxindex(){
    int min = minarr[0];
    int i =1;
    int index = 0;
    for(;i<size;i++)
    {   //找到最大值
        if(minarr[i]>min){
            min = minarr[i];
            index = i;
        } 
    }
    return index;
}    
    
int main () {
    int maxnumindex; //定义每次从minarr返回最大值的下标
    int maxnum; //定义minarr中的最大值
    int i = size -1; //继续从size-1的位置开始遍历往后的元素
    while(i<10){
        //得到最大值下标
        maxnumindex = Getmaxindex(minarr);
        //得到最大值
        maxnum = minarr[maxnumindex];
        //继续遍历
        //如果继续遍历得到的值比minarr数组中最大的值大,将这个最大值替换成这个值
        if(arr[i]<maxnum){
            minarr[maxnumindex] = arr[i];
        }
        i++;
    }
    for(i = 0; i<size;i++){
        printf("%d\n",minarr[i]);
    }
    return 0;
}

寻找和为定值的两个数:有序数组与双向滑动指针

#include <stdio.h>
int main () {
    int sum = 124;
    int list[15] = {5,23,86,21,43,67,45,34,58,23,102,123,11,22,1};
    
    //对数组进行选择排序:从小到大////////
    int i, j, temp,min;
    for(i = 0; i< 15;i++)
    {
//令最小值等于无序区的第一个值
        min = list[i];
//找到无序区的最小值
        for(j = i; j<15;j++)
        {
            if(min>list[j])
            {
                temp = min;
                min = list[j];
                list[j] = temp;
            }
        }
        list[i] = min;
    }
    //for (i = 0;i < 15; i++)
       // printf("%d\n",list[i]);
    /////////////////////
    
    ///有序:从小到大的序列中找到满足x+y =sum的x与y元素//
    int start = 0;
    int end = 14;
    int currsum = 0;
    while(start<end){
        currsum = list[start] +list[end];
        if(currsum == sum)
        {
          printf("currsum == sum:%d+%d=%d\n",list[start],list[end],currsum);
          //i++;
          //j--; //寻找其它x与y可以去掉这两行注释
          break;
        }else{
            //如果currsum比sum小,只需要移动start指针
            if(currsum < sum){start++;} 
            //如果currsum比sum大,只需要移动end指针
            else{end--;}     
        }
    }
}

原文地址:https://www.cnblogs.com/-wenli/p/12456991.html