用matlab如何求出一个数组中最接近某个数的两个数的下标??

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用matlab如何求出一个数组中最接近某个数的两个数的下标??相关的知识,希望对你有一定的参考价值。

比如:189 188 187 184 178 169 155 137 118 99 80 64 51 39 30 10 12 15 20 30 44 63 86 112 136 157 171 180 185 189 190 190 191 比如这个数组中最接近82的两个数是80 和 86,应该怎么得到这两个数并返回这两个数的下标???

A= [189 188 187 184 178 169 155 137 118 99 80 64 51 39 30 10 12 15 20 30 44 63 86 112 136 157 171 180 185 189 190 190 191];
B=abs(A-82);
[x,index]=sort(B);
A1=[A(index(1)) A(index(2))]
A2=[index(1) index(2)]

A1是最接近的两个数,A2是这两个数的下标!

祝你学习愉快!追问

多谢!!

参考技术A clear all
clc

arr = [189 188 187 184 178 169 155 137 118 99 80 64 51 39 30 10 12 15 20 30 44 63 86 112 136 157 171 180 185 189 190 190 191];
[a,b] = size(arr);
arr(b+1)=82; %把元素82添加到数组中去
sorted_arr = sort(arr);
[a,b] = size(sorted_arr);
for i = 1: b
if( sorted_arr(i) == 82)
index = i;
break;
end
end
index1 = index-1;
index2 = index+1;
disp('82旁边的两个数是:')
num1 = sorted_arr(index1)
num2 = sorted_arr(index2)
disp('82旁边的两个数的下标是:')
index1
index2追问

要求的下标是这两个数在原来数组中的下标。

追答

clear all
clc

arr = [189 188 187 184 178 169 155 137 118 99 80 64 51 39 30 10 12 15 20 30 44 63 86 112 136 157 171 180 185 189 190 190 191];
[a,b] = size(arr);
arr(b+1)=82; %把元素82添加到数组中去
sorted_arr = sort(arr);
[a,b] = size(sorted_arr);
for i = 1: b-1
if( sorted_arr(i) == 82)
index = i;
break;
end
end
index1 = index-1
index2 = index+1
disp('82旁边的两个数是:')
num1 = sorted_arr(index1)
num2 = sorted_arr(index2)
% 从原来的数组arr中寻找num1和num2所在的下标
for i = 1: b
if( arr(i) == num1)
index1 = i;
elseif( arr(i) == num2)
index2 = i;
end
end
disp('82旁边的两个数的下标是:')
index1
index2

追问

太感谢了。。。

追答

。。

树状数组区间更新

概述

这篇文章前半部分主要研究树状数组的区间更新 单点求值,后半部分研究区间更新 区间求和

前置知识

树状数组的基本知识以及单点更新区间求和,差分的思想。

区间更新,单点求和

分析

回顾一下最简单的树状数组的功能:快速求出一个数列中某个数的前缀和,以及修改一个位置上的数。
现在我们要利用这两个功能实现:快速求出某个数列中某个数的值,以及修改一个区间上的数。

结合差分的知识,将上下两种功能进行比对,不难发现:快速求出某个数列中某个数的值,就是在该数列的差分数列中求出前缀和(差分和前缀和是互逆操作);而区间更新则是差分最擅长的,只需要进行两次单点修改即可。

代码

模板题是洛谷P3368 树状数组2。
在原本的树状数组代码中做一些小改动(已经标注出),得到:

#include<bits/stdc++.h>


using namespace std;


int n;
int c[1000010];


void rev(int st, int fi, int x); // 运用差分进行区间修改
int query(int loc); // 查询单点值(不是前缀和!)
void _pointRev(int loc, int x);
inline int lowbit(int x);


int main(void) {
    int m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        int x;
        scanf("%d", &x);
        rev(i, i, x);
    }
    for (int i = 1; i <= m; ++i) {
        int f, st, fi, x;
        scanf("%d", &f);
        switch(f) {
            case 1:
            scanf("%d%d%d", &st, &fi, &x);
            rev(st, fi, x);
            break;
            case 2:
            scanf("%d", &st);
            printf("%d
", query(st));
        }
    }
    return 0;
}


void rev(int st, int fi, int x) {
    _pointRev(st, x); // 首加
    if (fi < n) { // 有可能是末尾,严谨一点
        _pointRev(fi + 1, -x); // 尾后一位减
    }
    return;
}

int query(int loc) {
    int sum = 0;
    for (int i = loc; i > 0; i -= lowbit(i)) {
        sum += c[i];
    }
    return sum;
}

void _pointRev(int loc, int x) {
    for (int i = loc; i <= n; i += lowbit(i)) {
        c[i] += x;
    }
    return;
}

inline int lowbit(int x) {
    return x & -x;
}

区间更新,区间求和

分析

区间求和要通过前缀和来进行(树状数组也只能维护前缀和)。而区间更新又必须使用差分,用普通的方法就行不通了。我们来列出公式进行一下变形(num[]表示原数组,c[]表示差分数组):

num[1]+num[2]+num[3]+...+num[n]
=(c[1]) + (c[1]+c[2]) + (c[1]+c[2]+c[3]) + ... + (c[1]+c[2]+c[3]+...+c[n])
=c[1]*n + c[2]*(n-1) + c[3]*(n-2) + ... + c[n]*1
=c[1]*(n-0) + c[2]*(n-1) + c[3]*(n-2) + ... + c[n]*(n-(n-1))
=(c[1] + c[2] + c[3] + ... + c[n]) * n - c[1]*0 - c[2]*1 - c[3]*2 - ... - c[n] * (n-1)
=(c[1] + c[2] + c[3] + ... + c[n]) * n - (c[1]*(1-1) + c[2]*(2-1) + c[3] * (3-1) + ... + c[n] * (n-1))

最终得到的公式需要维护一个对于c[i]的普通前缀和以及一个对于c[i]*(i-1)的前缀和变体,两个树状数组就可以满足了。

代码

模板题是洛谷P3372 线段树1

#include<bits/stdc++.h>


using namespace std;


typedef long long LL;


int n;
LL c1[100010], c2[100010];


void revise(int st, int fi, LL x);
LL query(int st, int fi);
void _pointRevise(int loc, LL x);
LL _pointQuery(int loc);
inline int lowbit(int x);


int main(void) {
    int m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        LL t;
        scanf("%lld", &t);
        revise(i, i, t);
    }
    for (int i = 1; i <= m; ++i) {
        int opt, x, y;
        LL k;
        scanf("%d", &opt);
        switch(opt) {
            case 1:
                scanf("%d%d%lld", &x, &y, &k);
                revise(x, y, k);
                break;
            case 2:
                scanf("%d%d", &x, &y);
                printf("%lld
", query(x, y));
                break;
        }
    }
    return 0;
}


void revise(int st, int fi, LL x) {
    _pointRevise(st, x);
    if (fi < n) {
        _pointRevise(fi + 1, -x);
    }
    return;
}

LL query(int st, int fi) {
    return _pointQuery(fi) - ((st > 1) ? _pointQuery(st - 1) : 0);
}

void _pointRevise(int loc, LL x) {
    for (int i = loc; i <= n; i += lowbit(i)) {
        c1[i] += x;
        c2[i] += x * (loc - 1);
    }
    return;
}

LL _pointQuery(int loc) {
    LL sum = 0;
    for (int i = loc; i > 0; i -= lowbit(i)) {
        sum += c1[i] * loc - c2[i];
    }
    return sum;
}

inline int lowbit(int x) {
    return x & -x;
}

以上是关于用matlab如何求出一个数组中最接近某个数的两个数的下标??的主要内容,如果未能解决你的问题,请参考以下文章

java 三维矩阵

树状数组区间更新

在 JavaScript 中,如何求出两个数组的交集和差集?

如何找到最接近某个数字的数组元素? [复制]

Java 求一个整型数组元素中最接近其平均值的整数

求一个数组中最接近平均值的数,用java编程